@jmfederico/pi-web 1.202607.1 → 1.202607.2

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.
Files changed (56) hide show
  1. package/README.md +8 -8
  2. package/dist/cli.js +17 -5
  3. package/dist/cli.js.map +1 -1
  4. package/dist/client/assets/{CodeViewer-uASb28Y1.js → CodeViewer-B4M13447.js} +1 -1
  5. package/dist/client/assets/{TerminalPanel-DfTmykFw.js → TerminalPanel-Bmvj-Ecn.js} +1 -1
  6. package/dist/client/assets/{UnifiedDiffViewer-laQN1x7P.js → UnifiedDiffViewer-C0hygwRo.js} +1 -1
  7. package/dist/client/assets/index-TvPsRyS1.js +3545 -0
  8. package/dist/client/index.html +1 -1
  9. package/dist/config.js +13 -0
  10. package/dist/config.js.map +1 -1
  11. package/dist/server/diagnostics/nodePtyNativeModule.js +36 -0
  12. package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -0
  13. package/dist/server/git/gitService.js +176 -5
  14. package/dist/server/git/gitService.js.map +1 -1
  15. package/dist/server/piWebStatus.js +6 -3
  16. package/dist/server/piWebStatus.js.map +1 -1
  17. package/dist/server/realtime/sessionEventHub.js +4 -0
  18. package/dist/server/realtime/sessionEventHub.js.map +1 -1
  19. package/dist/server/sessiond.js +47 -7
  20. package/dist/server/sessiond.js.map +1 -1
  21. package/dist/server/sessions/authService.js +58 -7
  22. package/dist/server/sessions/authService.js.map +1 -1
  23. package/dist/server/sessions/globalProviderPolicy.js +98 -0
  24. package/dist/server/sessions/globalProviderPolicy.js.map +1 -0
  25. package/dist/server/sessions/modelCatalogRefresher.js +184 -0
  26. package/dist/server/sessions/modelCatalogRefresher.js.map +1 -0
  27. package/dist/server/sessions/piSessionService.js +736 -100
  28. package/dist/server/sessions/piSessionService.js.map +1 -1
  29. package/dist/server/sessions/plainTextTheme.js +112 -0
  30. package/dist/server/sessions/plainTextTheme.js.map +1 -0
  31. package/dist/server/sessions/sessionCommandService.js +68 -9
  32. package/dist/server/sessions/sessionCommandService.js.map +1 -1
  33. package/dist/server/sessions/sessionNotificationStore.js +484 -0
  34. package/dist/server/sessions/sessionNotificationStore.js.map +1 -0
  35. package/dist/server/sessions/sessionRoutes.js +175 -0
  36. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  37. package/dist/server/sessions/sessionTreeProjection.js +250 -0
  38. package/dist/server/sessions/sessionTreeProjection.js.map +1 -0
  39. package/dist/server/sessions/sessionUnreadStore.js +520 -0
  40. package/dist/server/sessions/sessionUnreadStore.js.map +1 -0
  41. package/dist/server/sessions/spawnSessionTool.js +2 -2
  42. package/dist/server/sessions/spawnSessionTool.js.map +1 -1
  43. package/dist/server/sessions/spawnSubsessionTool.js +10 -12
  44. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
  45. package/dist/shared/apiTypes.d.ts +159 -2
  46. package/dist/shared/apiTypes.js +10 -0
  47. package/dist/shared/apiTypes.js.map +1 -1
  48. package/dist/shared/capabilities.js +6 -0
  49. package/dist/shared/capabilities.js.map +1 -1
  50. package/dist/shared/federatedRoutes.js +8 -0
  51. package/dist/shared/federatedRoutes.js.map +1 -1
  52. package/docs/config.md +32 -4
  53. package/docs/plugins.md +10 -6
  54. package/install.sh +1 -1
  55. package/package.json +8 -7
  56. package/dist/client/assets/index-Dhapi0oR.js +0 -3093
@@ -1,3093 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./CodeViewer-uASb28Y1.js","./vendor-editor-core-vUi74DnD.js","./vendor-editor-languages-DoaXUodB.js","./vendor-editor-legacy-CYBnW6ZU.js","./TerminalPanel-DfTmykFw.js","./vendor-terminal-D8k4UKM2.js","./vendor-terminal-BrP-ENHg.css"])))=>i.map(i=>d[i]);
2
- import{$ as e,A as t,J as n,P as r,Q as i,S as a,X as o,Z as s,d as c,f as l,j as u,l as d,p as f,q as p,u as m}from"./vendor-editor-core-vUi74DnD.js";import{a as ee,o as te,s as ne}from"./vendor-editor-languages-DoaXUodB.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var re=globalThis,ie=re.ShadowRoot&&(re.ShadyCSS===void 0||re.ShadyCSS.nativeShadow)&&`adoptedStyleSheets`in Document.prototype&&`replace`in CSSStyleSheet.prototype,ae=Symbol(),oe=new WeakMap,se=class{constructor(e,t,n){if(this._$cssResult$=!0,n!==ae)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o,t=this.t;if(ie&&e===void 0){let n=t!==void 0&&t.length===1;n&&(e=oe.get(t)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),n&&oe.set(t,e))}return e}toString(){return this.cssText}},ce=e=>new se(typeof e==`string`?e:e+``,void 0,ae),h=(e,...t)=>new se(e.length===1?e[0]:t.reduce((t,n,r)=>t+(e=>{if(!0===e._$cssResult$)return e.cssText;if(typeof e==`number`)return e;throw Error(`Value passed to 'css' function must be a 'css' function result: `+e+`. Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.`)})(n)+e[r+1],e[0]),e,ae),le=(e,t)=>{if(ie)e.adoptedStyleSheets=t.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(let n of t){let t=document.createElement(`style`),r=re.litNonce;r!==void 0&&t.setAttribute(`nonce`,r),t.textContent=n.cssText,e.appendChild(t)}},ue=ie?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t=``;for(let n of e.cssRules)t+=n.cssText;return ce(t)})(e):e,{is:de,defineProperty:fe,getOwnPropertyDescriptor:pe,getOwnPropertyNames:me,getOwnPropertySymbols:he,getPrototypeOf:ge}=Object,_e=globalThis,ve=_e.trustedTypes,ye=ve?ve.emptyScript:``,be=_e.reactiveElementPolyfillSupport,xe=(e,t)=>e,Se={toAttribute(e,t){switch(t){case Boolean:e=e?ye:null;break;case Object:case Array:e=e==null?e:JSON.stringify(e)}return e},fromAttribute(e,t){let n=e;switch(t){case Boolean:n=e!==null;break;case Number:n=e===null?null:Number(e);break;case Object:case Array:try{n=JSON.parse(e)}catch{n=null}}return n}},Ce=(e,t)=>!de(e,t),we={attribute:!0,type:String,converter:Se,reflect:!1,useDefault:!1,hasChanged:Ce};Symbol.metadata??=Symbol(`metadata`),_e.litPropertyMetadata??=new WeakMap;var Te=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=we){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){let n=Symbol(),r=this.getPropertyDescriptor(e,n,t);r!==void 0&&fe(this.prototype,e,r)}}static getPropertyDescriptor(e,t,n){let{get:r,set:i}=pe(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get:r,set(t){let a=r?.call(this);i?.call(this,t),this.requestUpdate(e,a,n)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??we}static _$Ei(){if(this.hasOwnProperty(xe(`elementProperties`)))return;let e=ge(this);e.finalize(),e.l!==void 0&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(xe(`finalized`)))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(xe(`properties`))){let e=this.properties,t=[...me(e),...he(e)];for(let n of t)this.createProperty(n,e[n])}let e=this[Symbol.metadata];if(e!==null){let t=litPropertyMetadata.get(e);if(t!==void 0)for(let[e,n]of t)this.elementProperties.set(e,n)}this._$Eh=new Map;for(let[e,t]of this.elementProperties){let n=this._$Eu(e,t);n!==void 0&&this._$Eh.set(n,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){let t=[];if(Array.isArray(e)){let n=new Set(e.flat(1/0).reverse());for(let e of n)t.unshift(ue(e))}else e!==void 0&&t.push(ue(e));return t}static _$Eu(e,t){let n=t.attribute;return!1===n?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_(){let e=new Map,t=this.constructor.elementProperties;for(let n of t.keys())this.hasOwnProperty(n)&&(e.set(n,this[n]),delete this[n]);e.size>0&&(this._$Ep=e)}createRenderRoot(){let e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return le(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){let n=this.constructor.elementProperties.get(e),r=this.constructor._$Eu(e,n);if(r!==void 0&&!0===n.reflect){let i=(n.converter?.toAttribute===void 0?Se:n.converter).toAttribute(t,n.type);this._$Em=e,i==null?this.removeAttribute(r):this.setAttribute(r,i),this._$Em=null}}_$AK(e,t){let n=this.constructor,r=n._$Eh.get(e);if(r!==void 0&&this._$Em!==r){let e=n.getPropertyOptions(r),i=typeof e.converter==`function`?{fromAttribute:e.converter}:e.converter?.fromAttribute===void 0?Se:e.converter;this._$Em=r;let a=i.fromAttribute(t,e.type);this[r]=a??this._$Ej?.get(r)??a,this._$Em=null}}requestUpdate(e,t,n,r=!1,i){if(e!==void 0){let a=this.constructor;if(!1===r&&(i=this[e]),n??=a.getPropertyOptions(e),!((n.hasChanged??Ce)(i,t)||n.useDefault&&n.reflect&&i===this._$Ej?.get(e)&&!this.hasAttribute(a._$Eu(e,n))))return;this.C(e,t,n)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(e,t,{useDefault:n,reflect:r,wrapped:i},a){n&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,a??t??this[e]),!0!==i||a!==void 0)||(this._$AL.has(e)||(this.hasUpdated||n||(t=void 0),this._$AL.set(e,t)),!0===r&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}let 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(let[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}let e=this.constructor.elementProperties;if(e.size>0)for(let[t,n]of e){let{wrapped:e}=n,r=this[t];!0!==e||this._$AL.has(t)||r===void 0||this.C(t,void 0,n,r)}}let e=!1,t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM()}catch(t){throw e=!1,this._$EM(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(e=>e.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(e=>this._$ET(e,this[e])),this._$EM()}updated(e){}firstUpdated(e){}};Te.elementStyles=[],Te.shadowRootOptions={mode:`open`},Te[xe(`elementProperties`)]=new Map,Te[xe(`finalized`)]=new Map,be?.({ReactiveElement:Te}),(_e.reactiveElementVersions??=[]).push(`2.1.2`);var Ee=globalThis,De=e=>e,Oe=Ee.trustedTypes,ke=Oe?Oe.createPolicy(`lit-html`,{createHTML:e=>e}):void 0,Ae=`$lit$`,je=`lit$${Math.random().toFixed(9).slice(2)}$`,Me=`?`+je,Ne=`<${Me}>`,Pe=document,Fe=()=>Pe.createComment(``),Ie=e=>e===null||typeof e!=`object`&&typeof e!=`function`,Le=Array.isArray,Re=e=>Le(e)||typeof e?.[Symbol.iterator]==`function`,ze=`[
3
- \f\r]`,Be=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,Ve=/-->/g,He=/>/g,Ue=RegExp(`>|${ze}(?:([^\\s"'>=/]+)(${ze}*=${ze}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,`g`),We=/'/g,Ge=/"/g,Ke=/^(?:script|style|textarea|title)$/i,qe=e=>(t,...n)=>({_$litType$:e,strings:t,values:n}),g=qe(1),Je=qe(2),Ye=Symbol.for(`lit-noChange`),_=Symbol.for(`lit-nothing`),Xe=new WeakMap,Ze=Pe.createTreeWalker(Pe,129);function Qe(e,t){if(!Le(e)||!e.hasOwnProperty(`raw`))throw Error(`invalid template strings array`);return ke===void 0?t:ke.createHTML(t)}var $e=(e,t)=>{let n=e.length-1,r=[],i,a=t===2?`<svg>`:t===3?`<math>`:``,o=Be;for(let t=0;t<n;t++){let n=e[t],s,c,l=-1,u=0;for(;u<n.length&&(o.lastIndex=u,c=o.exec(n),c!==null);)u=o.lastIndex,o===Be?c[1]===`!--`?o=Ve:c[1]===void 0?c[2]===void 0?c[3]!==void 0&&(o=Ue):(Ke.test(c[2])&&(i=RegExp(`</`+c[2],`g`)),o=Ue):o=He:o===Ue?c[0]===`>`?(o=i??Be,l=-1):c[1]===void 0?l=-2:(l=o.lastIndex-c[2].length,s=c[1],o=c[3]===void 0?Ue:c[3]===`"`?Ge:We):o===Ge||o===We?o=Ue:o===Ve||o===He?o=Be:(o=Ue,i=void 0);let d=o===Ue&&e[t+1].startsWith(`/>`)?` `:``;a+=o===Be?n+Ne:l>=0?(r.push(s),n.slice(0,l)+Ae+n.slice(l)+je+d):n+je+(l===-2?t:d)}return[Qe(e,a+(e[n]||`<?>`)+(t===2?`</svg>`:t===3?`</math>`:``)),r]},et=class e{constructor({strings:t,_$litType$:n},r){let i;this.parts=[];let a=0,o=0,s=t.length-1,c=this.parts,[l,u]=$e(t,n);if(this.el=e.createElement(l,r),Ze.currentNode=this.el.content,n===2||n===3){let e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;(i=Ze.nextNode())!==null&&c.length<s;){if(i.nodeType===1){if(i.hasAttributes())for(let e of i.getAttributeNames())if(e.endsWith(Ae)){let t=u[o++],n=i.getAttribute(e).split(je),r=/([.?@])?(.*)/.exec(t);c.push({type:1,index:a,name:r[2],strings:n,ctor:r[1]===`.`?at:r[1]===`?`?ot:r[1]===`@`?st:it}),i.removeAttribute(e)}else e.startsWith(je)&&(c.push({type:6,index:a}),i.removeAttribute(e));if(Ke.test(i.tagName)){let e=i.textContent.split(je),t=e.length-1;if(t>0){i.textContent=Oe?Oe.emptyScript:``;for(let n=0;n<t;n++)i.append(e[n],Fe()),Ze.nextNode(),c.push({type:2,index:++a});i.append(e[t],Fe())}}}else if(i.nodeType===8)if(i.data===Me)c.push({type:2,index:a});else{let e=-1;for(;(e=i.data.indexOf(je,e+1))!==-1;)c.push({type:7,index:a}),e+=je.length-1}a++}}static createElement(e,t){let n=Pe.createElement(`template`);return n.innerHTML=e,n}};function tt(e,t,n=e,r){if(t===Ye)return t;let i=r===void 0?n._$Cl:n._$Co?.[r],a=Ie(t)?void 0:t._$litDirective$;return i?.constructor!==a&&(i?._$AO?.(!1),a===void 0?i=void 0:(i=new a(e),i._$AT(e,n,r)),r===void 0?n._$Cl=i:(n._$Co??=[])[r]=i),i!==void 0&&(t=tt(e,i._$AS(e,t.values),i,r)),t}var nt=class{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){let{el:{content:t},parts:n}=this._$AD,r=(e?.creationScope??Pe).importNode(t,!0);Ze.currentNode=r;let i=Ze.nextNode(),a=0,o=0,s=n[0];for(;s!==void 0;){if(a===s.index){let t;s.type===2?t=new rt(i,i.nextSibling,this,e):s.type===1?t=new s.ctor(i,s.name,s.strings,this,e):s.type===6&&(t=new ct(i,this,e)),this._$AV.push(t),s=n[++o]}a!==s?.index&&(i=Ze.nextNode(),a++)}return Ze.currentNode=Pe,r}p(e){let t=0;for(let n of this._$AV)n!==void 0&&(n.strings===void 0?n._$AI(e[t]):(n._$AI(e,n,t),t+=n.strings.length-2)),t++}},rt=class e{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,n,r){this.type=2,this._$AH=_,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=n,this.options=r,this._$Cv=r?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode,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=tt(this,e,t),Ie(e)?e===_||e==null||e===``?(this._$AH!==_&&this._$AR(),this._$AH=_):e!==this._$AH&&e!==Ye&&this._(e):e._$litType$===void 0?e.nodeType===void 0?Re(e)?this.k(e):this._(e):this.T(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!==_&&Ie(this._$AH)?this._$AA.nextSibling.data=e:this.T(Pe.createTextNode(e)),this._$AH=e}$(e){let{values:t,_$litType$:n}=e,r=typeof n==`number`?this._$AC(e):(n.el===void 0&&(n.el=et.createElement(Qe(n.h,n.h[0]),this.options)),n);if(this._$AH?._$AD===r)this._$AH.p(t);else{let e=new nt(r,this),n=e.u(this.options);e.p(t),this.T(n),this._$AH=e}}_$AC(e){let t=Xe.get(e.strings);return t===void 0&&Xe.set(e.strings,t=new et(e)),t}k(t){Le(this._$AH)||(this._$AH=[],this._$AR());let n=this._$AH,r,i=0;for(let a of t)i===n.length?n.push(r=new e(this.O(Fe()),this.O(Fe()),this,this.options)):r=n[i],r._$AI(a),i++;i<n.length&&(this._$AR(r&&r._$AB.nextSibling,i),n.length=i)}_$AR(e=this._$AA.nextSibling,t){for(this._$AP?.(!1,!0,t);e!==this._$AB;){let t=De(e).nextSibling;De(e).remove(),e=t}}setConnected(e){this._$AM===void 0&&(this._$Cv=e,this._$AP?.(e))}},it=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,n,r,i){this.type=1,this._$AH=_,this._$AN=void 0,this.element=e,this.name=t,this._$AM=r,this.options=i,n.length>2||n[0]!==``||n[1]!==``?(this._$AH=Array(n.length-1).fill(new String),this.strings=n):this._$AH=_}_$AI(e,t=this,n,r){let i=this.strings,a=!1;if(i===void 0)e=tt(this,e,t,0),a=!Ie(e)||e!==this._$AH&&e!==Ye,a&&(this._$AH=e);else{let r=e,o,s;for(e=i[0],o=0;o<i.length-1;o++)s=tt(this,r[n+o],t,o),s===Ye&&(s=this._$AH[o]),a||=!Ie(s)||s!==this._$AH[o],s===_?e=_:e!==_&&(e+=(s??``)+i[o+1]),this._$AH[o]=s}a&&!r&&this.j(e)}j(e){e===_?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,e??``)}},at=class extends it{constructor(){super(...arguments),this.type=3}j(e){this.element[this.name]=e===_?void 0:e}},ot=class extends it{constructor(){super(...arguments),this.type=4}j(e){this.element.toggleAttribute(this.name,!!e&&e!==_)}},st=class extends it{constructor(e,t,n,r,i){super(e,t,n,r,i),this.type=5}_$AI(e,t=this){if((e=tt(this,e,t,0)??_)===Ye)return;let n=this._$AH,r=e===_&&n!==_||e.capture!==n.capture||e.once!==n.once||e.passive!==n.passive,i=e!==_&&(n===_||r);r&&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)}},ct=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){tt(this,e)}},lt={M:Ae,P:je,A:Me,C:1,L:$e,R:nt,D:Re,V:tt,I:rt,H:it,N:ot,U:st,B:at,F:ct},ut=Ee.litHtmlPolyfillSupport;ut?.(et,rt),(Ee.litHtmlVersions??=[]).push(`3.3.3`);var dt=(e,t,n)=>{let r=n?.renderBefore??t,i=r._$litPart$;if(i===void 0){let e=n?.renderBefore??null;r._$litPart$=i=new rt(t.insertBefore(Fe(),e),e,void 0,n??{})}return i._$AI(e),i},ft=globalThis,v=class extends Te{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){let t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=dt(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return Ye}};v._$litElement$=!0,v.finalized=!0,ft.litElementHydrateSupport?.({LitElement:v});var pt=ft.litElementPolyfillSupport;pt?.({LitElement:v}),(ft.litElementVersions??=[]).push(`4.2.2`);var y=e=>(t,n)=>{n===void 0?customElements.define(e,t):n.addInitializer(()=>{customElements.define(e,t)})},mt={attribute:!0,type:String,converter:Se,reflect:!1,hasChanged:Ce},ht=(e=mt,t,n)=>{let{kind:r,metadata:i}=n,a=globalThis.litPropertyMetadata.get(i);if(a===void 0&&globalThis.litPropertyMetadata.set(i,a=new Map),r===`setter`&&((e=Object.create(e)).wrapped=!0),a.set(n.name,e),r===`accessor`){let{name:r}=n;return{set(n){let i=t.get.call(this);t.set.call(this,n),this.requestUpdate(r,i,e,!0,n)},init(t){return t!==void 0&&this.C(r,void 0,e,t),t}}}if(r===`setter`){let{name:r}=n;return function(n){let i=this[r];t.call(this,n),this.requestUpdate(r,i,e,!0,n)}}throw Error(`Unsupported decorator location: `+r)};function b(e){return(t,n)=>typeof n==`object`?ht(e,t,n):((e,t,n)=>{let r=t.hasOwnProperty(n);return t.constructor.createProperty(n,e),r?Object.getOwnPropertyDescriptor(t,n):void 0})(e,t,n)}function x(e){return b({...e,state:!0,attribute:!1})}var gt=(e,t,n)=>(n.configurable=!0,n.enumerable=!0,Reflect.decorate&&typeof t!=`object`&&Object.defineProperty(e,t,n),n);function S(e,t){return(n,r,i)=>{let a=t=>t.renderRoot?.querySelector(e)??null;if(t){let{get:e,set:t}=typeof r==`object`?n:i??(()=>{let e=Symbol();return{get(){return this[e]},set(t){this[e]=t}}})();return gt(n,r,{get(){let n=e.call(this);return n===void 0&&(n=a(this),(n!==null||this.hasUpdated)&&t.call(this,n)),n}})}return gt(n,r,{get(){return a(this)}})}}function _t(e,t=yt()){let n=new URL(t.viteBaseUrl,t.documentBaseUrl);return new URL(bt(e),n).toString()}function vt(e,t=yt()){let n=new URL(_t(e,t));if(n.protocol===`http:`)n.protocol=`ws:`;else if(n.protocol===`https:`)n.protocol=`wss:`;else throw Error(`Cannot create a WebSocket URL from ${n.protocol}`);return n.toString()}function yt(){return{viteBaseUrl:`./`,documentBaseUrl:document.baseURI}}function bt(e){return e.startsWith(`/`)?`.${e}`:e}async function C(e,t,n){let r=new Headers(n?.headers);n?.body!==void 0&&!r.has(`content-type`)&&r.set(`content-type`,`application/json`);let i=await fetch(_t(e),{...n,headers:r});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(xt(e)??i.statusText)}return t(await i.json())}function xt(e){if(St(e))return typeof e.error==`string`?e.error:void 0}function St(e){return typeof e==`object`&&!!e}function Ct(e){return(e.split(/[\\/]/u).at(-1)?.toLowerCase()??e.toLowerCase()).replace(/(?:\.[cm]?js|\.exe|\.cmd)$/iu,``)===`pi`}function wt(e){return!e.includes(`/`)&&!e.includes(`\\`)&&Ct(e)}var Tt=new Set([`schemaVersion`,`revision`,`command`,`dir`,`sessionDirEnvKeys`]),Et=/^sha256:[0-9a-f]{64}$/u,Dt=/^[A-Za-z0-9_][A-Za-z0-9._+-]*$/u,Ot=new Set([`PI_WEB_AGENT_SESSION_DIR`,`PI_CODING_AGENT_SESSION_DIR`]);function kt(e){if(!Pt(e)||Object.keys(e).some(e=>!Tt.has(e)))return;let t=e.schemaVersion,n=e.revision,r=e.command,i=e.dir,a=e.sessionDirEnvKeys;if(t===1&&!(typeof n!=`string`||!Et.test(n))&&!(typeof r!=`string`||!At(r))&&!(typeof i!=`string`||!jt(i))&&Nt(a)&&new Set(a).size===a.length&&!(a[0]!==`PI_WEB_AGENT_SESSION_DIR`||a.some(e=>!Ot.has(e))))return Object.freeze({schemaVersion:t,revision:n,command:r,dir:i,sessionDirEnvKeys:Object.freeze([...a])})}function At(e){return e!==e.trim()||/[\s;&|`$<>]/u.test(e)?!1:jt(e)?!e.endsWith(`/`)&&!e.endsWith(`\\`):Dt.test(e)}function jt(e){if(e===``||e!==e.trim()||Mt(e))return!1;let t=e.replace(/\\/g,`/`);return t.startsWith(`/`)||/^[A-Za-z]:\//u.test(t)}function Mt(e){for(let t of e){let e=t.charCodeAt(0);if(e<32||e===127)return!0}return!1}function Nt(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`&&e!==``)}function Pt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}var w={sessionsDeleteArchived:`sessions.deleteArchived`,sessionsBulkMutations:`sessions.bulkMutations`,sessionsCleanup:`sessions.cleanup`,sessionsReload:`sessions.reload`,sessionsClearQueue:`sessions.clearQueue`,sessionsPersistedState:`sessions.persistedState`,promptAttachments:`prompt.attachments`,workspaceFileSuggestions:`workspace.fileSuggestions`,piPackagesManage:`piPackages.manage`,selectedMachineSettings:`settings.selectedMachine`,agentProfileConfig:`settings.agentProfile`},Ft=Object.values(w),It=new Set(Ft);w.sessionsDeleteArchived,w.sessionsBulkMutations,w.sessionsCleanup,w.sessionsReload,w.sessionsClearQueue,w.sessionsPersistedState,w.promptAttachments,w.workspaceFileSuggestions,w.piPackagesManage,w.selectedMachineSettings,w.agentProfileConfig,w.sessionsDeleteArchived,w.sessionsBulkMutations,w.sessionsCleanup,w.sessionsReload,w.sessionsClearQueue,w.sessionsPersistedState,w.promptAttachments,w.sessionsDeleteArchived,w.sessionsBulkMutations,w.sessionsCleanup,w.sessionsReload,w.sessionsClearQueue,w.sessionsPersistedState,w.promptAttachments,w.workspaceFileSuggestions,w.piPackagesManage,w.selectedMachineSettings,w.agentProfileConfig;function Lt(e){return typeof e==`string`&&It.has(e)}function Rt(e,t){return e?.capabilities?.includes(t)===!0}function zt(e){if(!(!Array.isArray(e)||!e.every(e=>typeof e==`string`)))return e.filter(Lt)}function Bt(e){return typeof e==`object`&&!!e}function T(e){if(!Bt(e))throw Error(`Expected object response`);return e}function E(e,t){let n=e[t];if(typeof n!=`string`)throw Error(`Expected string field: ${t}`);return n}function D(e,t){let n=e[t];if(n!==void 0){if(typeof n!=`string`)throw Error(`Expected optional string field: ${t}`);return n}}function O(e,t){let n=e[t];if(typeof n!=`number`)throw Error(`Expected number field: ${t}`);return n}function k(e,t){let n=e[t];if(typeof n!=`boolean`)throw Error(`Expected boolean field: ${t}`);return n}function A(e){return t=>{if(!Array.isArray(t))throw Error(`Expected array response`);return t.map(e)}}function Vt(e){if(!Array.isArray(e))throw Error(`Expected array response`);return e}function Ht(e,t){if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw Error(`Expected string array field: ${t}`);return e}function Ut(e){if(Array.isArray(e))return{messages:e,start:0,total:e.length};let t=T(e);return{messages:Vt(t.messages),start:O(t,`start`),total:O(t,`total`)}}function Wt(e){let t=T(e);return A(Gt)(t.machines)}function Gt(e){let t=T(e),n=Jt(t,`kind`),r=D(t,`baseUrl`),i=Yt(t,`status`),a=D(t,`statusMessage`);return{id:E(t,`id`),name:E(t,`name`),kind:n,...r===void 0?{}:{baseUrl:r},createdAt:E(t,`createdAt`),updatedAt:E(t,`updatedAt`),...i===void 0?{}:{status:i},...a===void 0?{}:{statusMessage:a}}}function Kt(e){let t=T(e),n=Yt(t,`status`),r=D(t,`error`);return{machineId:E(t,`machineId`),ok:k(t,`ok`),checkedAt:E(t,`checkedAt`),...n===void 0?{}:{status:n},...t.web===void 0?{}:{web:kr(t.web)},...t.sessiond===void 0?{}:{sessiond:kr(t.sessiond)},...r===void 0?{}:{error:r}}}function qt(e){let t=T(e),n=D(t,`error`);return{machineId:E(t,`machineId`),ok:k(t,`ok`),checkedAt:E(t,`checkedAt`),...j(`packageName`,D(t,`packageName`)),...j(`generatedAt`,D(t,`generatedAt`)),...t.components===void 0?{}:{components:Dr(t.components)},...t.capabilities===void 0?{}:{capabilities:Fr(t.capabilities)},...n===void 0?{}:{error:n}}}function Jt(e,t){let n=E(e,t);if(n!==`local`&&n!==`remote`)throw Error(`Expected machine kind field: ${t}`);return n}function Yt(e,t){let n=D(e,t);if(n!==void 0){if(n!==`unknown`&&n!==`online`&&n!==`offline`&&n!==`error`)throw Error(`Expected machine status field: ${t}`);return n}}function Xt(e){let t=T(e);return{id:E(t,`id`),name:E(t,`name`),path:E(t,`path`),createdAt:E(t,`createdAt`)}}function Zt(e){let t=T(e),n=D(t,`branch`);return{id:E(t,`id`),projectId:E(t,`projectId`),path:E(t,`path`),label:E(t,`label`),...n===void 0?{}:{branch:n},isMain:k(t,`isMain`),isGitRepo:k(t,`isGitRepo`),isGitWorktree:k(t,`isGitWorktree`),...j(`effectiveConfig`,Qt(t.effectiveConfig))}}function Qt(e){if(e!==void 0){if(!Bt(e)||Array.isArray(e))throw Error(`Invalid workspace effectiveConfig field`);return{...j(`uploads`,cr(e.uploads))}}}function $t(e){let t=T(e),n=D(t,`name`),r=Cr(t.persisted,`persisted`),i=D(t,`parentSessionPath`),a=D(t,`archivedAt`);return{id:E(t,`id`),path:E(t,`path`),cwd:E(t,`cwd`),...r===void 0?{}:{persisted:r},...n===void 0?{}:{name:n},created:E(t,`created`),modified:E(t,`modified`),messageCount:O(t,`messageCount`),firstMessage:E(t,`firstMessage`),...i===void 0?{}:{parentSessionPath:i},...t.archived===!0?{archived:!0}:{},...a===void 0?{}:{archivedAt:a}}}function en(e){if(e!==`info`&&e!==`warning`&&e!==`error`)throw Error(`Invalid session warning severity`);return e}function tn(e){if(e!==void 0)return{id:E(T(e),`id`)}}function nn(e){let t=T(e),n=tn(t.dismiss);return{severity:en(t.severity),message:E(t,`message`),...j(`source`,D(t,`source`)),...j(`path`,D(t,`path`)),...n===void 0?{}:{dismiss:n}}}function rn(e){return e===void 0?{}:{warnings:A(nn)(e)}}function an(e){let t=T(e);return{sessionId:E(t,`sessionId`),...j(`persisted`,Cr(t.persisted,`persisted`)),isStreaming:k(t,`isStreaming`),isCompacting:k(t,`isCompacting`),isBashRunning:k(t,`isBashRunning`),pendingMessageCount:O(t,`pendingMessageCount`),queuedMessages:t.queuedMessages===void 0?[]:A(hn)(t.queuedMessages),...j(`messageCount`,Qr(t,`messageCount`)),tokens:gn(t.tokens),cost:O(t,`cost`),...vn(t.model),...In(t.contextUsage),...j(`thinkingLevel`,D(t,`thinkingLevel`)),...rn(t.warnings)}}function on(e){let t=T(e);return{seq:O(t,`seq`),partial:t.partial??null}}function sn(e){let t=T(e),n=t.skippedBusySessionIds===void 0?void 0:Ht(t.skippedBusySessionIds,`skippedBusySessionIds`);return{generatedAt:E(t,`generatedAt`),thresholds:fn(t.thresholds),projects:A(pn)(t.projects),totals:mn(t.totals),...n===void 0?{}:{skippedBusySessionIds:n}}}function cn(e){let t=T(e);return{...sn(t),archivedSessionIds:Ht(t.archivedSessionIds,`archivedSessionIds`),deletedSessionIds:Ht(t.deletedSessionIds,`deletedSessionIds`)}}function ln(e){let t=T(e);if(t.archived!==!0)throw Error(`Expected bulk archived response`);return{archived:!0,archivedSessionIds:Ht(t.archivedSessionIds,`archivedSessionIds`),failures:A(dn)(t.failures),generatedAt:E(t,`generatedAt`)}}function un(e){let t=T(e);if(t.deleted!==!0)throw Error(`Expected bulk deleted response`);return{deleted:!0,deletedSessionIds:Ht(t.deletedSessionIds,`deletedSessionIds`),failures:A(dn)(t.failures),generatedAt:E(t,`generatedAt`)}}function dn(e){let t=T(e);return{sessionId:E(t,`sessionId`),error:E(t,`error`)}}function fn(e){let t=T(e);return{...j(`archiveIdleDays`,Qr(t,`archiveIdleDays`)),...j(`deleteArchivedDays`,Qr(t,`deleteArchivedDays`))}}function pn(e){let t=T(e);return{cwd:E(t,`cwd`),archiveCount:O(t,`archiveCount`),deleteCount:O(t,`deleteCount`)}}function mn(e){let t=T(e);return{archiveCount:O(t,`archiveCount`),deleteCount:O(t,`deleteCount`)}}function hn(e){let t=T(e),n=E(t,`kind`);if(n!==`steer`&&n!==`followUp`)throw Error(`Invalid queued message kind`);return{kind:n,text:E(t,`text`)}}function gn(e){let t=T(e);return{input:O(t,`input`),output:O(t,`output`),cacheRead:O(t,`cacheRead`),cacheWrite:O(t,`cacheWrite`),total:O(t,`total`)}}function _n(e){let t=T(e);return{...j(`provider`,D(t,`provider`)),...j(`id`,D(t,`id`)),...j(`name`,D(t,`name`)),...j(`contextWindow`,Qr(t,`contextWindow`)),...j(`reasoning`,t.reasoning)}}function vn(e){return e===void 0?{}:{model:_n(e)}}function yn(e){let t=T(e);return{models:A(_n)(t.models)}}function bn(e){if(typeof e!=`string`)throw Error(`Invalid thinking level`);return e}function xn(e){let t=T(e);return{levels:A(bn)(t.levels)}}function Sn(e){if(e!==`oauth`&&e!==`api_key`)throw Error(`Invalid auth type`);return e}function Cn(e){if(e!==`stored`&&e!==`runtime`&&e!==`environment`&&e!==`fallback`&&e!==`models_json_key`&&e!==`models_json_command`)throw Error(`Invalid auth status source`);return e}function wn(e){let t=T(e),n=t.source===void 0?void 0:Cn(t.source);return{configured:k(t,`configured`),...j(`source`,n),...j(`label`,D(t,`label`))}}function Tn(e){let t=T(e),n=t.loginFlow;if(n!==void 0&&n!==`interactive`)throw Error(`Invalid auth provider login flow`);return{id:E(t,`id`),name:E(t,`name`),authType:Sn(t.authType),status:wn(t.status),...n===void 0?{}:{loginFlow:n}}}function En(e){let t=T(e);return{providers:A(Tn)(t.providers)}}function Dn(e){let t=T(e);return{flowId:E(t,`flowId`),providerId:E(t,`providerId`),providerName:E(t,`providerName`),status:On(t.status),progress:A(e=>{if(typeof e!=`string`)throw Error(`Expected progress item string`);return e})(t.progress),...j(`error`,D(t,`error`)),...j(`auth`,kn(t.auth)),...j(`prompt`,jn(t.prompt)),...j(`select`,Nn(t.select)),...j(`info`,Pn(t.info))}}function On(e){if(e!==`running`&&e!==`complete`&&e!==`error`&&e!==`cancelled`)throw Error(`Invalid OAuth flow status`);return e}function kn(e){if(e===void 0)return;let t=T(e);return{url:E(t,`url`),...j(`instructions`,D(t,`instructions`)),...j(`deviceCode`,An(t.deviceCode))}}function An(e){if(e===void 0)return;let t=T(e);return{userCode:E(t,`userCode`),...j(`intervalSeconds`,Qr(t,`intervalSeconds`)),...j(`expiresInSeconds`,Qr(t,`expiresInSeconds`))}}function jn(e){if(e===void 0)return;let t=T(e),n=E(t,`kind`);if(n!==`prompt`&&n!==`manual`)throw Error(`Invalid OAuth prompt kind`);let r=t.promptType===void 0?n===`manual`?`manual_code`:`text`:Mn(t.promptType);return{requestId:E(t,`requestId`),message:E(t,`message`),kind:n,promptType:r,...j(`placeholder`,D(t,`placeholder`)),...j(`allowEmpty`,Zr(t,`allowEmpty`))}}function Mn(e){if(e!==`text`&&e!==`secret`&&e!==`manual_code`)throw Error(`Invalid OAuth prompt type`);return e}function Nn(e){if(e===void 0)return;let t=T(e);return{requestId:E(t,`requestId`),message:E(t,`message`),options:A(Rr)(t.options)}}function Pn(e){if(e!==void 0)return A(e=>{let t=T(e);return{message:E(t,`message`),...j(`links`,t.links===void 0?void 0:A(Fn)(t.links))}})(e)}function Fn(e){let t=T(e);return{url:E(t,`url`),...j(`label`,D(t,`label`))}}function In(e){if(e===void 0)return{};let t=T(e);return{contextUsage:{tokens:$r(t,`tokens`),contextWindow:O(t,`contextWindow`),percent:$r(t,`percent`)}}}function Ln(e){let t=T(e),n=E(t,`source`);if(n!==`extension`&&n!==`prompt`&&n!==`skill`&&n!==`builtin`)throw Error(`Invalid command source`);return{name:E(t,`name`),source:n,...j(`description`,D(t,`description`))}}function Rn(e){let t=T(e),n=E(t,`kind`);if(n!==`tracked`&&n!==`untracked`&&n!==`other`)throw Error(`Invalid file kind`);return{path:E(t,`path`),kind:n}}function zn(e){let t=T(e);return{path:E(t,`path`),entries:A(Bn)(t.entries),scannedAt:E(t,`scannedAt`),truncated:k(t,`truncated`)}}function Bn(e){let t=T(e),n=E(t,`type`);if(n!==`file`&&n!==`directory`&&n!==`symlink`)throw Error(`Invalid file tree entry type`);return{name:E(t,`name`),path:E(t,`path`),type:n,...j(`size`,Qr(t,`size`)),...j(`modifiedAt`,D(t,`modifiedAt`))}}function Vn(e){let t=T(e),n=E(t,`encoding`);if(n!==`utf8`)throw Error(`Invalid file encoding`);return{path:E(t,`path`),...j(`language`,D(t,`language`)),...j(`mediaType`,Gn(t.mediaType)),...j(`mimeType`,D(t,`mimeType`)),encoding:n,size:O(t,`size`),modifiedAt:E(t,`modifiedAt`),content:E(t,`content`),truncated:k(t,`truncated`),binary:k(t,`binary`)}}function Hn(e){let t=T(e);return{path:E(t,`path`),size:O(t,`size`),modifiedAt:E(t,`modifiedAt`),created:k(t,`created`)}}function Un(e){let t=T(e);return{path:E(t,`path`),existed:k(t,`existed`)}}function Wn(e){let t=T(e);return{fromPath:E(t,`fromPath`),toPath:E(t,`toPath`),size:O(t,`size`),modifiedAt:E(t,`modifiedAt`)}}function Gn(e){if(e!==void 0){if(e!==`image`)throw Error(`Invalid file media type`);return e}}function Kn(e){let t=T(e);return{isGitRepo:k(t,`isGitRepo`),hash:E(t,`hash`),...j(`branch`,D(t,`branch`)),...j(`upstream`,D(t,`upstream`)),...j(`ahead`,Qr(t,`ahead`)),...j(`behind`,Qr(t,`behind`)),files:A(qn)(t.files)}}function qn(e){let t=T(e);return{path:E(t,`path`),...j(`oldPath`,D(t,`oldPath`)),index:Jn(t.index),workingTree:Jn(t.workingTree)}}function Jn(e){switch(e){case`unmodified`:case`modified`:case`added`:case`deleted`:case`renamed`:case`copied`:case`untracked`:case`ignored`:case`conflicted`:return e;default:throw Error(`Invalid git file state`)}}function Yn(e){let t=T(e);return{...j(`path`,D(t,`path`)),staged:k(t,`staged`),hash:E(t,`hash`),diff:E(t,`diff`),truncated:k(t,`truncated`)}}function Xn(e){let t=T(e);return{id:E(t,`id`),cwd:E(t,`cwd`),name:E(t,`name`),createdAt:E(t,`createdAt`),exited:k(t,`exited`),...j(`exitCode`,Qr(t,`exitCode`)),...j(`commandRunId`,D(t,`commandRunId`))}}function Zn(e){let t=T(e);return{id:E(t,`id`),origin:E(t,`origin`),projectId:E(t,`projectId`),workspaceId:E(t,`workspaceId`),terminalId:E(t,`terminalId`),title:E(t,`title`),command:E(t,`command`),status:Qn(t.status),...j(`exitCode`,Qr(t,`exitCode`)),createdAt:E(t,`createdAt`),...j(`startedAt`,D(t,`startedAt`)),...j(`completedAt`,D(t,`completedAt`)),metadata:$n(t.metadata,`metadata`)}}function Qn(e){if(e!==`queued`&&e!==`running`&&e!==`succeeded`&&e!==`failed`)throw Error(`Invalid terminal command run status`);return e}function $n(e,t){let n=T(e);return Object.fromEntries(Object.entries(n).map(([e,n])=>{if(typeof n!=`string`)throw Error(`Expected string record field: ${t}.${e}`);return[e,n]}))}function er(e){let t=T(e);return{cwd:E(t,`cwd`),hasSessionActivity:k(t,`hasSessionActivity`),hasTerminalActivity:k(t,`hasTerminalActivity`),updatedAt:E(t,`updatedAt`)}}function tr(e){let t=T(e);return{workspaces:A(er)(t.workspaces),generatedAt:E(t,`generatedAt`)}}function nr(e){let t=T(e);return{path:E(t,`path`),exists:k(t,`exists`),config:rr(t.config),effectiveConfig:rr(t.effectiveConfig),envOverrides:pr(t.envOverrides)}}function rr(e){let t=T(e);return{...j(`host`,D(t,`host`)),...j(`port`,Qr(t,`port`)),...j(`allowedHosts`,ar(t.allowedHosts)),...j(`shortcuts`,dr(t.shortcuts)),...j(`plugins`,fr(t.plugins)),...j(`pathAccess`,or(t.pathAccess)),...j(`uploads`,cr(t.uploads)),...j(`maxUploadBytes`,Qr(t,`maxUploadBytes`)),...j(`agent`,ir(t.agent)),...j(`spawnSessions`,Zr(t,`spawnSessions`)),...j(`subsessions`,Zr(t,`subsessions`))}}function ir(e){if(e!==void 0){if(!Bt(e)||Array.isArray(e))throw Error(`Invalid PI WEB agent field`);return{...j(`command`,D(e,`command`)),...j(`dir`,D(e,`dir`))}}}function ar(e){if(e!==void 0){if(e===!0)return!0;if(lr(e))return e;throw Error(`Invalid PI WEB allowedHosts field`)}}function or(e){if(e===void 0)return;if(!Bt(e))throw Error(`Invalid PI WEB pathAccess field`);let t=e.allowedPaths;return{...j(`allowedPaths`,sr(t,`pathAccess.allowedPaths`))}}function sr(e,t){if(e!==void 0){if(ur(e))return e;throw Error(`Invalid PI WEB ${t} field`)}}function cr(e){if(e!==void 0){if(!Bt(e)||Array.isArray(e))throw Error(`Invalid PI WEB uploads field`);return{...j(`defaultFolder`,D(e,`defaultFolder`))}}}function lr(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function ur(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`&&e!==``)}function dr(e){if(e!==void 0){if(!Bt(e)||Array.isArray(e))throw Error(`Invalid PI WEB shortcuts field`);return Object.fromEntries(Object.entries(e).map(([e,t])=>{if(t!==null&&(typeof t!=`string`||t===``))throw Error(`Invalid PI WEB shortcut field`);return[e,t]}))}}function fr(e){if(e!==void 0){if(!Bt(e)||Array.isArray(e))throw Error(`Invalid PI WEB plugins field`);return Object.fromEntries(Object.entries(e).map(([e,t])=>{if(!Bt(t)||Array.isArray(t))throw Error(`Invalid PI WEB plugin config field`);let n=t.enabled;if(n!==void 0&&typeof n!=`boolean`)throw Error(`Invalid PI WEB plugin enabled field`);let r=t.settings;if(r!==void 0&&(!Bt(r)||Array.isArray(r)))throw Error(`Invalid PI WEB plugin settings field`);return[e,t]}))}}function pr(e){let t=T(e);return{host:k(t,`host`),port:k(t,`port`),allowedHosts:k(t,`allowedHosts`),spawnSessions:k(t,`spawnSessions`),subsessions:k(t,`subsessions`),agentCommand:Zr(t,`agentCommand`)??!1,agentDir:Zr(t,`agentDir`)??!1,...mr(t),agentSessionDir:Zr(t,`agentSessionDir`)??!1}}function mr(e){let t=e.agentDirSource;if(t===void 0)return{};if(t!==`pi-web`&&t!==`pi-compatibility`)throw Error(`Invalid PI WEB agentDirSource field`);return{agentDirSource:t}}function hr(e){let t=T(e);return{packages:A(_r)(t.packages)}}function gr(e){let t=T(e),n=D(t,`source`),r=t.scope===void 0?void 0:vr(t.scope),i=Cr(t.removed,`removed`);return{action:yr(t.action),...j(`source`,n),...j(`scope`,r),...j(`removed`,i),packages:A(_r)(t.packages)}}function _r(e){let t=T(e);return{source:E(t,`source`),scope:vr(t.scope),filtered:k(t,`filtered`),...j(`installedPath`,D(t,`installedPath`))}}function vr(e){if(e!==`user`&&e!==`project`)throw Error(`Invalid Pi package scope`);return e}function yr(e){if(e!==`install`&&e!==`remove`&&e!==`update`)throw Error(`Invalid Pi package mutation action`);return e}function br(e){let t=T(e);return{plugins:A(xr)(t.plugins)}}function xr(e){let t=T(e);return{id:E(t,`id`),module:E(t,`module`),source:E(t,`source`),scope:Sr(t.scope),machineSpecific:Cr(t.machineSpecific,`machineSpecific`)??!1,enabled:k(t,`enabled`)}}function Sr(e){if(e!==`bundled`&&e!==`local`&&e!==`user`&&e!==`project`)throw Error(`Invalid PI WEB plugin scope`);return e}function Cr(e,t){if(e!==void 0){if(typeof e!=`boolean`)throw Error(`Expected optional boolean field: ${t}`);return e}}function wr(e){let t=T(e);return{packageName:E(t,`packageName`),generatedAt:E(t,`generatedAt`),components:Er(t.components),release:jr(t.release),commands:Mr(t.commands),messages:A(Nr)(t.messages)}}function Tr(e){let t=T(e);return{packageName:E(t,`packageName`),generatedAt:E(t,`generatedAt`),components:Dr(t.components),capabilities:Fr(t.capabilities)}}function Er(e){let t=T(e);return{web:kr(t.web),sessiond:kr(t.sessiond)}}function Dr(e){let t=T(e);return{web:Or(t.web),sessiond:Or(t.sessiond)}}function Or(e){let t=T(e),n=Pr(t.component),r=t.activeAgentProfile,i=r===void 0?void 0:kt(r);if(r!==void 0&&(n!==`sessiond`||i===void 0))throw Error(`Invalid active agent profile descriptor`);return{component:n,label:E(t,`label`),...j(`runtimeVersion`,D(t,`runtimeVersion`)),available:k(t,`available`),capabilities:Fr(t.capabilities),...j(`activeAgentProfile`,i),...j(`error`,D(t,`error`))}}function kr(e){let t=T(e);return{component:Pr(t.component),label:E(t,`label`),...j(`runtimeVersion`,D(t,`runtimeVersion`)),...j(`installedVersion`,D(t,`installedVersion`)),stale:k(t,`stale`),available:k(t,`available`),...j(`installation`,Ar(t.installation)),...j(`error`,D(t,`error`))}}function Ar(e){if(e===void 0)return;let t=T(e),n=E(t,`kind`);if(n!==`pi-package`&&n!==`npm-global`&&n!==`local`&&n!==`docker`&&n!==`unknown`)throw Error(`Invalid PI WEB installation kind`);let r=t.scope;if(r!==void 0&&r!==`user`&&r!==`project`)throw Error(`Invalid PI WEB installation scope`);let i=t.dockerMode;if(i!==void 0&&i!==`runtime`&&i!==`dev`)throw Error(`Invalid PI WEB Docker mode`);return{kind:n,...j(`path`,D(t,`path`)),...j(`source`,D(t,`source`)),...r===void 0?{}:{scope:r},...j(`npmRoot`,D(t,`npmRoot`)),...i===void 0?{}:{dockerMode:i}}}function jr(e){let t=T(e);return{packageName:E(t,`packageName`),...j(`latestVersion`,D(t,`latestVersion`)),updateAvailable:k(t,`updateAvailable`),...j(`checkedAt`,D(t,`checkedAt`)),...t.skipped===!0?{skipped:!0}:{},...j(`error`,D(t,`error`))}}function Mr(e){let t=T(e);return{...j(`update`,D(t,`update`)),...j(`restart`,D(t,`restart`)),...j(`restartWeb`,D(t,`restartWeb`)),...j(`restartSessiond`,D(t,`restartSessiond`)),...j(`status`,D(t,`status`))}}function Nr(e){let t=T(e);return{id:E(t,`id`),severity:Ir(t.severity),title:E(t,`title`),body:E(t,`body`),...j(`command`,D(t,`command`))}}function Pr(e){if(e!==`web`&&e!==`sessiond`)throw Error(`Invalid PI WEB service component`);return e}function Fr(e){let t=zt(e);if(t===void 0)throw Error(`Invalid PI WEB capabilities`);return t}function Ir(e){if(e!==`info`&&e!==`warning`&&e!==`error`)throw Error(`Invalid PI WEB status severity`);return e}function Lr(e){let t=T(e),n=E(t,`type`);if(n===`unsupported`)return{type:n,message:E(t,`message`)};if(n===`select`)return{type:n,requestId:E(t,`requestId`),title:E(t,`title`),options:A(Rr)(t.options)};if(n===`done`)return{type:n,...j(`message`,D(t,`message`)),...zr(t.session),...j(`promptDraft`,D(t,`promptDraft`))};throw Error(`Invalid command result type`)}function Rr(e){let t=T(e);return{value:E(t,`value`),label:E(t,`label`),...j(`description`,D(t,`description`))}}function zr(e){return e===void 0?{}:{session:$t(e)}}function Br(e){if(T(e).accepted!==!0)throw Error(`Expected accepted response`);return{accepted:!0}}function Vr(e){let t=T(e);return A(Hr)(t.attachments)}function Hr(e){let t=T(e);return{path:E(t,`path`),mimeType:E(t,`mimeType`),size:O(t,`size`)}}function Ur(e){if(T(e).closed!==!0)throw Error(`Expected closed response`);return{closed:!0}}function Wr(e){if(T(e).aborted!==!0)throw Error(`Expected aborted response`);return{aborted:!0}}function Gr(e){if(T(e).stopped!==!0)throw Error(`Expected stopped response`);return{stopped:!0}}function Kr(e){let t=T(e);if(t.archived!==!0)throw Error(`Expected archived response`);let n=t.sessionIds===void 0?void 0:Ht(t.sessionIds,`sessionIds`),r=Qr(t,`archivedCount`),i=Qr(t,`skippedAlreadyArchivedCount`);return{archived:!0,...n===void 0?{}:{sessionIds:n},...r===void 0?{}:{archivedCount:r},...i===void 0?{}:{skippedAlreadyArchivedCount:i}}}function qr(e){if(T(e).restored!==!0)throw Error(`Expected restored response`);return{restored:!0}}function Jr(e){if(T(e).deleted!==!0)throw Error(`Expected deleted response`);return{deleted:!0}}function Yr(e){if(T(e).detached!==!0)throw Error(`Expected detached response`);return{detached:!0}}function Xr(e){if(T(e).reloaded!==!0)throw Error(`Expected reloaded response`);return{reloaded:!0}}function Zr(e,t){let n=e[t];if(n!==void 0){if(typeof n!=`boolean`)throw Error(`Invalid PI WEB ${t} field`);return n}}function Qr(e,t){let n=e[t];if(n!==void 0){if(typeof n!=`number`)throw Error(`Expected optional number field: ${t}`);return n}}function $r(e,t){let n=e[t];if(n===null)return null;if(typeof n!=`number`)throw Error(`Expected number|null field: ${t}`);return n}function j(e,t){return t===void 0?{}:{[e]:t}}function ei(e){return typeof e==`string`?e:e.id}function ti(e){return typeof e==`string`?void 0:e.cwd}function ni(e,t,n,r){let i=new URLSearchParams;r?.path!==void 0&&i.set(`path`,r.path),r?.staged===!0&&i.set(`staged`,`true`);let a=i.toString();return`api/machines/${encodeURIComponent(e)}/projects/${encodeURIComponent(t)}/workspaces/${encodeURIComponent(n)}/git/diff${a?`?${a}`:``}`}function ri(e,t,n=`local`){let r=new URLSearchParams,i=ti(e);i!==void 0&&i!==``&&r.set(`cwd`,i),t?.limit!==void 0&&r.set(`limit`,String(t.limit)),t?.before!==void 0&&r.set(`before`,String(t.before));let a=r.toString();return`api/machines/${encodeURIComponent(n)}/sessions/${encodeURIComponent(ei(e))}/messages${a===``?``:`?${a}`}`}function ii(e,t,n,r){let i=new URLSearchParams({path:n});return r?.createDirs===!1&&i.set(`createDirs`,`false`),r?.overwrite===!1&&i.set(`overwrite`,`false`),_t(`${`api/machines/${encodeURIComponent(r?.machineId??`local`)}`}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file?${i.toString()}`)}function ai(e,t,n,r){let i=new URLSearchParams;return i.set(`path`,n),r?.modifiedAt!==void 0&&i.set(`v`,r.modifiedAt),_t(`${`api/machines/${encodeURIComponent(r?.machineId??`local`)}`}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file/preview?${i.toString()}`)}var M=(e=`local`)=>`api/machines/${encodeURIComponent(e)}`;function oi(e){return typeof e==`string`?e:e.id}function si(e){return typeof e==`string`?void 0:e.cwd}function ci(e,t=`local`){return`${M(t)}/sessions/${encodeURIComponent(oi(e))}`}function N(e,t,n=`local`){return`${ci(e,n)}/${t}`}function li(e,t,n=`local`){return`${N(e,t,n)}${di(e)}`}function ui(e,t=`local`){return`${ci(e,t)}${di(e)}`}function di(e){let t=si(e);return t===void 0||t===``?``:`?${new URLSearchParams({cwd:t}).toString()}`}function P(e,t={}){let n=si(e);return JSON.stringify(n===void 0||n===``?t:{cwd:n,...t})}function fi(e){return JSON.stringify({sessions:e.map(pi)})}function pi(e){let t=oi(e),n=si(e);return n===void 0||n===``?{id:t}:{id:t,cwd:n}}function mi(e){return e===`local`?`api/pi-web/status`:`${M(e)}/pi-web/status`}var hi={piWebStatus:(e=`local`)=>C(mi(e),wr),checkForUpdates:(e=`local`)=>C(`${mi(e)}?refresh=1`,wr,{cache:`no-store`}),piWebRuntime:()=>C(`api/pi-web/runtime`,Tr)},gi={machines:()=>C(`api/machines`,Wt),addMachine:e=>C(`api/machines`,Gt,{method:`POST`,body:JSON.stringify(e)}),deleteMachine:e=>C(`api/machines/${encodeURIComponent(e)}`,e=>e,{method:`DELETE`}),health:e=>C(`api/machines/${encodeURIComponent(e)}/health`,Kt),runtime:(e,t=!1)=>C(`api/machines/${encodeURIComponent(e)}/runtime${t?`?refresh=1`:``}`,qt,t?{cache:`no-store`}:{})};function _i(e){return e===void 0?`api/config`:`${M(e)}/config`}function vi(e){return e===void 0?`api/plugins`:`${M(e)}/plugins`}var yi={config:e=>C(_i(e),nr),saveConfig:(e,t)=>C(_i(t),nr,{method:`PUT`,body:JSON.stringify({config:e})})},bi={plugins:e=>C(vi(e),br)};function xi(e=``,t){let n=t===void 0?`api/pi-packages`:`${M(t)}/pi-packages`;return e===``?n:`${n}/${e}`}var Si={packages:e=>C(xi(``,e),hr),install:(e,t)=>{let n={source:e};return C(xi(`install`,t),gr,{method:`POST`,body:JSON.stringify(n)})},remove:(e,t,n)=>{let r=t===void 0?{source:e}:{source:e,scope:t};return C(xi(`remove`,n),gr,{method:`POST`,body:JSON.stringify(r)})},update:(e,t)=>{let n=e===void 0?void 0:{source:e};return C(xi(`update`,t),gr,{method:`POST`,...n===void 0?{}:{body:JSON.stringify(n)}})}},Ci={workspaceActivity:(e=`local`)=>C(`${M(e)}/activity`,tr)},wi={projects:(e=`local`)=>C(`${M(e)}/projects`,A(Xt)),addProject:(e,t,n,r=`local`)=>C(`${M(r)}/projects`,Xt,{method:`POST`,body:JSON.stringify({path:e,name:t,create:n})}),closeProject:(e,t=`local`)=>C(`${M(t)}/projects/${encodeURIComponent(e)}`,Ur,{method:`DELETE`}),projectDirectories:(e,t=`local`)=>C(`${M(t)}/project-directories?q=${encodeURIComponent(e)}`,A(Rn))},Ti={workspaces:(e,t=`local`)=>C(`${M(t)}/projects/${encodeURIComponent(e)}/workspaces`,A(Zt)),deleteWorkspace:(e,t,n=`local`)=>C(`${M(n)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}`,Zn,{method:`DELETE`}),workspaceTree:(e,t,n=``,r=`local`)=>C(`${M(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/tree?path=${encodeURIComponent(n)}`,zn),workspaceFile:(e,t,n,r=`local`)=>C(`${M(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file?path=${encodeURIComponent(n)}`,Vn),writeWorkspaceFile:(e,t,n,r,i,a=`local`)=>{let o=new URLSearchParams({path:n});i?.createDirs===!1&&o.set(`createDirs`,`false`),i?.overwrite===!1&&o.set(`overwrite`,`false`);let s=r instanceof Uint8Array,c=s?new Uint8Array(r):new TextEncoder().encode(r);return C(`${M(a)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file?${o.toString()}`,Hn,{method:`PUT`,body:c,headers:{"Content-Type":s?`application/octet-stream`:`text/plain`}})},deleteWorkspaceFile:(e,t,n,r=`local`)=>{let i=new URLSearchParams({path:n});return C(`${M(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file?${i.toString()}`,Un,{method:`DELETE`})},moveWorkspaceFile:(e,t,n,r,i,a=`local`)=>{let o=new URLSearchParams({fromPath:n,toPath:r});return i?.createDirs===!1&&o.set(`createDirs`,`false`),i?.overwrite===!0&&o.set(`overwrite`,`true`),C(`${M(a)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file/move?${o.toString()}`,Wn,{method:`POST`})}},Ei={sessions:(e,t=`local`)=>C(`${M(t)}/sessions?cwd=${encodeURIComponent(e)}`,A($t)),startSession:(e,t=`local`)=>C(`${M(t)}/sessions`,$t,{method:`POST`,body:JSON.stringify({cwd:e})}),cleanupPreview:(e,t=`local`)=>C(`${M(t)}/sessions/cleanup/preview`,sn,{method:`POST`,body:JSON.stringify(e)}),cleanup:(e,t=`local`)=>C(`${M(t)}/sessions/cleanup`,cn,{method:`POST`,body:JSON.stringify(e)}),archiveMany:(e,t=`local`)=>C(`${M(t)}/sessions/bulk/archive`,ln,{method:`POST`,body:fi(e)}),deleteArchivedMany:(e,t=`local`)=>C(`${M(t)}/sessions/bulk/delete-archived`,un,{method:`POST`,body:fi(e)}),messages:(e,t,n=`local`)=>C(ri(e,t,n),Ut),status:(e,t=`local`)=>C(li(e,`status`,t),an),streamSnapshot:(e,t=`local`)=>C(li(e,`stream-snapshot`,t),on),clearQueue:(e,t=`local`)=>C(N(e,`queue/clear`,t),an,{method:`POST`,body:P(e)}),dismissWarning:(e,t,n=`local`)=>C(N(e,`warnings/dismiss`,n),an,{method:`POST`,body:P(e,{dismissId:t})}),models:(e,t=`local`)=>C(li(e,`models`,t),yn),setModel:(e,t,n,r=`local`)=>C(N(e,`model`,r),an,{method:`POST`,body:P(e,{provider:t,modelId:n})}),cycleModel:(e,t,n=`local`)=>C(N(e,`model/cycle`,n),an,{method:`POST`,body:P(e,{direction:t})}),thinkingLevels:(e,t=`local`)=>C(li(e,`thinking-levels`,t),xn),setThinkingLevel:(e,t,n=`local`)=>C(N(e,`thinking-level`,n),an,{method:`POST`,body:P(e,{level:t})}),cycleThinkingLevel:(e,t=`local`)=>C(N(e,`thinking-level/cycle`,t),an,{method:`POST`,body:P(e)}),commands:(e,t=`local`)=>C(li(e,`commands`,t),A(Ln)),prompt:(e,t,n,r=`local`,i)=>C(N(e,`prompt`,r),Br,{method:`POST`,body:P(e,{text:t,...n===void 0?{}:{streamingBehavior:n},...i!==void 0&&i.length>0?{attachments:i}:{}})}),saveAttachments:(e,t,n=`local`,r)=>C(N(e,`attachments`,n),Vr,{method:`POST`,body:P(e,{attachments:t,...r===void 0?{}:{folder:r}})}),shell:(e,t,n=`local`)=>C(N(e,`shell`,n),Br,{method:`POST`,body:P(e,{text:t})}),runCommand:(e,t,n=`local`)=>C(N(e,`commands/run`,n),Lr,{method:`POST`,body:P(e,{text:t})}),respondToCommand:(e,t,n,r=`local`)=>C(N(e,`commands/respond`,r),Lr,{method:`POST`,body:P(e,{requestId:t,value:n})}),abort:(e,t=`local`)=>C(N(e,`abort`,t),Wr,{method:`POST`,body:P(e)}),stop:(e,t=`local`)=>C(N(e,`stop`,t),Gr,{method:`POST`,body:P(e)}),archive:(e,t=`local`)=>C(N(e,`archive`,t),Kr,{method:`POST`,body:P(e)}),archiveWithDescendants:(e,t=`local`)=>C(N(e,`archive-tree`,t),Kr,{method:`POST`,body:P(e)}),restore:(e,t=`local`)=>C(N(e,`restore`,t),qr,{method:`POST`,body:P(e)}),deleteArchived:(e,t=`local`)=>C(ui(e,t),Jr,{method:`DELETE`}),detachParent:(e,t=`local`)=>C(N(e,`detach-parent`,t),Yr,{method:`POST`,body:P(e)}),reloadSession:(e,t=`local`)=>C(N(e,`reload`,t),Xr,{method:`POST`,body:P(e)}),authProviders:e=>{let t=new URLSearchParams;e?.mode!==void 0&&t.set(`mode`,e.mode),e?.authType!==void 0&&t.set(`authType`,e.authType);let n=t.toString();return C(`${M(e?.machineId)}/auth/providers${n===``?``:`?${n}`}`,En)},saveApiKey:(e,t,n=`local`)=>C(`${M(n)}/auth/api-key`,Br,{method:`POST`,body:JSON.stringify({providerId:e,key:t})}),startInteractiveApiKeyLogin:(e,t=`local`)=>C(`${M(t)}/auth/api-key/interactive`,Dn,{method:`POST`,body:JSON.stringify({providerId:e})}),logoutProvider:(e,t=`local`)=>C(`${M(t)}/auth/logout`,Br,{method:`POST`,body:JSON.stringify({providerId:e})}),startOAuthLogin:(e,t=`local`)=>C(`${M(t)}/auth/oauth`,Dn,{method:`POST`,body:JSON.stringify({providerId:e})}),oauthFlow:(e,t=`local`)=>C(`${M(t)}/auth/oauth/${encodeURIComponent(e)}`,Dn),respondOAuthFlow:(e,t,n,r=`local`)=>C(`${M(r)}/auth/oauth/${encodeURIComponent(e)}/respond`,Dn,{method:`POST`,body:JSON.stringify({requestId:t,value:n})}),cancelOAuthFlow:(e,t=`local`)=>C(`${M(t)}/auth/oauth/${encodeURIComponent(e)}/cancel`,Dn,{method:`POST`})},Di={terminals:(e,t,n=`local`)=>C(`${M(n)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals`,A(Xn)),startTerminal:(e,t,n,r=`local`)=>C(`${M(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals`,Xn,{method:`POST`,body:JSON.stringify(n??{})}),closeWorkspaceTerminals:(e,t,n=`local`)=>C(`${M(n)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals`,Ur,{method:`DELETE`}),closeTerminal:(e,t,n,r=`local`)=>C(`${M(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals/${encodeURIComponent(n)}`,Ur,{method:`DELETE`}),continueTerminal:(e,t,n,r=`local`)=>C(`${M(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals/${encodeURIComponent(n)}/continue`,Xn,{method:`POST`}),runTerminalCommand:(e,t,n=`local`)=>C(`${M(n)}/projects/${encodeURIComponent(t.workspace.projectId)}/workspaces/${encodeURIComponent(t.workspace.id)}/terminal-command-runs`,Zn,{method:`POST`,body:JSON.stringify({origin:e,title:t.title,command:t.command,metadata:t.metadata??{}})}),listCommandRuns:(e,t=`local`)=>C(`${M(t)}/terminal-command-runs${ki(e)}`,A(Zn)),getCommandRun:(e,t=`local`)=>Oi(e,t),cancelCommandRun:(e,t=`local`)=>C(`${M(t)}/terminal-command-runs/${encodeURIComponent(e)}/cancel`,Zn,{method:`POST`})};async function Oi(e,t){let n=await fetch(_t(`${M(t)}/terminal-command-runs/${encodeURIComponent(e)}`));if(n.status!==404){if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(Ai(e)??n.statusText)}return Zn(await n.json())}}function ki(e){if(e===void 0)return``;let t=new URLSearchParams;e.projectId!==void 0&&t.set(`projectId`,e.projectId),e.workspaceId!==void 0&&t.set(`workspaceId`,e.workspaceId),e.terminalId!==void 0&&t.set(`terminalId`,e.terminalId),e.statuses!==void 0&&e.statuses.length>0&&t.set(`statuses`,e.statuses.join(`,`)),e.metadata!==void 0&&Object.keys(e.metadata).length>0&&t.set(`metadata`,JSON.stringify(e.metadata));let n=t.toString();return n===``?``:`?${n}`}function Ai(e){if(!ji(e))return;let t=e.error;return typeof t==`string`?t:void 0}function ji(e){return typeof e==`object`&&!!e}var Mi={files:(e,t,n={})=>{let r=new URLSearchParams({q:t});return n.kind!==void 0&&r.set(`kind`,n.kind),n.mode!==void 0&&r.set(`mode`,n.mode),n.scope!==void 0&&r.set(`scope`,n.scope),n.workspaceScoped===!0&&n.projectId!==void 0&&n.workspaceId!==void 0?C(`${M(n.machineId)}/projects/${encodeURIComponent(n.projectId)}/workspaces/${encodeURIComponent(n.workspaceId)}/files?${r.toString()}`,A(Rn)):(r.set(`cwd`,e),C(`${M(n.machineId)}/files?${r.toString()}`,A(Rn)))}},Ni={gitStatus:(e,t,n=`local`)=>C(`${M(n)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/git/status`,Kn),gitDiff:(e,t,n,r=`local`)=>C(ni(r,e,t,n),Yn)},F={...hi,...gi,...yi,...bi,...Si,...Ci,...wi,...Ti,...Ei,...Di,...Mi,...Ni};function Pi(e,t=`local`){let n=typeof e==`string`?void 0:e.cwd,r=n===void 0||n===``?``:`?${new URLSearchParams({cwd:n}).toString()}`,i=typeof e==`string`?e:e.id;return new WebSocket(vt(`${Li(t)}/sessions/${encodeURIComponent(i)}/events${r}`))}function Fi(e,t,n,r,i=`local`){let a=r===void 0?``:`?${new URLSearchParams({cols:String(r.cols),rows:String(r.rows)}).toString()}`;return new WebSocket(vt(`${Li(i)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals/${encodeURIComponent(n)}/socket${a}`))}function Ii(e=`local`){return new WebSocket(vt(`${Li(e)}/events`))}function Li(e){return`api/machines/${encodeURIComponent(e)}`}var Ri=`.pi-web/uploads`,zi=class extends Error{constructor(e=`Workspace upload cancelled`){super(e),this.name=`WorkspaceUploadCancelledError`}},Bi=class extends Error{constructor(e,t){super(Zi(e)),this.name=`WorkspaceUploadBatchError`,this.failures=e.map(e=>({...e})),this.responses=t.map(e=>({...e}))}};function Vi(e){return e?.uploads?.defaultFolder??`.pi-web/uploads`}function Hi(e,t){return e?.uploads?.defaultFolder??t}function Ui(e,t){let n=ea(e,`upload destination`,{allowEmpty:!0}),r=ea(t,`upload file name`,{allowEmpty:!1});return n===``?r:`${n}/${r}`}function Wi(e,t,n,r={}){let i=r.xhrFactory?.()??new XMLHttpRequest,a=!1,o=!1;return{promise:new Promise((s,c)=>{let l=e=>{a||(a=!0,c(e))},u=e=>{a||(a=!0,s(e))};i.open(`PUT`,ii(e,t,n.path,qi(r)),!0),i.responseType=`json`,i.setRequestHeader(`Content-Type`,(n.contentType??n.file.type)||`application/octet-stream`),i.upload.onprogress=e=>{r.onProgress?.(Ji(e,n.file.size))},i.onload=()=>{if(i.status>=200&&i.status<300){try{r.onProgress?.({loaded:n.file.size,total:n.file.size,percent:1,lengthComputable:!0}),u(Hn(na(i)))}catch(e){l(e instanceof Error?e:Error(String(e)))}return}l(Error(ra(i)))},i.onerror=()=>{l(Error(`Workspace upload failed`))},i.onabort=()=>{l(new zi(o?void 0:`Workspace upload aborted`))},i.send(n.file)}),cancel:()=>{a||(o=!0,i.abort())}}}function Gi(e,t,n,r={}){let i=r.destinationFolder??`.pi-web/uploads`,a=n.map((e,t)=>({index:t,name:e.name,path:Ui(i,e.name),loaded:0,total:e.size,percent:Xi(0,e.size),lengthComputable:!0,done:!1})),o,s=0,c={requested:!1},l=()=>{r.onProgress?.(Yi(a,s,a.every(e=>e.done)))};return{promise:(async()=>{let i=[],u=[];for(let d=0;d<n.length;d+=1){if(c.requested)throw new zi;s=d;let f=n[d],p=a[d];if(!(f===void 0||p===void 0)){o=Wi(e,t,{path:p.path,file:f},{...Ki(r),onProgress:e=>{p.total=e.total,p.loaded=Math.min(e.loaded,p.total),p.percent=e.percent,p.lengthComputable=e.lengthComputable,l()}});try{let e=await o.promise;p.loaded=p.total,p.percent=1,p.lengthComputable=!0,p.done=!0,i.push(e),l()}catch(e){if($i(e,c))throw e;let t=Qi(e);p.loaded=p.total,p.percent=1,p.lengthComputable=!0,p.done=!0,p.error=t,u.push({index:d,name:f.name,path:p.path,error:t}),l()}finally{o=void 0}}}if(u.length>0)throw new Bi(u,i);return i})(),cancel:()=>{c.requested=!0,o?.cancel()}}}function Ki(e){return{...e.createDirs===void 0?{}:{createDirs:e.createDirs},...e.overwrite===void 0?{}:{overwrite:e.overwrite},...e.machineId===void 0?{}:{machineId:e.machineId},...e.xhrFactory===void 0?{}:{xhrFactory:e.xhrFactory}}}function qi(e){return{...e.createDirs===void 0?{}:{createDirs:e.createDirs},...e.overwrite===void 0?{}:{overwrite:e.overwrite},...e.machineId===void 0?{}:{machineId:e.machineId}}}function Ji(e,t){let n=e.lengthComputable?e.total:t;return{loaded:e.loaded,total:n,percent:Xi(e.loaded,n),lengthComputable:e.lengthComputable}}function Yi(e,t,n){let r=e.reduce((e,t)=>e+t.total,0),i=e.reduce((e,t)=>e+t.loaded,0);return{currentFileIndex:t,files:e.map(e=>({...e})),loaded:i,total:r,percent:Xi(i,r),done:n}}function Xi(e,t){return t<=0?e<=0?0:1:Math.max(0,Math.min(1,e/t))}function Zi(e){return e.length===1?e[0]?.error??`Workspace upload failed`:`${String(e.length)} files failed to upload`}function Qi(e){return e instanceof Error?e.message:String(e)}function $i(e,t){return t.requested||e instanceof zi}function ea(e,t,n){let r=e.trim();if(r===``){if(n.allowEmpty)return``;throw Error(`${t} must not be empty`)}if(ta(r))throw Error(`${t} must be workspace-relative`);let i=r.split(/[\\/]+/u).filter(e=>e!==``&&e!==`.`);if(i.length===0){if(n.allowEmpty)return``;throw Error(`${t} must not be empty`)}if(i.some(e=>e===`..`))throw Error(`${t} must not contain path traversal`);return i.join(`/`)}function ta(e){let t=e.replace(/\\/g,`/`);return t.startsWith(`/`)||/^[A-Za-z]:\//u.test(t)}function na(e){return e.response!==void 0&&e.response!==null&&e.response!==``?e.response:e.responseText===``?{}:JSON.parse(e.responseText)}function ra(e){let t=ia(e);return aa(t)&&typeof t.error==`string`?t.error:e.statusText||`HTTP ${String(e.status)}`}function ia(e){try{return na(e)}catch{return}}function aa(e){return typeof e==`object`&&!!e}function oa(){return{sessions:[],clientQueuedSessionMessages:{},startingSessionCount:0,fileTree:[],expandedDirs:{},selectedFilePath:void 0,selectedFileContent:void 0,fileTreeStale:!1,gitStatus:void 0,selectedDiffPath:void 0,selectedDiff:void 0,selectedStagedDiff:void 0,gitStale:!1,selectedTerminalId:void 0,error:``}}function sa(){return{machines:[],selectedMachine:void 0,isLoadingMachines:!1,machineStatuses:{},machineRuntimes:{},projects:[],workspaces:[],sessions:[],messages:[],messagePageStart:0,messagePageEnd:0,messagePageTotal:0,isLoadingEarlierMessages:!1,sendingPrompts:{},clientQueuedSessionMessages:{},startingSessionCount:0,isLoadingProjects:!1,isLoadingWorkspaces:!1,selectedProject:void 0,selectedWorkspace:void 0,selectedSession:void 0,status:void 0,activity:void 0,availableThinkingLevels:[],sessionStatuses:{},sessionActivities:{},workspaceActivities:{},machineActivities:{},workspacesByProjectId:{},workspaceDeletionRuns:{},commandDialog:void 0,modelDialog:void 0,thinkingDialog:void 0,themeDialog:void 0,authDialog:void 0,actionPaletteOpen:!1,projectDialogOpen:!1,machineDialogOpen:!1,workspaceTool:`core:workspace.files`,mainView:`chat`,fileTree:[],expandedDirs:{},selectedFilePath:void 0,selectedFileContent:void 0,fileTreeStale:!1,workspaceUploadBatches:{},gitStatus:void 0,selectedDiffPath:void 0,selectedDiff:void 0,selectedStagedDiff:void 0,gitStale:!1,activeTerminalCount:0,selectedTerminalId:void 0,piWebStatus:void 0,error:``}}function ca(e,t){return t?.phase===`active`||e?.isStreaming===!0||e?.isBashRunning===!0||e?.isCompacting===!0||(e?.pendingMessageCount??0)>0}function la(e){return e!==void 0&&(e.hasSessionActivity||e.hasTerminalActivity)}function ua(e,t){return`${e}:${t}`}function da(e,t){return`${e}:${t}`}function I(e){return e.selectedMachine?.id??`local`}var fa=class{constructor(){this.pendingByKey=new Map}request(e,t){let n=this.pendingByKey.get(e);if(n!==void 0)return n.latestRefresh=t,n.started&&(n.trailing=!0),n.promise;let r={promise:Promise.resolve(),latestRefresh:t,started:!1,trailing:!1};return r.promise=Promise.resolve().then(async()=>{let e,t;do{r.trailing=!1;let n=r.latestRefresh;r.started=!0,t=!1;try{await n()}catch(n){e=n,t=!0}}while(this.hasTrailingRequest(r));if(t)throw e}).finally(()=>{this.pendingByKey.get(e)===r&&this.pendingByKey.delete(e)}),this.pendingByKey.set(e,r),r.promise}hasTrailingRequest(e){return e.trailing}},pa=class{constructor(e,t,n={}){this.getState=e,this.setState=t,this.refreshes=new fa,this.api=n.api??Ci}refresh(e=I(this.getState())){return this.refreshes.request(e,async()=>{this.applyMachineActivitySnapshot(e,ma(await this.api.workspaceActivity(e)))})}applyWorkspaceActivity(e,t=I(this.getState())){let n=this.getState(),r=I(n)===t,i=ha(n.machineActivities[t]??(r?n.workspaceActivities:{}),e);this.setState({machineActivities:{...n.machineActivities,[t]:i},...r?{workspaceActivities:i}:{}})}applyMachineActivitySnapshot(e,t){let n=this.getState();this.setState({machineActivities:{...n.machineActivities,[e]:t},...I(n)===e?{workspaceActivities:t}:{}})}};function ma(e){let t={};for(let n of e.workspaces)la(n)&&(t[n.cwd]=n);return t}function ha(e,t){let n={...e};return la(t)?(n[t.cwd]=t,n):Object.fromEntries(Object.entries(n).filter(([e])=>e!==t.cwd))}var ga=class{constructor(e,t,n,r={}){this.getState=e,this.setState=t,this.applyStatus=n,this.oauthOperationGeneration=0,this.pollGeneration=0,this.api=r.api??F,this.pollIntervalMs=r.pollIntervalMs??1e3}dispose(){this.oauthOperationGeneration+=1,this.stopPolling()}handleSlashCommand(e){let t=va(e);return t===void 0?!1:(t.command===`login`?this.openLogin(t.providerId):this.openLogout(t.providerId),!0)}async openLogin(e){if(e!==void 0&&e!==``){await this.openLoginProvider(e);return}this.setState({authDialog:{step:`method`}})}async chooseLoginMethod(e){try{let{providers:t}=await this.api.authProviders({mode:`login`,authType:e,machineId:I(this.getState())});this.setState({authDialog:{step:`providers`,mode:`login`,authType:e,providers:t}})}catch(e){this.setState({error:String(e)})}}async selectLoginProvider(e,t){let n=this.getState().authDialog;if(n?.step!==`providers`)return;let r=n.providers.find(n=>n.id===e&&(t===void 0||n.authType===t));r!==void 0&&(r.authType===`oauth`||r.loginFlow===`interactive`?await this.startLoginFlow(r):this.setState({authDialog:{step:`apiKey`,provider:r,value:``}}))}updateApiKey(e){let t=this.getState().authDialog;if(t?.step!==`apiKey`)return;let n={...t};delete n.error,this.setState({authDialog:{...n,value:e}})}async saveApiKey(){let e=this.getState().authDialog;if(e?.step!==`apiKey`)return;let t=e.value.trim();if(t===``){this.setState({authDialog:{...e,error:`API key is required`}});return}let n={...e};delete n.error,this.setState({authDialog:{...n,saving:!0}});try{await this.api.saveApiKey(e.provider.id,t,I(this.getState())),this.closeDialog(),this.refreshStatus()}catch(t){this.setState({authDialog:{...e,saving:!1,error:String(t)}})}}async openLogout(e){try{let{providers:t}=await this.api.authProviders({mode:`logout`,machineId:I(this.getState())});if(e!==void 0&&e!==``){let n=t.find(t=>t.id===e);n!==void 0&&!this.rejectRemoteOAuth(`logout`,n)?await this.logoutProvider(n.id):n===void 0&&this.setState({error:`No stored credentials for ${e}`});return}this.setState({authDialog:{step:`logout`,providers:t}})}catch(e){this.setState({error:String(e)})}}async logoutProvider(e){let t=this.getState().authDialog,n=t?.step===`logout`?t.providers.find(t=>t.id===e):void 0;if(!(n!==void 0&&this.rejectRemoteOAuth(`logout`,n)))try{await this.api.logoutProvider(e,I(this.getState())),this.closeDialog(),this.refreshStatus()}catch(e){this.setState({error:String(e)})}}updateOAuthInput(e){let t=this.getState().authDialog;if(t?.step!==`oauth`)return;let n={...t};delete n.error,this.setState({authDialog:{...n,inputValue:e}})}async respondOAuth(e){let t=this.getState().authDialog;if(t?.step!==`oauth`)return;let n=t.flow.prompt??t.flow.select;if(n===void 0)return;let r=this.oauthOperationGeneration,i=t.flow.flowId,a=n.requestId,o=e??t.inputValue??``,s={...t};delete s.error,this.setState({authDialog:{...s,responding:!0}});try{let e=await this.api.respondOAuthFlow(i,a,o,t.machineId),n=this.currentOAuthDialog(r,i);if(e.flowId!==i||n===void 0||_a(n.flow)!==a)return;this.updateOAuthFlow(e,n.machineId)}catch(e){let t=this.currentOAuthDialog(r,i);if(t===void 0||_a(t.flow)!==a)return;this.setState({authDialog:{...t,responding:!1,error:String(e)}})}}async cancelOAuth(){let e=this.getState().authDialog;if(e?.step!==`oauth`){this.closeDialog();return}let t=e.flow.flowId,n=e.machineId;this.closeDialog();try{await this.api.cancelOAuthFlow(t,n)}catch{}}closeDialog(){this.oauthOperationGeneration+=1,this.stopPolling(),this.setState({authDialog:void 0})}async openLoginProvider(e){try{let{providers:t}=await this.api.authProviders({mode:`login`,machineId:I(this.getState())}),n=t.filter(t=>t.id===e);if(n.length===0){this.setState({error:`Auth provider not found: ${e}`});return}if(n.length>1){this.setState({authDialog:{step:`providers`,mode:`login`,providers:n}});return}let r=n[0];if(r===void 0)return;r.authType===`oauth`||r.loginFlow===`interactive`?await this.startLoginFlow(r):this.setState({authDialog:{step:`apiKey`,provider:r,value:``}})}catch(e){this.setState({error:String(e)})}}async startLoginFlow(e){if(this.rejectRemoteOAuth(`login`,e))return;let t=++this.oauthOperationGeneration;this.stopPolling();try{let n=I(this.getState()),r=e.authType===`oauth`?await this.api.startOAuthLogin(e.id,n):await this.api.startInteractiveApiKeyLogin(e.id,n);if(t!==this.oauthOperationGeneration){if(r.status===`running`)try{await this.api.cancelOAuthFlow(r.flowId,n)}catch{}return}this.updateOAuthFlow(r,n),r.status===`running`&&this.startPolling(r.flowId,n)}catch(e){t===this.oauthOperationGeneration&&this.setState({error:String(e)})}}rejectRemoteOAuth(e,t){let n=this.getState().selectedMachine;if(t.authType!==`oauth`||n?.kind!==`remote`)return!1;let r=n.baseUrl??`that remote PI WEB instance`;return this.setState({error:`OAuth ${e} for remote machines must be configured directly on ${r}.`}),!0}updateOAuthFlow(e,t){if(e.status===`complete`){this.stopPolling(),this.closeDialog(),this.refreshStatus(t);return}(e.status===`error`||e.status===`cancelled`)&&(this.oauthOperationGeneration+=1,this.stopPolling());let n=this.getState().authDialog,r=n?.step===`oauth`&&n.flow.flowId===e.flowId?n.inputValue??``:``,i=n?.step===`oauth`?_a(n.flow):void 0,a=_a(e),o=i!==void 0&&i===a,s=o?r:``,c=o&&n?.step===`oauth`?n.responding===!0:!1;this.setState({authDialog:{step:`oauth`,flow:e,machineId:t,inputValue:s,responding:c}})}startPolling(e,t){this.stopPolling();let n=this.oauthOperationGeneration,r=this.pollGeneration;this.pollTimer=window.setInterval(()=>{this.poll(e,t,n,r)},this.pollIntervalMs)}stopPolling(){this.pollGeneration+=1,this.pollTimer!==void 0&&(window.clearInterval(this.pollTimer),this.pollTimer=void 0)}async poll(e,t,n,r){if(r!==this.pollGeneration)return;let i=this.currentOAuthDialog(n,e);if(i?.machineId!==t){this.stopPolling();return}let a=_a(i.flow);try{let i=await this.api.oauthFlow(e,t),o=this.currentOAuthDialog(n,e);if(i.flowId!==e||r!==this.pollGeneration||o?.machineId!==t||_a(o.flow)!==a)return;this.updateOAuthFlow(i,t)}catch(i){let o=this.currentOAuthDialog(n,e);if(r!==this.pollGeneration||o?.machineId!==t||_a(o.flow)!==a)return;this.stopPolling(),this.setState({authDialog:{...o,error:String(i)}})}}currentOAuthDialog(e,t){if(e!==this.oauthOperationGeneration)return;let n=this.getState().authDialog;return n?.step===`oauth`&&n.flow.flowId===t?n:void 0}async refreshStatus(e=I(this.getState())){let t=this.selectedSessionForMachine(e);if(t!==void 0)try{let n=await this.api.status(t,e),r=this.selectedSessionForMachine(e);if(r?.id!==t.id||r.cwd!==t.cwd)return;this.applyStatus(n)}catch{}}selectedSessionForMachine(e){let t=this.getState();if(I(t)!==e)return;let n=t.selectedSession;if(!(n===void 0||n.archived===!0))return n}};function _a(e){return e.prompt?.requestId??e.select?.requestId}function va(e){let t=e.trim(),n=/^\/(login|logout)(?:\s+(\S+))?\s*$/u.exec(t);if(n===null)return;let r=n[1];if(r!==`login`&&r!==`logout`)return;let i=n[2];return i===void 0||i===``?{command:r}:{command:r,providerId:i}}function ya(e){return e.replaceAll(`:`,`.`)}function ba(e){let t=new URLSearchParams(window.location.search),n=`${e}--`,r={};for(let[e,i]of t.entries()){if(!e.startsWith(n))continue;let t=e.slice(n.length),a=r[t];a===void 0?r[t]=i:Array.isArray(a)?a.push(i):r[t]=[a,i]}return r}function xa(e,t){let n=ba(e)[t];return Array.isArray(n)?n[0]:n===``?void 0:n}function Sa(e,t,n,r){let i=new URL(window.location.href),a=`${e}--${t}`;if(i.searchParams.delete(a),n!=null&&n!==``)if(Array.isArray(n))for(let e of n)i.searchParams.append(a,String(e));else i.searchParams.set(a,String(n));Ca(i,r)}function Ca(e,t){`${e.pathname}${e.search}${e.hash}`!=`${window.location.pathname}${window.location.search}${window.location.hash}`&&(t?.replace===!0?window.history.replaceState({},``,e):window.history.pushState({},``,e))}function wa(e){let t=e.files.map((t,n)=>{let r=t.size;return{index:n,name:t.name,path:Ui(e.destinationFolder,t.name),size:t.size,loaded:0,total:r,percent:Aa(0,r),lengthComputable:!0,status:n===0?`uploading`:`pending`}}),n=t.reduce((e,t)=>e+t.total,0);return{id:e.id,projectId:e.projectId,workspaceId:e.workspaceId,machineId:e.machineId,destinationFolder:e.destinationFolder,overwrite:e.overwrite,createDirs:e.createDirs,files:t,currentFileIndex:t.length===0?-1:0,loaded:0,total:n,percent:Aa(0,n),status:`uploading`,startedAt:e.startedAt}}function Ta(e,t){let n=new Map(t.files.map(e=>[e.index,e])),r=e.files.map(e=>{let r=n.get(e.index);if(r===void 0)return e;let i={...e,path:r.path,loaded:r.loaded,total:r.total,percent:r.percent,lengthComputable:r.lengthComputable,status:r.error===void 0?r.done?`completed`:t.currentFileIndex===e.index?`uploading`:e.status:`error`};return r.error===void 0?delete i.error:i.error=r.error,i});return{...e,files:r,currentFileIndex:t.currentFileIndex,loaded:t.loaded,total:t.total,percent:t.percent}}function Ea(e,t,n){let r=e.files.map((e,n)=>{let r=t[n];return{...e,...r===void 0?{}:{path:r.path,response:r},loaded:e.total,percent:1,lengthComputable:!0,status:`completed`}}),i=ka(r);return{...e,files:r,currentFileIndex:r.length===0?-1:r.length-1,...i,status:`completed`,completedAt:n}}function Da(e,t,n){let r=e.files.map(n=>n.status===`completed`||n.status===`error`?n:n.status===`uploading`||n.index===e.currentFileIndex?{...n,status:`error`,error:t}:{...n,status:`cancelled`,error:`Not uploaded because an earlier file failed.`});return{...e,files:r,...ka(r),status:`error`,error:t,completedAt:n}}function Oa(e,t){let n=`Upload cancelled`,r=e.files.map(e=>e.status===`completed`||e.status===`error`?e:{...e,status:`cancelled`,error:n});return{...e,files:r,...ka(r),status:`cancelled`,error:n,completedAt:t}}function ka(e){let t=e.reduce((e,t)=>e+t.total,0);return{loaded:t,total:t,percent:e.length===0?0:1}}function Aa(e,t){return t<=0?e<=0?0:1:Math.max(0,Math.min(1,e/t))}var ja=ya(`core:workspace.files`),Ma=class{constructor(e,t,n,r={}){this.getState=e,this.setState=t,this.updateUrl=n,this.uploadTasks=new Map,this.uploadBatchSequence=0,this.api=r.api??F,this.uploadWorkspaceFiles=r.uploadWorkspaceFiles??Gi,this.createUploadBatchId=r.createUploadBatchId??(()=>(this.uploadBatchSequence+=1,`workspace-upload-${String(this.uploadBatchSequence)}`)),this.now=r.now??(()=>new Date().toISOString())}async refreshFiles(){let e=this.getState().selectedProject,t=this.getState().selectedWorkspace;if(!(e===void 0||t===void 0))try{let n=I(this.getState()),r=await this.api.workspaceTree(e.id,t.id,``,n),i={...this.getState().expandedDirs};await Promise.all(Object.keys(i).map(async r=>{i[r]=(await this.api.workspaceTree(e.id,t.id,r,n)).entries})),this.setState({fileTree:r.entries,expandedDirs:i,fileTreeStale:!1,error:``})}catch(e){this.setState({error:String(e)})}}async expandDir(e){let t=this.getState().selectedProject,n=this.getState().selectedWorkspace;if(!(t===void 0||n===void 0)){if(this.getState().expandedDirs[e]!==void 0){this.setState({expandedDirs:Ia(this.getState().expandedDirs,e)});return}try{let r=await this.api.workspaceTree(t.id,n.id,e,I(this.getState()));this.setState({expandedDirs:{...this.getState().expandedDirs,[e]:r.entries},error:``})}catch(e){this.setState({error:String(e)})}}}async selectFile(e){this.setState({selectedFilePath:e,selectedFileContent:void 0,workspaceTool:`core:workspace.files`,mainView:this.getState().mainView===`chat`?`chat`:`core:workspace.files`}),Sa(ja,`file`,e),this.updateUrl({replace:!0}),await this.restoreFile(e)}async restoreFile(e){let t=this.getState().selectedProject,n=this.getState().selectedWorkspace;if(!(t===void 0||n===void 0)){this.setState({selectedFilePath:e,selectedFileContent:void 0});try{let r=await this.api.workspaceFile(t.id,n.id,e,I(this.getState()));this.getState().selectedFilePath===e&&this.setState({selectedFileContent:r,error:``})}catch(t){if(this.getState().selectedFilePath!==e)return;if(Na(t)){this.setState({selectedFilePath:void 0,selectedFileContent:void 0,error:``}),Sa(ja,`file`,void 0,{replace:!0}),this.updateUrl({replace:!0});return}this.setState({error:String(t)})}}}startWorkspaceUpload(e,t){let n=this.getState().selectedProject,r=this.getState().selectedWorkspace;if(n===void 0||r===void 0){this.setState({error:`Select a workspace before uploading files.`});return}if(e.length===0)return;let i=I(this.getState()),a=t.overwrite??!1,o=t.createDirs??!0,s;try{s=wa({id:this.createUploadBatchId(),projectId:n.id,workspaceId:r.id,machineId:i,destinationFolder:t.destinationFolder,overwrite:a,createDirs:o,files:e,startedAt:this.now()})}catch(e){this.setState({error:String(e)});return}this.setUploadBatch(s);let c;try{c=this.uploadWorkspaceFiles(n.id,r.id,e,{destinationFolder:t.destinationFolder,machineId:i,overwrite:a,createDirs:o,onProgress:e=>{this.updateUploadProgress(s.id,e)}})}catch(e){return this.failUploadBatch(s.id,e),{batchId:s.id,done:Promise.resolve()}}this.uploadTasks.set(s.id,c);let l=c.promise.then(async e=>{await this.completeUploadBatch(s.id,e,t)}).catch(async e=>{await this.handleUploadFailure(s.id,e,t)}).finally(()=>{this.uploadTasks.delete(s.id)});return{batchId:s.id,done:l}}cancelWorkspaceUpload(e){let t=this.getUploadBatch(e);t?.status===`uploading`&&(this.setUploadBatch(Oa(t,this.now())),this.uploadTasks.get(e)?.cancel())}clearWorkspaceUpload(e){this.uploadTasks.get(e)?.cancel(),this.uploadTasks.delete(e),this.setState({workspaceUploadBatches:Ia(this.getState().workspaceUploadBatches,e)})}updateUploadProgress(e,t){let n=this.getUploadBatch(e);n?.status===`uploading`&&this.setUploadBatch(Ta(n,t))}async completeUploadBatch(e,t,n){let r=this.getUploadBatch(e);if(r?.status!==`uploading`||(this.setUploadBatch(Ea(r,t,this.now()),{error:``}),!this.isCurrentWorkspaceBatch(r)))return;await this.refreshFiles();let i=t[0]?.path;n.selectUploadedFile!==!1&&i!==void 0&&this.isCurrentWorkspaceBatch(r)&&await this.selectFile(i)}async handleUploadFailure(e,t,n){let r=this.failUploadBatch(e,t);if(!(t instanceof Bi)||t.responses.length===0||r===void 0||!this.isCurrentWorkspaceBatch(r))return;await this.refreshFiles();let i=t.responses[0]?.path;n.selectUploadedFile!==!1&&i!==void 0&&this.isCurrentWorkspaceBatch(r)&&await this.selectFile(i)}failUploadBatch(e,t){let n=this.getUploadBatch(e);if(n?.status!==`uploading`)return;if(Pa(t)){let e=Oa(n,this.now());return this.setUploadBatch(e),e}let r=Fa(t),i=Da(n,r,this.now());return this.setUploadBatch(i,{error:r}),i}getUploadBatch(e){return this.getState().workspaceUploadBatches[e]}setUploadBatch(e,t={}){this.setState({workspaceUploadBatches:{...this.getState().workspaceUploadBatches,[e.id]:e},...t})}isCurrentWorkspaceBatch(e){let t=this.getState();return t.selectedProject?.id===e.projectId&&t.selectedWorkspace?.id===e.workspaceId&&I(t)===e.machineId}};function Na(e){let t=String(e);return t.includes(`Path does not exist`)||t.includes(`ENOENT`)||t.includes(`no such file or directory`)}function Pa(e){return e instanceof zi}function Fa(e){return e instanceof Error?e.message:String(e)}function Ia(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>e!==t))}var La=ya(`core:workspace.git`),Ra=class{constructor(e,t,n){this.getState=e,this.setState=t,this.updateUrl=n}dispose(){this.pollTimer!==void 0&&window.clearInterval(this.pollTimer),this.pollTimer=void 0}async refreshGit(){let e=this.getState().selectedProject,t=this.getState().selectedWorkspace;if(!(e===void 0||t===void 0))try{let n=await F.gitStatus(e.id,t.id,I(this.getState()));this.setState({gitStatus:n,gitStale:!1,error:``});let r=this.getState().selectedDiffPath;r!==void 0&&(n.files.some(e=>e.path===r)?await this.refreshDiff(r):(this.setState({selectedDiffPath:void 0,selectedDiff:void 0,selectedStagedDiff:void 0}),Sa(La,`diff`,void 0,{replace:!0})))}catch(e){this.setState({error:String(e)})}}async selectDiff(e){this.setState({selectedDiffPath:e,selectedDiff:void 0,selectedStagedDiff:void 0,workspaceTool:`core:workspace.git`,mainView:this.getState().mainView===`chat`?`chat`:`core:workspace.git`}),Sa(La,`diff`,e),this.updateUrl({replace:!0}),await this.refreshDiff(e)}async restoreDiff(e){this.setState({selectedDiffPath:e,selectedDiff:void 0,selectedStagedDiff:void 0}),await this.refreshDiff(e)}async refreshDiff(e){let t=this.getState().selectedProject,n=this.getState().selectedWorkspace;if(!(t===void 0||n===void 0))try{let[r,i]=await Promise.all([F.gitDiff(t.id,n.id,{path:e},I(this.getState())),F.gitDiff(t.id,n.id,{path:e,staged:!0},I(this.getState()))]);this.setState({selectedDiff:r,selectedStagedDiff:i,error:``})}catch(e){this.setState({error:String(e)})}}updatePolling(){this.dispose();let e=this.getState();(e.workspaceTool===`core:workspace.git`||e.mainView===`core:workspace.git`)&&(this.pollTimer=window.setInterval(()=>{this.refreshGit()},8e3))}},za=class{constructor(e,t,n,r){this.getState=e,this.setState=t,this.updateUrl=n,this.projects=r}async loadMachines(e){this.setState({error:``,isLoadingMachines:!0});try{let t=await F.machines(),n=await this.selectInitialMachine(t,e),r=new Set(t.map(e=>e.id));this.setState({machines:t,selectedMachine:n,machineActivities:Va(this.getState().machineActivities,r),machineRuntimes:Va(this.getState().machineRuntimes,r)}),this.refreshMachineHealthFor(t),this.refreshMachineRuntimeFor(t)}catch(e){this.setState({error:String(e)})}finally{this.setState({isLoadingMachines:!1})}}async selectMachine(e,t={}){this.getState().selectedMachine?.id!==e.id&&(this.setState({selectedMachine:e,projects:[],workspaces:[],isLoadingWorkspaces:!1,selectedProject:void 0,selectedWorkspace:void 0,selectedSession:void 0,messages:[],messagePageStart:0,messagePageTotal:0,status:void 0,activity:void 0,sessionStatuses:{},sessionActivities:{},sendingPrompts:{},workspaceActivities:{},workspacesByProjectId:{},workspaceDeletionRuns:{},activeTerminalCount:0,...oa()}),t.updateUrl!==!1&&this.updateUrl(),await this.projects.loadProjects(),this.refreshMachineHealth(e.id),this.refreshMachineRuntime(e.id))}async addMachine(e){this.setState({error:``});try{let t=await F.addMachine(e);return this.setState({machines:[...this.getState().machines.filter(e=>e.id!==t.id),t]}),await this.selectMachine(t),t}catch(e){this.setState({error:String(e)});return}}async deleteMachine(e=this.getState().selectedMachine,t={}){if(e!==void 0){if(e.kind===`local`){this.setState({error:`The local machine cannot be removed.`});return}try{let n=this.getState().selectedMachine?.id===e.id;await F.deleteMachine(e.id);let r=this.getState().machines.filter(t=>t.id!==e.id),i=r.find(e=>e.id===`local`)??r[0];return this.setState({machines:r,machineStatuses:Ba(this.getState().machineStatuses,e.id),machineRuntimes:Ba(this.getState().machineRuntimes,e.id),machineActivities:Ba(this.getState().machineActivities,e.id)}),n&&i!==void 0?(t.selectFallback===!1||await this.selectMachine(i),i):void 0}catch(e){this.setState({error:String(e)});return}}}async refreshMachineHealth(e=this.getState().selectedMachine?.id??`local`){try{let t=await F.health(e);return this.setState({machineStatuses:{...this.getState().machineStatuses,[t.machineId]:t}}),t}catch(e){this.setState({error:String(e)});return}}async refreshMachineRuntime(e=this.getState().selectedMachine?.id??`local`){try{let t=await F.runtime(e,!0);this.setState({machineRuntimes:{...this.getState().machineRuntimes,[t.machineId]:t}})}catch(e){this.setState({error:String(e)})}}async selectInitialMachine(e,t){let n=e.find(e=>e.id===(t??`local`));if(n===void 0)return this.localMachine(e);if(n.kind!==`remote`)return n;let r=await this.safeRemoteHealth(n);return this.setState({machineStatuses:{...this.getState().machineStatuses,[r.machineId]:r},...r.ok?{}:{error:`${n.name} is unavailable; reconnecting…`}}),n}async safeRemoteHealth(e){try{return await F.health(e.id)}catch(t){return{machineId:e.id,ok:!1,checkedAt:new Date().toISOString(),status:`offline`,error:t instanceof Error?t.message:String(t)}}}localMachine(e){return e.find(e=>e.id===`local`)??e[0]}async refreshMachineHealthFor(e){let t=await Promise.allSettled(e.map(e=>F.health(e.id))),n=Object.fromEntries(t.flatMap(e=>e.status===`fulfilled`?[[e.value.machineId,e.value]]:[]));Object.keys(n).length>0&&this.setState({machineStatuses:{...this.getState().machineStatuses,...n}})}async refreshMachineRuntimeFor(e){let t=await Promise.allSettled(e.map(e=>F.runtime(e.id))),n=Object.fromEntries(t.flatMap(e=>e.status===`fulfilled`?[[e.value.machineId,e.value]]:[]));Object.keys(n).length>0&&this.setState({machineRuntimes:{...this.getState().machineRuntimes,...n}})}};function Ba(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>e!==t))}function Va(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>t.has(e)))}var Ha=class{constructor(e,t,n){this.getState=e,this.setState=t,this.workspaces=n}async loadProjects(){let e=I(this.getState());this.setState({error:``,isLoadingProjects:!0});try{let t=await F.projects(e);if(I(this.getState())!==e)return;let n=new Set(t.map(e=>e.id)),r=Object.fromEntries(Object.entries(this.getState().workspacesByProjectId).filter(([e])=>n.has(e)));this.setState({projects:t,workspacesByProjectId:r})}catch(t){I(this.getState())===e&&this.setState({error:String(t)})}finally{I(this.getState())===e&&this.setState({isLoadingProjects:!1})}}async addProject(e,t){if(e.trim()!==``)try{let n=await F.addProject(e.trim(),void 0,t,I(this.getState())),r=this.getState().projects;this.setState({projects:[...r.filter(e=>e.id!==n.id),n],projectDialogOpen:!1}),await this.workspaces.selectProject(n)}catch(e){this.setState({error:String(e)})}}async closeProject(e){try{await F.closeProject(e,I(this.getState())),this.workspaces.forgetProject(e);let t=this.getState();this.setState({projects:t.projects.filter(t=>t.id!==e)}),t.selectedProject?.id===e&&this.workspaces.clearSelection()}catch(e){this.setState({error:String(e)})}}},Ua=class{constructor(e,t,n={}){this.getState=e,this.setState=t,this.requestSequence=0,this.api=n.api??hi,this.onRefreshError=n.onRefreshError??(()=>void 0)}async refresh(){let e=I(this.getState());if(this.pendingUpdateCheck?.machineId===e)return;let t=++this.requestSequence;try{let n=await this.api.piWebStatus(e);this.isCurrent(e,t)&&this.setState({piWebStatus:n})}catch(n){if(!this.isCurrent(e,t))return;this.setState({piWebStatus:void 0}),this.onRefreshError(e,n)}}checkForUpdates(){let e=I(this.getState()),t=this.pendingUpdateCheck;if(t?.machineId===e)return t.promise;let n=++this.requestSequence,r=this.api.checkForUpdates(e).then(t=>{this.isCurrent(e,n)&&(this.setState({piWebStatus:t}),Wa(t))}).catch(t=>{if(this.isCurrent(e,n))throw t}).finally(()=>{this.pendingUpdateCheck?.requestSequence===n&&(this.pendingUpdateCheck=void 0)});return this.pendingUpdateCheck={machineId:e,requestSequence:n,promise:r},r}isCurrent(e,t){return I(this.getState())===e&&t===this.requestSequence}};function Wa(e){if(e.release.error!==void 0)throw Error(`PI WEB update check failed: ${e.release.error}`);if(e.release.skipped===!0)throw Error(`PI WEB update check was skipped because remote version checks are disabled by offline/version-check settings`)}var Ga=`pi-web:cached-new-sessions:v1`,Ka=`browserCachedNew`,qa=`local`;function Ja(){try{return typeof localStorage>`u`?void 0:localStorage}catch{return}}function Ya(e,t=qa,n=Ja()){if(e.messageCount!==0||e.archived===!0)return;let r=to(n).filter(n=>n.id!==e.id||n.machineId!==t);no([Xa(e,t),...r],n)}function Xa(e,t=qa){return{...e,browserCachedNew:!0,machineId:t}}function Za(e,t=qa,n=Ja()){no(to(n).filter(n=>n.id!==e||n.machineId!==t),n)}function Qa(e,t,n=qa,r=Ja()){let i=new Set(t.map(e=>e.id)),a=to(r),o=a.filter(e=>e.machineId!==n||!i.has(e.id));return o.length!==a.length&&no(o,r),[...o.filter(t=>t.machineId===n&&t.cwd===e),...t]}function $a(e){return e!==void 0&&io(e)&&e.browserCachedNew===!0}function eo(e){return{id:e.id,path:e.path,cwd:e.cwd,...e.persisted===void 0?{}:{persisted:e.persisted},...e.name===void 0?{}:{name:e.name},created:e.created,modified:e.modified,messageCount:e.messageCount,firstMessage:e.firstMessage,...e.parentSessionPath===void 0?{}:{parentSessionPath:e.parentSessionPath},...`machineId`in e&&typeof e.machineId==`string`?{machineId:e.machineId}:{machineId:qa},...e.archived===!0?{archived:!0}:{},...e.archivedAt===void 0?{}:{archivedAt:e.archivedAt}}}function to(e=Ja()){try{let t=e?.getItem(Ga);if(t==null||t===``)return[];let n=JSON.parse(t);return Array.isArray(n)?n.flatMap(e=>ro(e)):[]}catch{return[]}}function no(e,t=Ja()){try{e.length===0?t?.removeItem(Ga):t?.setItem(Ga,JSON.stringify(e))}catch{}}function ro(e){if(!ao(e))return[];let t=oo(e,`id`),n=oo(e,`path`),r=oo(e,`cwd`),i=oo(e,`created`),a=oo(e,`modified`),o=oo(e,`firstMessage`),s=co(e,`messageCount`);if(t===void 0||n===void 0||r===void 0||i===void 0||a===void 0||o===void 0||s!==0)return[];let c=so(e,`name`),l=so(e,`parentSessionPath`),u=so(e,`machineId`)??qa;return[{id:t,path:n,cwd:r,...c===void 0?{}:{name:c},created:i,modified:a,messageCount:s,firstMessage:o,...l===void 0?{}:{parentSessionPath:l},machineId:u,browserCachedNew:!0}]}function io(e){return Ka in e}function ao(e){return typeof e==`object`&&!!e}function oo(e,t){let n=e[t];return typeof n==`string`?n:void 0}function so(e,t){let n=e[t];return n===void 0||typeof n!=`string`?void 0:n}function co(e,t){let n=e[t];return typeof n==`number`?n:void 0}function lo(e){return ko(e.flatMap(ho)).filter(e=>e.parts.length>0)}function uo(e,t){return{role:e,parts:[{type:`text`,text:t}]}}function fo(e,t){let n=xo(t);return n===void 0?e:{...e,meta:n}}function po(e,t,n){if(n===``)return e;let r=e.at(-1),i=r?.parts.at(-1);return r?.role===t&&i?.type===`text`?[...e.slice(0,-1),{...r,parts:[...r.parts.slice(0,-1),{...i,text:i.text+n}]}]:r?.role===t?[...e.slice(0,-1),{...r,parts:[...r.parts,{type:`text`,text:n}]}]:[...e,uo(t,n)]}function mo(e,t){if(t===``)return e;let n=e.at(-1),r=n?.parts.at(-1);return n?.role===`assistant`&&r?.type===`thinking`?[...e.slice(0,-1),{...n,parts:[...n.parts.slice(0,-1),{...r,text:r.text+t}]}]:n?.role===`assistant`?[...e.slice(0,-1),{...n,parts:[...n.parts,{type:`thinking`,text:t}]}]:[...e,{role:`assistant`,parts:[{type:`thinking`,text:t}]}]}function ho(e){if(_o(e))return[e];if(L(e,`role`)===`bashExecution`)return[fo(wo(e),e)];let t=To(L(e,`role`)),n=Eo(Lo(e,`content`),e),r=t===`user`?vo(n):void 0;if(r!==void 0)return r.map(t=>fo(t,e));let i=bo(e);if(t===`tool`)return[fo({role:t,parts:n,...i===void 0?{}:{source:i}},e)];let a=n.filter(e=>e.type!==`empty`),o=t===`assistant`&&a.length>0&&a.every(e=>e.type===`skillRead`)?`skill`:t,s=a.length>0?[fo({role:o,parts:a,...i===void 0?{}:{source:i}},e)]:[],c=go(e);return c===void 0?s:[...s,fo(c,e)]}function go(e){if(L(e,`role`)!==`assistant`||L(e,`stopReason`)!==`error`)return;let t=L(e,`errorMessage`)?.trim();return uo(`system`,`Model response failed: ${t===void 0||t===``?`The model returned an error.`:t}`)}function _o(e){let t=L(e,`role`);return(t===`user`||t===`assistant`||t===`tool`||t===`system`||t===`bash`||t===`skill`)&&Array.isArray(Lo(e,`parts`))}function vo(e){if(e.length!==1||e[0]?.type!==`text`)return;let t=yo(e[0].text);if(t!==void 0)return[{role:`user`,parts:[{type:`skillInvocation`,name:t.name,location:t.location,content:t.content}]},...t.userMessage===void 0?[]:[{role:`user`,parts:[{type:`text`,text:t.userMessage}]}]]}function yo(e){let t=/^<skill name="([^"]+)" location="([^"]+)">\n([\s\S]*?)\n<\/skill>(?:\n\n([\s\S]+))?$/.exec(e);if(t===null)return;let n=t[4]?.trim();return{name:t[1]??`skill`,location:t[2]??``,content:t[3]??``,...n===void 0||n===``?{}:{userMessage:n}}}function bo(e){let t=L(e,`source`);if(t===`compaction`||t===`branch_summary`)return t}function xo(e){let t=So(Lo(e,`timestamp`)),n=Co(e);if(!(t===void 0&&n===void 0))return{...t===void 0?{}:{timestamp:t},...n===void 0?{}:{model:n}}}function So(e){if(typeof e==`number`&&Number.isFinite(e))return new Date(e).toISOString();if(typeof e!=`string`||e===``)return;let t=Date.parse(e);return Number.isFinite(t)?new Date(t).toISOString():void 0}function Co(e){if(L(e,`role`)!==`assistant`)return;let t=L(e,`provider`),n=L(e,`model`),r=L(e,`responseModel`);if(!((t===void 0||t===``)&&(n===void 0||n===``)&&(r===void 0||r===``)))return{...t===void 0||t===``?{}:{provider:t},...n===void 0||n===``?{}:{id:n},...r===void 0||r===``?{}:{responseId:r}}}function wo(e){let t=L(e,`command`)??``,n=Ro(e,`excludeFromContext`)===!0?[`excluded from context`,``,`$ ${t}`]:[`$ ${t}`],r=Lo(e,`output`);r!=null&&n.push(``,Bo(r));let i=Lo(e,`exitCode`);i!=null&&n.push(``,`exit ${Bo(i)}`),Ro(e,`cancelled`)===!0&&n.push(``,`cancelled`),Ro(e,`truncated`)===!0&&n.push(``,`output truncated`);let a=L(e,`fullOutputPath`);return a!==void 0&&a!==``&&n.push(``,`full output: ${a}`),{role:`bash`,parts:[{type:`text`,text:n.join(`
4
- `)}]}}function To(e){return e===`assistant`?`assistant`:e===`user`?`user`:e===`toolResult`?`tool`:`system`}function Eo(e,t){return typeof e==`string`?e===``?[]:[{type:`text`,text:e}]:Array.isArray(e)?e.flatMap(e=>{let t=L(e,`type`),n=L(e,`text`);if(t===`text`)return n!==void 0&&n!==``?[{type:`text`,text:n}]:[];if(t===`thinking`){let t=L(e,`thinking`)??n;return t!==void 0&&t!==``?[{type:`thinking`,text:t}]:[]}if(t===`toolCall`){let t=L(e,`name`)??`tool`,n=Lo(e,`arguments`),r=L(e,`id`),i=t===`read`?Oo(L(n,`path`)):void 0;return i===void 0?[{type:`toolCall`,...r===void 0?{}:{toolCallId:r},toolName:t,summary:Po(n),...n===void 0?{}:{args:n}}]:[{type:`skillRead`,...i,...r===void 0?{}:{toolCallId:r}}]}if(t===`image`){let t=L(e,`data`),n=L(e,`mimeType`);return t!==void 0&&t!==``&&n!==void 0&&n!==``?[{type:`image`,mimeType:n,data:t}]:[{type:`text`,text:`[image]`}]}return No(e)}).map(e=>e.type===`text`&&L(t,`role`)===`toolResult`?Do(e.text,t):e):No(e)}function Do(e,t){let n=L(t,`toolCallId`),r=Lo(t,`content`),i=Lo(t,`details`);return{type:`toolResult`,...n===void 0?{}:{toolCallId:n},toolName:L(t,`toolName`)??`tool`,text:e,...r===void 0?{}:{content:r},...i===void 0?{}:{details:i},isError:Ro(t,`isError`)===!0}}function Oo(e){if(e===void 0||e===``)return;let t=e.replace(/\\/g,`/`);if(!t.endsWith(`/SKILL.md`)&&t!==`SKILL.md`)return;let n=t.split(`/`).at(-2);if(!(n===void 0||n===``))return{name:n,path:e}}function ko(e){let t=[],n=new Map;for(let r of e){let e=[],i={...r.source===void 0?{}:{source:r.source},...r.meta===void 0?{}:{meta:r.meta}},a=()=>{e.length!==0&&(t.push({role:r.role,parts:e,...i}),e=[])};for(let o of r.parts){if(o.type===`toolCall`){a();let e=Ao(o),r=t.length;t.push({role:`tool`,parts:[e],...i}),e.toolCallId!==void 0&&n.set(e.toolCallId,{lineIndex:r,partIndex:0});continue}if(o.type===`toolResult`){let e=o.toolCallId===void 0?void 0:n.get(o.toolCallId);if(e!==void 0&&jo(t,e,o)){n.delete(o.toolCallId??``);continue}}e.push(o)}a()}return t}function Ao(e){return{type:`toolExecution`,...e.toolCallId===void 0?{}:{toolCallId:e.toolCallId},toolName:e.toolName,summary:e.summary,...e.args===void 0?{}:{args:e.args},status:`pending`}}function jo(e,t,n){let r=e[t.lineIndex],i=r?.parts[t.partIndex];if(r===void 0||i?.type!==`toolExecution`)return!1;let a=Mo(n.details)??i.preview,o={...i,status:n.isError?`error`:`success`,resultText:n.text,...n.content===void 0?{}:{content:n.content},...n.details===void 0?{}:{details:n.details},...a===void 0?{}:{preview:a}};return e[t.lineIndex]={...r,parts:[...r.parts.slice(0,t.partIndex),o,...r.parts.slice(t.partIndex+1)]},!0}function Mo(e){let t=Lo(e,`preview`);if(!Io(t))return;let n=L(t,`diff`),r=L(t,`error`),i=zo(t,`firstChangedLine`);if(!(n===void 0&&r===void 0&&i===void 0))return{...n===void 0?{}:{diff:n},...r===void 0?{}:{error:r},...i===void 0?{}:{firstChangedLine:i}}}function No(e){return e==null?[]:typeof e==`object`?[{type:`text`,text:Po(e)}]:[{type:`text`,text:Bo(e)}]}function Po(e){if(!Io(e))return Bo(e);let t=L(e,`command`);if(t!==void 0)return t;let n=L(e,`path`);if(n!==void 0)return n;if(typeof e.oldText==`string`&&typeof e.newText==`string`)return`edit text replacement`;let r=e.edits;return Array.isArray(r)?`${String(r.length)} edit${r.length===1?``:`s`}`:Object.entries(e).filter(([,e])=>e!=null).slice(0,3).map(([e,t])=>`${e}: ${Fo(t)}`).join(` · `)}function Fo(e){return typeof e==`string`?e.length>80?`${e.slice(0,77)}…`:e:typeof e==`number`||typeof e==`boolean`?String(e):Array.isArray(e)?`${String(e.length)} item${e.length===1?``:`s`}`:typeof e==`object`&&e?`object`:``}function Io(e){return typeof e==`object`&&!!e}function Lo(e,t){return Io(e)?e[t]:void 0}function L(e,t){let n=Lo(e,t);return typeof n==`string`?n:void 0}function Ro(e,t){let n=Lo(e,t);return typeof n==`boolean`?n:void 0}function zo(e,t){let n=Lo(e,t);return typeof n==`number`&&Number.isFinite(n)?n:void 0}function Bo(e){return e==null?``:typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`?String(e):``}var Vo=`pi-web:prompt-draft:`;function Ho(e){return`${Vo}${e}`}function Uo(){try{return typeof localStorage>`u`?void 0:localStorage}catch{return}}function Wo(e,t=Uo()){try{return t?.getItem(Ho(e))??``}catch{return``}}function Go(e,t,n=Uo()){try{t?n?.setItem(Ho(e),t):n?.removeItem(Ho(e))}catch{}}function Ko(e,t=Uo()){try{t?.removeItem(Ho(e))}catch{}}function qo(e,t,n=Uo()){let r=Wo(e,n);r!==``&&(Go(t,r,n),Ko(e,n))}function Jo(e,t){return uo(`bash`,`${t===!0?`excluded from context
5
-
6
- `:``}$ ${e}`)}function Yo(e,t){let n=e.at(-1),r=n?.parts.at(-1);if(n?.role!==`bash`||r?.type!==`text`)return[...e,uo(`bash`,t)];let i=Zo(r.text)?``:`
7
-
8
- `;return[...e.slice(0,-1),{...n,parts:[...n.parts.slice(0,-1),{...r,text:r.text+i+t}]}]}function Xo(e,t){let n=e.at(-1),r=n?.parts.at(-1);if(n?.role!==`bash`||r?.type!==`text`)return e;let i=[];return!r.text.includes(`
9
-
10
- `)&&(t.output===void 0||t.output===``)&&i.push(`(no output)`),t.isError===!0&&i.push(t.output??`Bash command failed`),t.exitCode!=null&&i.push(`exit ${String(t.exitCode)}`),t.cancelled===!0&&i.push(`cancelled`),t.truncated===!0&&i.push(`output truncated`),t.fullOutputPath!==void 0&&t.fullOutputPath!==``&&i.push(`full output: ${t.fullOutputPath}`),i.length===0?e:[...e.slice(0,-1),{...n,parts:[...n.parts.slice(0,-1),{...r,text:`${r.text}\n\n${i.join(`
11
- `)}`}]}]}function Zo(e){return e.lastIndexOf(`
12
-
13
- `)>e.lastIndexOf(`$ `)}function Qo(e,t){if(t==null)return e;let n=lo([t]);return n.length===0?e:[...e,...n]}function $o(e,t){if(t.type===`message.append`)return Ss(e,t.message);if(t.type===`assistant.delta`)return po(e,`assistant`,t.text);if(t.type===`assistant.thinking.delta`)return mo(e,t.text);if(t.type===`tool.start`)return is(e,t);if(t.type===`tool.update`)return ss(e,t.toolCallId,e=>as(e,t));if(t.type===`tool.end`)return os(e,{toolCallId:t.toolCallId,toolName:t.toolName,text:t.text,isError:t.isError,content:t.content,details:t.details,presentation:ls({role:`toolResult`,content:t.content})});if(t.type===`shell.start`)return[...e,Jo(t.command,t.excludeFromContext)];if(t.type===`shell.chunk`)return Yo(e,t.chunk);if(t.type===`shell.end`)return Xo(e,t);if(t.type===`command.output`)return[...e,uo(t.level===`error`?`system`:`tool`,t.message)];if(t.type===`session.error`)return[...e,uo(`system`,t.message)];if(t.type===`message.end`)return t.message===void 0?void 0:es(e,t.message)}function es(e,t){let n=us(t);if(n!==void 0)return os(e,n);let r=ho(t);if(r.length===0)return;let i=r.map(e=>e.role===`assistant`?ns(e):e).filter(e=>e.parts.length>0);return i.length===0?e:i.reduce((e,t)=>ts(e,t),e)}function ts(e,t){let n=fs(e,t);if(n.length>0)return ps(e,n,t);let r=e.at(-1);return r?.role===t.role&&(t.role===`assistant`||bs(r,t))?[...e.slice(0,-1),t]:[...e,t]}function ns(e){return{...e,parts:e.parts.filter(e=>e.type!==`toolCall`)}}function rs(e){if(e===void 0||e===``)return;let t=e.replace(/\\/g,`/`);if(!t.endsWith(`/SKILL.md`)&&t!==`SKILL.md`)return;let n=t.split(`/`).at(-2);if(!(n===void 0||n===``))return{name:n,path:e}}function is(e,t){let n=t.toolName===`read`?rs(ks(t.args,`path`)):void 0;if(n!==void 0)return Cs(e,{role:`skill`,parts:[{type:`skillRead`,...n,...t.toolCallId===``?{}:{toolCallId:t.toolCallId}}]});let r={type:`toolExecution`,...t.toolCallId===``?{}:{toolCallId:t.toolCallId},toolName:t.toolName,summary:t.summary||Po(t.args),...t.args===void 0?{}:{args:t.args},status:`running`};return[...e,{role:`tool`,parts:[r]}]}function as(e,t){let n=Mo(t.details)??e.preview;return{...e,status:e.status===`pending`?`running`:e.status,...t.text===``?{}:{resultText:t.text},...t.content===void 0?{}:{content:t.content},...t.details===void 0?{}:{details:t.details},...n===void 0?{}:{preview:n}}}function os(e,t){let{toolCallId:n,toolName:r,text:i,isError:a,content:o,details:s,presentation:c}=t,l=ss(e,n,e=>{let t=Mo(s)??e.preview;return{...e,status:a?`error`:`success`,resultText:i,...o===void 0?{}:{content:o},...s===void 0?{}:{details:s},...t===void 0?{}:{preview:t}}},e=>cs(e,c));if(l!==e)return l;let u=Mo(s),d={type:`toolExecution`,...n===void 0||n===``?{}:{toolCallId:n},toolName:r,summary:Po(o),status:a?`error`:`success`,resultText:i,...o===void 0?{}:{content:o},...s===void 0?{}:{details:s},...u===void 0?{}:{preview:u}};return[...e,cs({role:`tool`,parts:[d]},c)]}function ss(e,t,n,r=e=>e){if(t===void 0||t===``)return e;for(let i=e.length-1;i>=0;i--){let a=e[i];if(a===void 0)continue;let o=a.parts.findIndex(e=>e.type===`toolExecution`&&e.toolCallId===t);if(o<0)continue;let s=a.parts[o];if(s?.type!==`toolExecution`)continue;let c=r({...a,parts:[...a.parts.slice(0,o),n(s),...a.parts.slice(o+1)]});return[...e.slice(0,i),c,...e.slice(i+1)]}return e}function cs(e,t){let n={...e,parts:[...e.parts.filter(e=>e.type!==`image`),...t.images]};return t.meta===void 0?n:{...n,meta:t.meta}}function ls(e){let t=ho(e),n=t.flatMap(e=>e.parts.filter(e=>e.type===`image`)),r=t.find(e=>e.meta!==void 0)?.meta;return{images:n,...r===void 0?{}:{meta:r}}}function us(e){if(ks(e,`role`)!==`toolResult`)return;let t=ks(e,`toolCallId`),n=Os(e,`content`);return{...t===void 0?{}:{toolCallId:t},toolName:ks(e,`toolName`)??`tool`,text:ds(n),isError:As(e,`isError`)===!0,content:n,details:Os(e,`details`),presentation:ls(e)}}function ds(e){if(typeof e==`string`)return e;if(Array.isArray(e))return e.map(ds).filter(e=>e!==``).join(`
14
- `);if(typeof e==`object`&&e){let t=ks(e,`text`)??ks(e,`content`)??ks(e,`output`);if(t!==void 0)return t}return``}function fs(e,t){let n=gs(t);if(n.length===0)return[];let r=[],i=n.length,a=Es(e)+1;for(let t=e.length-1;t>=a;t--){let a=gs(e[t]);if(a.length===0)continue;let o=i-a.length;if(!(o<0)&&_s(a,n.slice(o,i))&&(r.unshift(t),i=o,i===0))return r}return[]}function ps(e,t,n){let r=ms(e,t,n),i=r[0];if(i===void 0)return e;let a=new Set(r),o=[];for(let t=0;t<e.length;t++){t===i&&o.push(n);let r=e[t];r!==void 0&&!a.has(t)&&o.push(r)}return o}function ms(e,t,n){let r=t[0];if(n.role!==`assistant`||r===void 0)return t;let i=r-1;return hs(e[i])?[i,...t]:t}function hs(e){return e?.role===`assistant`&&e.parts.length>0&&e.parts.every(e=>e.type===`text`||e.type===`thinking`)}function gs(e){return e===void 0?[]:e.parts.filter(e=>e.type===`skillRead`)}function _s(e,t){return e.length===t.length&&e.every((e,n)=>vs(e,t[n]))}function vs(e,t){return t===void 0?!1:e.toolCallId!==void 0&&t.toolCallId!==void 0?e.toolCallId===t.toolCallId:ys(e.path)===ys(t.path)||e.name===t.name}function ys(e){return e.replace(/\\/g,`/`)}function bs(e,t){return xs(e)===xs(t)}function xs(e){return e.parts.filter(e=>e.type===`text`).map(e=>e.text).join(`
15
-
16
- `)}function Ss(e,t){let n=ho(t);return n.length===0?e:[...e,...n]}function Cs(e,t){let n=e.at(-1);return ws(e,t)?e:n?.role===t.role&&t.role!==`skill`?[...e.slice(0,-1),{...n,parts:[...n.parts,...t.parts]}]:[...e,t]}function ws(e,t){let n=gs(t);if(t.role!==`skill`||n.length===0)return!1;let r=Es(e)+1;return n.every(t=>Ts(e,t,r))}function Ts(e,t,n){for(let r=e.length-1;r>=n;r--)if(gs(e[r]).some(e=>vs(e,t)))return!0;return!1}function Es(e){for(let t=e.length-1;t>=0;t--)if(e[t]?.role===`user`)return t;return-1}function Ds(e){return typeof e==`object`&&!!e}function Os(e,t){return Ds(e)?e[t]:void 0}function ks(e,t){let n=Os(e,t);return typeof n==`string`?n:void 0}function As(e,t){let n=Os(e,t);return typeof n==`boolean`?n:void 0}var js=`pi-web:chat-history:v2:`,Ms=1800*1e3;function Ns(e){try{let t=sessionStorage.getItem(Bs(e));if(t===null||t===``)return;let n=JSON.parse(t);if(!Vs(n))return;if(Date.now()-n.savedAt>Ms){sessionStorage.removeItem(Bs(e));return}return{messages:n.messages,start:n.start,total:n.total}}catch{return}}function Ps(e,t){try{sessionStorage.setItem(Bs(e),JSON.stringify({...t,savedAt:Date.now()}))}catch{}}function Fs(e){try{sessionStorage.removeItem(Bs(e))}catch{}}function Is(e,t){if(e===void 0||!Hs(e))return t;if(!Hs(t))return e;if(Ls(e,t))return t;let n=Math.min(e.start,t.start),r=Math.max(e.start+e.messages.length,t.start+t.messages.length),i=Array(r-n);return zs(i,n,e),zs(i,n,t),Rs(i)?t:{start:n,total:Math.max(e.total,t.total),messages:i}}function Ls(e,t){return e.total>t.total&&e.start===0&&t.start===0&&t.messages.length===t.total}function Rs(e){for(let t=0;t<e.length;t+=1)if(!(t in e)||e[t]===void 0)return!0;return!1}function zs(e,t,n){n.messages.forEach((r,i)=>{e[n.start-t+i]=r})}function Bs(e){return`${js}${e}`}function Vs(e){if(typeof e!=`object`||!e||!(`messages`in e)||!(`start`in e)||!(`total`in e)||!(`savedAt`in e))return!1;let{messages:t,start:n,total:r,savedAt:i}=e;return Array.isArray(t)&&typeof n==`number`&&typeof r==`number`&&typeof i==`number`&&Hs({messages:t,start:n,total:r})}function Hs(e){return Number.isInteger(e.start)&&Number.isInteger(e.total)&&e.start>=0&&e.total>=e.start&&e.messages.length<=e.total-e.start&&!e.messages.some(Us)}function Us(e){return typeof e==`object`&&!!e&&`role`in e&&`parts`in e&&!(`content`in e)&&typeof e.role==`string`&&Array.isArray(e.parts)}var Ws={read:Ns,write:Ps,remove:Fs},Gs=class{constructor(e=Ws){this.cache=e,this.rawHistoryPages=new Map}cachedView(e){return Ks(this.rawHistoryPage(e))}mergeHistory(e,t){let n=Is(this.rawHistoryPage(e),t);return this.rawHistoryPages.set(e,n),this.cache.write(e,n),Ks(n)}applyLiveEvent(e,t){return $o(e,t)}seedStreamingPartial(e,t){return Qo(e,t)}discard(e){this.rawHistoryPages.delete(e),this.cache.remove?.(e)}rawHistoryPage(e){let t=this.rawHistoryPages.get(e)??this.cache.read(e);return t!==void 0&&this.rawHistoryPages.set(e,t),t}};function Ks(e){let t=e?.start??0;return{messages:lo(e?.messages??[]),messagePageStart:t,messagePageEnd:t+(e?.messages.length??0),messagePageTotal:e?.total??0}}function qs(e,t=e.length){let n=e.slice(0,t),r=Ys(n,t);if(r!==void 0)return r;let i=Xs(n,t);if(i!==void 0)return i;let a=Math.max(n.lastIndexOf(` `),n.lastIndexOf(`
17
- `))+1,o=n.slice(a);if(n.slice(0,a).endsWith(`@ `))return{kind:`file`,query:o,from:a-2,to:t,fileScope:`all`,allPrefix:`@ `};if(o.startsWith(`/`)&&a===0)return{kind:`command`,query:o.slice(1),from:a,to:t};if(o.startsWith(`!@`))return{kind:`file`,query:o.slice(2),from:a,to:t,fileScope:`all`,allPrefix:`!@`};if(o.startsWith(`@`))return{kind:`file`,query:o.slice(1),from:a,to:t,fileScope:`tracked`}}function Js(e,t,n){let r=n??`@`;return!t&&!e.includes(` `)?`${r}${e}`:`${r}"${e}"`}function Ys(e,t){let n=e.lastIndexOf(`"`);if(n===-1)return;let r=e.slice(0,n);if(r.endsWith(`!@`))return{kind:`file`,query:e.slice(n+1),from:r.length-2,to:t,fileScope:`all`,allPrefix:`!@`,quoted:!0};if(r.endsWith(`@`))return{kind:`file`,query:e.slice(n+1),from:r.length-1,to:t,fileScope:`tracked`,quoted:!0};if(r.endsWith(`@ `))return{kind:`file`,query:e.slice(n+1),from:r.length-2,to:t,fileScope:`all`,allPrefix:`@ `,quoted:!0}}function Xs(e,t){let n=e.lastIndexOf(`
18
- `)+1,r=e.slice(n),i=Zs(r,`@ `),a=Zs(r,`!@`),o=Math.max(i,a);if(o===-1)return;let s=o===a?`!@`:`@ `,c=n+o,l=c+s.length;return{kind:`file`,query:e.slice(l),from:c,to:t,fileScope:`all`,allPrefix:s}}function Zs(e,t){for(let n=e.lastIndexOf(t);n>=0;n=e.lastIndexOf(t,n-1))if(n===0||Qs(e[n-1]))return n;return-1}function Qs(e){return e===` `||e===` `}function $s(e){let t=e.trimStart();return t.startsWith(`!@`)?{kind:`file`}:t.startsWith(`!`)?{kind:`shell`,excludeFromContext:t.startsWith(`!!`)}:nc(e).startsWith(`/`)?{kind:`command`}:qs(e)?.kind===`file`?{kind:`file`}:{kind:`normal`}}function ec(e){return $s(e).kind===`shell`}function tc(e,t){return e.kind===t.kind?e.kind===`shell`&&t.kind===`shell`?e.excludeFromContext===t.excludeFromContext:!0:!1}function nc(e){let t=Math.max(e.lastIndexOf(` `),e.lastIndexOf(`
19
- `))+1;return e.slice(t)}var rc=class{constructor(){this.reconnectDelay=500,this.shouldReconnect=!1,this.hasOpened=!1,this.machineId=`local`}connect(e,t,n,r=`local`){this.close(),this.machineId=r,this.session=e,this.onEvent=t,this.onReconnect=n,this.shouldReconnect=!0,this.open()}setHandler(e){this.onEvent=e}close(){this.shouldReconnect=!1,window.clearTimeout(this.reconnectTimer),uc(this.socket),this.socket=void 0,this.session=void 0,this.onEvent=void 0,this.onReconnect=void 0,this.hasOpened=!1,this.machineId=`local`}open(){if(this.session===void 0||this.session.id===``||this.session.cwd===``||!this.shouldReconnect)return;let e=Pi(this.session,this.machineId);this.socket=e,e.onopen=()=>{this.reconnectDelay=500,this.hasOpened&&this.onReconnect?.(),this.hasOpened=!0},e.onmessage=e=>void this.handleMessage(e.data),e.onerror=()=>{e.close()},e.onclose=()=>{this.socket===e&&(this.socket=void 0),this.scheduleReconnect()}}scheduleReconnect(){if(!this.shouldReconnect)return;window.clearTimeout(this.reconnectTimer);let e=this.reconnectDelay;this.reconnectDelay=Math.min(this.reconnectDelay*1.6,5e3),this.reconnectTimer=window.setTimeout(()=>{this.open()},e)}async handleMessage(e){let t=await lc(e);ac(t)&&this.onEvent?.(t)}},ic=class{constructor(){this.reconnectDelay=500,this.shouldReconnect=!1,this.machineId=`local`}connect(e,t,n=`local`){this.close(),this.machineId=n,this.onEvent=e,this.onOpen=t,this.shouldReconnect=!0,this.open()}close(){this.shouldReconnect=!1,window.clearTimeout(this.reconnectTimer),uc(this.socket),this.socket=void 0,this.onEvent=void 0,this.onOpen=void 0,this.machineId=`local`}open(){if(!this.shouldReconnect)return;let e=Ii(this.machineId);this.socket=e,e.onopen=()=>{this.reconnectDelay=500,this.onOpen?.()},e.onmessage=e=>void this.handleMessage(e.data),e.onerror=()=>{e.close()},e.onclose=()=>{this.socket===e&&(this.socket=void 0),this.scheduleReconnect()}}scheduleReconnect(){if(!this.shouldReconnect)return;window.clearTimeout(this.reconnectTimer);let e=this.reconnectDelay;this.reconnectDelay=Math.min(this.reconnectDelay*1.6,5e3),this.reconnectTimer=window.setTimeout(()=>{this.open()},e)}async handleMessage(e){let t=await lc(e);sc(t)&&this.onEvent?.(t)}};function ac(e){let t=cc(e);return[`message.append`,`assistant.delta`,`assistant.thinking.delta`,`tool.start`,`tool.update`,`tool.end`,`shell.start`,`shell.chunk`,`shell.end`,`agent.start`,`agent.end`,`message.end`,`status.update`,`activity.update`,`command.output`,`session.error`,`session.name`,`session.created`,`pi.event`].includes(t)}function oc(e){let t=cc(e);return t===`status.update`||t===`activity.update`||t===`session.name`||t===`session.created`}function sc(e){let t=cc(e);return oc(e)||t===`terminal.created`||t===`terminal.exited`||t===`terminal.closed`||t===`workspace.activity`}function cc(e){if(typeof e!=`object`||!e||!(`type`in e))return``;let t=e.type;return typeof t==`string`?t:``}async function lc(e){try{return typeof e==`string`?JSON.parse(e):e instanceof Blob?JSON.parse(await e.text()):e instanceof ArrayBuffer?JSON.parse(new TextDecoder().decode(e)):void 0}catch{return}}function uc(e){if(e!==void 0){if(e.onmessage=null,e.onerror=null,e.onclose=null,e.readyState===WebSocket.CONNECTING){e.onopen=()=>{e.close()};return}e.close()}}function dc(e){return e?.ok===!0&&Rt(e,w.sessionsPersistedState)}function fc(e){return{authoritative:dc(e)}}function pc(e,t,n={}){if(e===void 0)return`unknown`;let r=(t?.sessionId===e.id?t.persisted:void 0)??e.persisted;return r===!0?`persisted`:r===!1||$a(e)?`transient`:n.authoritative===!0?`unknown`:`persisted`}function mc(e,t,n){return e!==void 0&&e.archived!==!0&&pc(e,t,n)===`persisted`}function hc(e,t,n){return e!==void 0&&e.archived!==!0&&pc(e,t,n)===`transient`}function gc(){try{return typeof sessionStorage>`u`?void 0:sessionStorage}catch{return}}var _c=class{constructor(e,t,n=gc()){this.storageKey=e,this.storage=n,this.values=new Map;for(let[r,i]of yc(e,t,n))this.values.set(r,i)}get(e){return this.values.get(e)}set(e,t){this.values.set(e,t),this.save()}delete(e){this.values.delete(e),this.save()}entries(){return[...this.values.entries()]}save(){try{if(this.values.size===0){this.storage?.removeItem(this.storageKey);return}let e={version:1,entries:[...this.values.entries()]};this.storage?.setItem(this.storageKey,JSON.stringify(e))}catch{}}};function vc(e){return typeof e==`string`&&e!==``?e:void 0}function yc(e,t,n){try{let r=n?.getItem(e);if(r==null||r===``)return[];let i=JSON.parse(r);if(!bc(i))return[];let a=[];for(let e of i.entries){let n=e[0],r=t(e[1]);r!==void 0&&a.push([n,r])}return a}catch{return[]}}function bc(e){return!xc(e)||e.version!==1||!Array.isArray(e.entries)?!1:e.entries.every(e=>Array.isArray(e)&&e.length===2&&typeof e[0]==`string`&&e[0]!==``)}function xc(e){return typeof e==`object`&&!!e}var Sc=class{constructor(){this.sessionIdsByCwd=new Map}latestSessionId(e){return this.sessionIdsByCwd.get(e)}rememberSession(e){this.sessionIdsByCwd.set(e.cwd,e.id)}forgetWorkspace(e){this.sessionIdsByCwd.delete(e)}},Cc=`pi-web:session-selection:v1`,wc=class{constructor(e=gc()){this.sessionIdsByCwd=new _c(Cc,vc,e)}latestSessionId(e){return this.sessionIdsByCwd.get(e)}rememberSession(e){this.sessionIdsByCwd.set(e.cwd,e.id)}forgetWorkspace(e){this.sessionIdsByCwd.delete(e)}};function Tc(e,t){let n=t?.targetSessionId;if(n!==void 0&&n!==``)return Dc(e,n);let r=t?.latestSessionId;return r!==void 0&&r!==``?e.find(e=>e.id===r)??e.find(e=>e.archived!==!0):e.find(e=>e.archived!==!0)}function Ec(e,t){return t?.archived===!0&&!e.some(e=>e.archived!==!0)}function Dc(e,t){return e.find(e=>e.id===t||e.id.startsWith(t))}function Oc(e,t,n){return kc(e,[t],n)}function kc(e,t,n){let r=new Set(t);return e.map(e=>r.has(e.id)?{...e,archived:!0,archivedAt:n}:e)}function Ac(e,t,n){return jc(e,t,[n])}function jc(e,t,n){if(t===void 0||!n.includes(t))return{type:`unchanged`};let r=new Set(n),i=e.find(e=>!r.has(e.id)&&e.archived!==!0);return i===void 0?{type:`clear`}:{type:`select`,session:i}}var Mc=100,Nc=4,Pc=class{constructor(e,t,n,r=new Sc,i={}){this.getState=e,this.setState=t,this.updateUrl=n,this.sessionSelection=r,this.selectionSeq=0,this.pendingTranscriptEvents=[],this.pendingStatusBySession=new Map,this.pendingActivityBySession=new Map,this.pendingSessionStartSeq=0,this.pendingQueuedSendSeq=0,this.pendingSessionStarts=new Map,this.suppressedCreatedSessions=new Map,this.selectedSessionRefreshes=new fa,this.socket=i.socket??new rc,this.api=i.api??F,this.transcripts=i.transcripts??new Gs}applyGlobalEvent(e){e.type===`status.update`?this.queueStatusUpdate(e.status):e.type===`activity.update`?this.queueActivityUpdate(e.activity):e.type===`session.created`?this.applyCreatedSession(e.session):this.applySessionName(e.sessionId,e.name)}dispose(){this.selectionSeq+=1,this.socket.close(),this.clearPendingUpdates()}clearActiveSession(){this.selectionSeq+=1,this.socket.close(),this.streamWatermark=void 0,this.clearPendingUpdates(),this.setState({selectedSession:void 0,messages:[],messagePageStart:0,messagePageEnd:0,messagePageTotal:0,isLoadingEarlierMessages:!1,status:void 0,activity:void 0,availableThinkingLevels:[]})}deselectSession(e){let t=this.getState(),n=t.selectedSession?.cwd??t.selectedWorkspace?.path;e?.forgetRememberedSelection===!0&&n!==void 0&&this.sessionSelection.forgetWorkspace(this.workspaceSelectionKey(n)),this.clearActiveSession(),e?.updateUrl!==!1&&this.updateUrl()}clearSelectionAfterArchivedCollapse(){let e=this.getState();Ec(e.sessions,e.selectedSession)&&this.deselectSession({forgetRememberedSelection:!0})}async startSession(){let e=this.getState().selectedWorkspace;if(!e)return;let t=I(this.getState()),n=this.createPendingSessionStart(e,t);this.pendingSessionStarts.set(n.tempId,n),this.insertAndSelectPendingSession(n.session);try{let r=await this.api.startSession(e.path,t);await this.resolvePendingSessionStart(n.tempId,r)}catch(e){this.failPendingSessionStart(n.tempId,e)}}preferredSession(e,t,n){return Tc(t,{targetSessionId:n,latestSessionId:this.sessionSelection.latestSessionId(this.workspaceSelectionKey(e))})}async selectSession(e,t){if(Bc(e)){this.selectClientPendingStartSession(e,t);return}this.sessionSelection.rememberSession({...e,cwd:this.workspaceSelectionKey(e.cwd)});let n=++this.selectionSeq;this.socket.close(),this.streamWatermark=void 0,this.clearPendingUpdates();let r=this.sessionCacheKey(e.id),i=this.transcripts.cachedView(r);this.setState({selectedSession:e,...i,isLoadingEarlierMessages:!1,status:e.archived===!0?void 0:this.getState().sessionStatuses[e.id],activity:e.archived===!0?void 0:this.getState().sessionActivities[e.id],availableThinkingLevels:[]});try{if(e.archived===!0){let i=await this.api.messages(e,{limit:Mc},I(this.getState()));if(n!==this.selectionSeq||this.getState().selectedSession?.id!==e.id)return;let a=this.transcripts.mergeHistory(r,i);this.setState({...a,isLoadingEarlierMessages:!1,status:void 0,activity:void 0}),t?.updateUrl!==!1&&this.updateUrl();return}let i=[];this.socket.connect(e,e=>i.push(e),()=>{this.refreshSelectedSession(e.id)},I(this.getState()));let a=I(this.getState());if(await this.requestSelectedSessionRefresh({session:e,machineId:a,selectionSeq:n}),!this.isCurrentRefreshTarget({session:e,machineId:a,selectionSeq:n}))return;this.refreshAvailableThinkingLevels();for(let e of i)this.applyEvent(e);this.socket.setHandler(e=>{this.applyEvent(e)}),t?.updateUrl!==!1&&this.updateUrl()}catch(r){if(n!==this.selectionSeq||this.getState().selectedSession?.id!==e.id)return;if($a(e)&&nl(r)){await this.recreateCachedNewSession(e,t);return}this.setState({error:String(r)})}}async loadEarlierMessages(){let e=this.getState(),t=e.selectedSession;if(!(!t||e.isLoadingEarlierMessages||e.messagePageStart<=0)){this.setState({isLoadingEarlierMessages:!0});try{let n=await this.api.messages(t,{before:e.messagePageStart,limit:Mc},I(this.getState()));if(this.getState().selectedSession?.id!==t.id)return;let r=this.transcripts.mergeHistory(this.sessionCacheKey(t.id),n);this.setState(r)}catch(e){this.setState({error:String(e)})}finally{this.getState().selectedSession?.id===t.id&&this.setState({isLoadingEarlierMessages:!1})}}}async send(e,t,n,r=`inline`){let i=this.getState().selectedSession;if(!i||i.archived===!0)return;let a=e.trim(),o=n!==void 0&&n.length>0;if(Bc(i)){!o&&a.startsWith(`/`)?this.enqueuePendingSessionSend(i,{type:`command`,text:e}):!o&&ec(e)?this.enqueuePendingSessionSend(i,{type:`shell`,text:e}):this.enqueuePendingSessionSend(i,{type:`prompt`,text:e,streamingBehavior:t,attachments:n,delivery:r});return}if(!o&&a.startsWith(`/`))return this.runCommand(e);if(!o&&ec(e))return this.runShell(e);await this.deliverPromptToSession(i,e,t,n,r,I(this.getState()),{markSending:o})}markSendingPrompt(e,t){let n=this.getState().sendingPrompts;t?n[e]!==!0&&this.setState({sendingPrompts:{...n,[e]:!0}}):e in n&&this.setState({sendingPrompts:Ic(n,e)})}async runShell(e){let t=this.getState().selectedSession;if(!(!t||t.archived===!0)){if(Bc(t)){this.enqueuePendingSessionSend(t,{type:`shell`,text:e});return}await this.deliverShellToSession(t,e,I(this.getState()),{optimisticLine:!0})}}async runCommand(e){let t=this.getState().selectedSession;if(!(!t||t.archived===!0)){if(Bc(t)){this.enqueuePendingSessionSend(t,{type:`command`,text:e});return}await this.deliverCommandToSession(t,e,I(this.getState()),{applyResult:!0})}}enqueuePendingSessionSend(e,t){let n=this.pendingSessionStarts.get(e.id);if(n===void 0||n.discarded){this.setState({error:`The backend session is not ready for queued sends. Copy your message before discarding this failed start.`});return}let r={...t,id:`pending-send-${String(++this.pendingQueuedSendSeq)}`};n.queuedSends.push(r);let i=this.getState(),a=i.clientQueuedSessionMessages[e.id]??[],o=Vc(e.id,n.queuedSends.length);this.setState({clientQueuedSessionMessages:{...i.clientQueuedSessionMessages,[e.id]:[...a,Uc(r)]},sessionActivities:{...i.sessionActivities,[e.id]:o},activity:i.selectedSession?.id===e.id?o:i.activity,error:``})}async flushQueuedPendingSends(e,t,n){for(let r of n){if(!await this.deliverQueuedPendingSend(e,t,r))return;this.dropNextQueuedSessionMessage(e.id)}}async deliverQueuedPendingSend(e,t,n){return n.type===`prompt`?this.deliverPromptToSession(e,n.text,n.streamingBehavior,n.attachments,n.delivery,t,{markSending:!0}):n.type===`shell`?this.deliverShellToSession(e,n.text,t,{optimisticLine:!0}):this.deliverCommandToSession(e,n.text,t,{applyResult:!0})}async deliverPromptToSession(e,t,n,r,i,a,o){let s=r!==void 0&&r.length>0;o.markSending&&this.markSendingPrompt(e.id,!0);try{if(s&&i===`folder`){let i=(await this.api.saveAttachments(e,r,a)).map(e=>Js(e.path,!1)).join(` `),o=t===``?i:`${t}\n\n${i}`;await this.api.prompt(e,o,n,a)}else await this.api.prompt(e,t,n,a,r);return this.markCachedNewSessionPersisted(e),!0}catch(e){return this.setState({error:String(e)}),!1}finally{o.markSending&&this.markSendingPrompt(e.id,!1)}}async deliverShellToSession(e,t,n,r){r.optimisticLine&&this.getState().selectedSession?.id===e.id&&this.setState({messages:[...this.getState().messages,uo(`user`,t)]});try{return await this.api.shell(e,t,n),this.markCachedNewSessionPersisted(e),!0}catch(t){return this.getState().selectedSession?.id===e.id&&this.setState({messages:[...this.getState().messages,uo(`system`,String(t))]}),this.setState({error:String(t)}),!1}}async deliverCommandToSession(e,t,n,r){this.markSendingPrompt(e.id,!0);try{let i=await this.api.runCommand(e,t,n);return r.applyResult&&this.getState().selectedSession?.id===e.id?this.applyCommandResult(i):i.type===`select`&&this.setState({error:`Queued command “${t}” needs input; open the session and run it again.`}),this.markCachedNewSessionPersisted(e),!0}catch(t){return this.getState().selectedSession?.id===e.id&&this.setState({messages:[...this.getState().messages,uo(`system`,String(t))]}),this.setState({error:String(t)}),!1}finally{this.markSendingPrompt(e.id,!1)}}dropNextQueuedSessionMessage(e){let t=this.getState(),n=t.clientQueuedSessionMessages[e]??[];if(n.length===0)return;let r=n.slice(1);this.setState({clientQueuedSessionMessages:r.length===0?Ic(t.clientQueuedSessionMessages,e):{...t.clientQueuedSessionMessages,[e]:r}})}async respondToCommand(e,t){let n=this.getState().selectedSession;if(n){this.setState({commandDialog:void 0});try{this.applyCommandResult(await this.api.respondToCommand(n,e,t,I(this.getState())))}catch(e){this.setState({error:String(e)})}}}cancelCommand(){this.setState({commandDialog:void 0})}applySessionStatus(e){this.applyStatus(e)}async archiveSession(e=this.getState().selectedSession){if(!e)return;let t=this.statusForSession(e),n=this.sessionPersistenceOptions();if(hc(e,t,n)){await this.deleteCachedNewSession(e);return}if(mc(e,t,n))try{await this.api.archive(e,I(this.getState()));let t=this.getState(),n=Oc(t.sessions,e.id,new Date().toISOString()),r=Ac(n,t.selectedSession?.id,e.id);this.setState({sessions:n}),r.type===`select`?await this.selectSession(r.session):r.type===`clear`&&this.deselectSession({forgetRememberedSelection:!0})}catch(e){this.setState({error:String(e)})}}async archiveSessionWithDescendants(e=this.getState().selectedSession){if(!(e===void 0||!mc(e,this.statusForSession(e),this.sessionPersistenceOptions())))try{let t=await this.api.archiveWithDescendants(e,I(this.getState())),n=t.sessionIds!==void 0&&t.sessionIds.length>0?t.sessionIds:[e.id],r=this.getState(),i=kc(r.sessions,n,new Date().toISOString()),a=jc(i,r.selectedSession?.id,n);this.setState({sessions:i}),a.type===`select`?await this.selectSession(a.session):a.type===`clear`&&this.deselectSession({forgetRememberedSelection:!0})}catch(e){this.setState({error:String(e)})}}async archiveSessions(e){let t=this.sessionPersistenceOptions(),n=Kc(e).filter(e=>mc(e,this.statusForSession(e),t));if(n.length!==0)try{let e=I(this.getState()),{succeededIds:t,failures:r,generatedAt:i}=await this.archiveSessionBatch(n,e);if(t.length>0){let e=this.getState(),n=kc(e.sessions,t,i??new Date().toISOString()),r=jc(n,e.selectedSession?.id,t);this.setState({sessions:n}),r.type===`select`?await this.selectSession(r.session):r.type===`clear`&&this.deselectSession({forgetRememberedSelection:!0})}this.applyBulkSessionFailures(`Archive`,r)}catch(e){this.setState({error:`Archive failed: ${$c(e)}`})}}async deleteArchivedSessions(e){let t=Kc(e).filter(e=>e.archived===!0);if(t.length===0)return;let n=I(this.getState()),r=this.getState().machineRuntimes[n];if(r?.ok===!0&&!Rt(r,w.sessionsDeleteArchived)){this.setState({error:`Deleting archived sessions requires an updated Pi-Web runtime on this machine.`});return}try{let{succeededIds:e,failures:r}=await this.deleteArchivedSessionBatch(t,n);if(e.length>0){let t=new Set(e),n=this.getState(),r=n.sessions.filter(e=>!t.has(e.id));if(this.setState({sessions:r}),n.selectedSession!==void 0&&t.has(n.selectedSession.id)){let e=r.find(e=>e.archived!==!0)??r[0];e===void 0?this.deselectSession({forgetRememberedSelection:!0}):await this.selectSession(e)}}this.applyBulkSessionFailures(`Delete`,r)}catch(e){this.setState({error:`Delete failed: ${$c(e)}`})}}async archiveSessionBatch(e,t){let n=this.getState().machineRuntimes[t];if(n?.ok===!0&&Rt(n,w.sessionsBulkMutations)){let n=await this.api.archiveMany(e,t);return{succeededIds:n.archivedSessionIds,failures:Jc(n.failures),generatedAt:n.generatedAt}}let r=await Xc(e,Nc,async e=>(await this.api.archive(e,t),e.id));return{succeededIds:qc(r),failures:Yc(e,r)}}async deleteArchivedSessionBatch(e,t){let n=this.getState().machineRuntimes[t];if(n?.ok===!0&&Rt(n,w.sessionsBulkMutations)){let n=await this.api.deleteArchivedMany(e,t);return{succeededIds:n.deletedSessionIds,failures:Jc(n.failures)}}let r=await Xc(e,Nc,async e=>(await this.api.deleteArchived(e,t),e.id));return{succeededIds:qc(r),failures:Yc(e,r)}}async applySessionCleanupResult(e,t=I(this.getState())){if(I(this.getState())!==t)return;let n=e.archivedSessionIds,r=e.deletedSessionIds;if(n.length>0||r.length>0){let t=this.getState(),i=new Set(r),a=[...n,...r],o=kc(t.sessions,n,e.generatedAt).filter(e=>!i.has(e.id)),s=t.selectedSession!==void 0&&a.includes(t.selectedSession.id);if(this.setState({sessions:o,sessionStatuses:Lc(t.sessionStatuses,a),sessionActivities:Lc(t.sessionActivities,a),...s?{status:void 0,activity:void 0}:{}}),t.selectedSession!==void 0&&i.has(t.selectedSession.id)){let e=o.find(e=>e.archived!==!0)??o[0];e===void 0?this.deselectSession({forgetRememberedSelection:!0}):await this.selectSession(e)}else{let e=jc(o,t.selectedSession?.id,n);e.type===`select`?await this.selectSession(e.session):e.type===`clear`&&this.deselectSession({forgetRememberedSelection:!0})}}await this.refreshCurrentWorkspaceSessions(t)}async refreshCurrentWorkspaceSessions(e=I(this.getState())){let t=this.getState().selectedWorkspace;if(t!==void 0)try{let n=Qa(t.path,await this.api.sessions(t.path,e),e).filter(t=>!this.isSuppressedCreatedSession(t,e));if(I(this.getState())!==e||this.getState().selectedWorkspace?.id!==t.id)return;let r=this.mergePendingStartSessions(t.path,n,e),i=this.getState().selectedSession;if(this.setState({sessions:r}),i===void 0)return;let a=r.find(e=>e.id===i.id);if(a!==void 0){a!==i&&this.setState({selectedSession:a});return}let o=r.find(e=>e.archived!==!0)??r[0];o===void 0?this.deselectSession({forgetRememberedSelection:!0}):await this.selectSession(o)}catch(n){I(this.getState())===e&&this.getState().selectedWorkspace?.id===t.id&&this.setState({error:String(n)})}}async deleteCachedNewSession(e=this.getState().selectedSession){if(e===void 0||!hc(e,this.statusForSession(e),this.sessionPersistenceOptions()))return;let t=Bc(e)?this.pendingSessionStarts.get(e.id):void 0;t===void 0?this.api.stop(e,I(this.getState())).catch(()=>{}):(t.discarded=!0,t.queuedSends=[]),Za(e.id,I(this.getState())),Ko(this.sessionCacheKey(e.id));let n=this.getState(),r=n.sessions.filter(t=>t.id!==e.id);if(this.setState({sessions:r,sessionStatuses:Ic(n.sessionStatuses,e.id),sessionActivities:Fc(n.sessionActivities,e.id),sendingPrompts:Ic(n.sendingPrompts,e.id),clientQueuedSessionMessages:Ic(n.clientQueuedSessionMessages,e.id)}),this.getState().selectedSession?.id!==e.id)return;let i=r.find(e=>e.archived!==!0)??r[0];i===void 0?(this.clearActiveSession(),this.updateUrl()):await this.selectSession(i)}async restoreSession(e=this.getState().selectedSession){if(e)try{await this.api.restore(e,I(this.getState()));let t={...e};delete t.archived,delete t.archivedAt,this.replaceSession(t),this.getState().selectedSession?.id===t.id&&await this.selectSession(t)}catch(e){this.setState({error:String(e)})}}async reloadSession(e=this.getState().selectedSession){if(e===void 0||!mc(e,this.statusForSession(e),this.sessionPersistenceOptions()))return;let t=I(this.getState()),n=this.getState().machineRuntimes[t];if(n?.ok!==!0||!Rt(n,w.sessionsReload)){this.setState({error:`Reloading sessions from disk requires an updated Pi-Web runtime on this machine.`});return}try{await this.api.reloadSession(e.id,t),this.transcripts.discard(this.sessionCacheKey(e.id)),this.getState().selectedSession?.id===e.id&&await this.selectSession(e,{updateUrl:!1})}catch(e){this.setState({error:String(e)})}}async detachParent(e=this.getState().selectedSession){if(e?.parentSessionPath!==void 0)try{await this.api.detachParent(e,I(this.getState()));let t={...e};delete t.parentSessionPath,this.replaceSession(t)}catch(e){this.setState({error:String(e)})}}async listModels(){let e=this.getState().selectedSession;if(!e||e.archived===!0)return[];try{return(await this.api.models(e,I(this.getState()))).models}catch(e){return this.setState({error:String(e)}),[]}}async setModel(e,t){let n=this.getState().selectedSession;if(!(!n||n.archived===!0))try{this.applyStatus(await this.api.setModel(n,e,t,I(this.getState()))),await this.refreshAvailableThinkingLevels()}catch(e){this.setState({error:String(e)})}}async cycleModel(e){let t=this.getState().selectedSession;if(!(!t||t.archived===!0))try{this.applyStatus(await this.api.cycleModel(t,e,I(this.getState()))),await this.refreshAvailableThinkingLevels()}catch(e){this.setState({error:String(e)})}}async listThinkingLevels(){let e=this.getState().selectedSession;if(!e||e.archived===!0)return[];try{return(await this.api.thinkingLevels(e,I(this.getState()))).levels}catch(e){return this.setState({error:String(e)}),[]}}async refreshAvailableThinkingLevels(){let e=this.getState().selectedSession;if(!e||e.archived===!0){this.getState().availableThinkingLevels.length>0&&this.setState({availableThinkingLevels:[]});return}let t=await this.listThinkingLevels();this.getState().selectedSession?.id===e.id&&this.setState({availableThinkingLevels:t})}async setThinkingLevel(e){let t=this.getState().selectedSession;if(!(!t||t.archived===!0))try{this.applyStatus(await this.api.setThinkingLevel(t,e,I(this.getState())))}catch(e){this.setState({error:String(e)})}}async cycleThinkingLevel(){let e=this.getState().selectedSession;if(!(!e||e.archived===!0))try{this.applyStatus(await this.api.cycleThinkingLevel(e,I(this.getState())))}catch(e){this.setState({error:String(e)})}}async clearServerQueue(){let e=this.getState(),t=e.selectedSession;if(t===void 0||t.archived===!0||Bc(t))return;let n=I(e),r=this.selectionSeq;try{let e=await this.api.clearQueue(t,n);this.isCurrentSessionSelection(t.id,n,r)&&this.applyStatus(e)}catch(e){this.isCurrentSessionSelection(t.id,n,r)&&this.setState({error:String(e)})}}async dismissWarning(e){let t=this.getState(),n=t.selectedSession;if(n===void 0||Bc(n))return;let r=I(t),i=this.selectionSeq;try{let t=await this.api.dismissWarning(n,e,r);this.isCurrentSessionSelection(n.id,r,i)&&this.applyStatus(t)}catch(e){this.isCurrentSessionSelection(n.id,r,i)&&this.setState({error:String(e)})}}async stopActiveWork(){let e=this.getState().selectedSession;if(e)try{await this.api.abort(e,I(this.getState()))}catch(e){this.setState({error:String(e)})}}refreshSelectedSession(e=this.getState().selectedSession?.id){let t=this.getState().selectedSession;if(e===void 0||t?.id!==e||t.archived===!0||Bc(t))return Promise.resolve();let n={session:t,machineId:I(this.getState()),selectionSeq:this.selectionSeq};return this.requestSelectedSessionRefresh(n).catch(e=>{this.isCurrentRefreshTarget(n)&&this.setState({error:String(e)})})}requestSelectedSessionRefresh(e){let t=da(e.machineId,e.session.id);return this.selectedSessionRefreshes.request(t,async()=>{if(!this.isCurrentRefreshTarget(e))return;this.flushPendingUpdates();let[n,r,i]=await Promise.all([this.api.messages(e.session,{limit:Mc},e.machineId),this.api.status(e.session,e.machineId),this.api.streamSnapshot(e.session,e.machineId).catch(()=>({seq:0,partial:null}))]);if(!this.isCurrentRefreshTarget(e))return;let a=this.transcripts.mergeHistory(t,n),o=this.transcripts.seedStreamingPartial(a.messages,i.partial);this.streamWatermark={sessionId:e.session.id,seq:i.seq},this.setState({...a,messages:o,status:r,activity:this.getState().sessionActivities[e.session.id]}),this.applyStatus(r)})}isCurrentRefreshTarget(e){return this.isCurrentSessionSelection(e.session.id,e.machineId,e.selectionSeq)}isCurrentSessionSelection(e,t,n){let r=this.getState(),i=r.selectedSession;return n===this.selectionSeq&&I(r)===t&&i?.id===e&&i.archived!==!0&&!Bc(i)}applyBulkSessionFailures(e,t){t.length!==0&&this.setState({error:`${e} failed for ${String(t.length)} session${t.length===1?``:`s`}: ${t.join(`; `)}`})}sessionCacheKey(e){return da(I(this.getState()),e)}statusForSession(e){if(e===void 0)return;let t=this.getState();return t.status?.sessionId===e.id&&t.selectedSession?.id===e.id?t.status:t.sessionStatuses[e.id]}sessionPersistenceOptions(){let e=this.getState();return fc(e.machineRuntimes[I(e)])}workspaceSelectionKey(e){return`${I(this.getState())}:${e}`}replaceSession(e){let t=this.getState().selectedSession;this.setState({sessions:this.getState().sessions.map(t=>t.id===e.id?e:t),selectedSession:t?.id===e.id?e:t})}createPendingSessionStart(e,t){let n=`pending-session-${String(++this.pendingSessionStartSeq)}-${Date.now().toString(36)}`,r=new Date().toISOString(),i={id:n,path:`pi-web://pending-session/${n}`,cwd:e.path,persisted:!1,name:`New session`,created:r,modified:r,messageCount:0,firstMessage:``,clientPendingStart:!0,machineId:t};return{tempId:n,workspaceId:e.id,cwd:e.path,machineId:t,session:i,queuedSends:[],discarded:!1}}insertAndSelectPendingSession(e){let t=this.getState();this.selectClientPendingStartSession(e,{activity:Vc(e.id),sessions:[e,...t.sessions.filter(t=>t.id!==e.id)]})}selectClientPendingStartSession(e,t){this.sessionSelection.rememberSession({...e,cwd:this.workspaceSelectionKey(e.cwd)}),this.selectionSeq+=1,this.socket.close(),this.streamWatermark=void 0,this.clearPendingUpdates();let n=this.getState(),r=this.pendingSessionStarts.get(e.id),i=t?.activity??n.sessionActivities[e.id]??(r===void 0?void 0:Vc(e.id,r.queuedSends.length));this.setState({...t?.sessions===void 0?{}:{sessions:t.sessions},selectedSession:e,messages:[],messagePageStart:0,messagePageEnd:0,messagePageTotal:0,isLoadingEarlierMessages:!1,status:void 0,activity:i,availableThinkingLevels:[],...i===void 0?{}:{sessionActivities:{...n.sessionActivities,[e.id]:i}},error:``}),t?.updateUrl!==!1&&this.updateUrl()}async resolvePendingSessionStart(e,t){let n=this.pendingSessionStarts.get(e);if(n===void 0)return;this.pendingSessionStarts.delete(e);let r=n.queuedSends.splice(0),i=this.takeSuppressedCreatedSessionsFor(n.cwd,n.machineId,t.id);if(n.discarded){Ko(da(n.machineId,e)),this.setState({clientQueuedSessionMessages:Ic(this.getState().clientQueuedSessionMessages,e)}),this.applyReleasedCreatedSessions(i,n.machineId),this.api.stop(t,n.machineId).catch(()=>{});return}Ya(t,n.machineId),qo(da(n.machineId,e),da(n.machineId,t.id));let a=Xa(t,n.machineId);if(!this.isCurrentPendingStart(n)){this.setState({clientQueuedSessionMessages:Ic(this.getState().clientQueuedSessionMessages,e)}),await this.flushQueuedPendingSends(a,n.machineId,r);return}let o=this.getState(),s=o.selectedSession?.id===e;this.setState({sessions:zc(o.sessions,e,a),sessionActivities:Fc(o.sessionActivities,e),sendingPrompts:Rc(o.sendingPrompts,e,a.id),clientQueuedSessionMessages:Rc(o.clientQueuedSessionMessages,e,a.id),...s?{selectedSession:a,status:o.sessionStatuses[a.id],activity:o.sessionActivities[a.id]}:{},error:``}),this.applyReleasedCreatedSessions(i,n.machineId),s&&(this.updateUrl({replace:!0}),await this.selectSession(a,{updateUrl:!1})),await this.flushQueuedPendingSends(a,n.machineId,r)}failPendingSessionStart(e,t){let n=this.pendingSessionStarts.get(e);if(n===void 0)return;this.pendingSessionStarts.delete(e);let r=this.takeSuppressedCreatedSessionsFor(n.cwd,n.machineId),i=this.isCurrentPendingStart(n);if(n.discarded||!i){i&&this.applyReleasedCreatedSessions(r,n.machineId);return}let a=this.getState(),o=$c(t),s=Hc(e,o,n.queuedSends.length),c=a.sessions.some(t=>t.id===e);this.setState({sessions:c?a.sessions:[n.session,...a.sessions],sessionActivities:{...a.sessionActivities,[e]:s},activity:a.selectedSession?.id===e?s:a.activity,error:`Failed to start session: ${o}`}),this.applyReleasedCreatedSessions(r,n.machineId)}isCurrentPendingStart(e){let t=this.getState();return I(t)===e.machineId&&t.selectedWorkspace?.id===e.workspaceId}hasPendingStartFor(e,t){return Array.from(this.pendingSessionStarts.values()).some(n=>n.cwd===e&&n.machineId===t)}isSuppressedCreatedSession(e,t){let n=this.suppressedCreatedSessions.get(e.id);return n?.session.cwd===e.cwd&&n.machineId===t}takeSuppressedCreatedSessionsFor(e,t,n){if(n!==void 0&&this.suppressedCreatedSessions.delete(n),this.hasPendingStartFor(e,t))return[];let r=[];for(let[n,i]of this.suppressedCreatedSessions)i.session.cwd!==e||i.machineId!==t||(this.suppressedCreatedSessions.delete(n),r.push(i.session));return r}applyReleasedCreatedSessions(e,t){if(e.length===0||I(this.getState())!==t)return;let n=this.getState();if(n.selectedWorkspace===void 0)return;let r=new Set(n.sessions.map(e=>e.id)),i=e.filter(e=>e.cwd===n.selectedWorkspace?.path&&!r.has(e.id));i.length!==0&&this.setState({sessions:[...i.reverse(),...n.sessions]})}mergePendingStartSessions(e,t,n){let r=this.getState().sessions.filter(t=>Bc(t)&&t.cwd===e&&t.machineId===n);if(r.length===0)return t;let i=new Set(r.map(e=>e.id));return[...r,...t.filter(e=>!i.has(e.id))]}async recreateCachedNewSession(e,t){try{let n=I(this.getState()),r=await this.api.startSession(e.cwd,n);Ya(r,n),qo(this.sessionCacheKey(e.id),this.sessionCacheKey(r.id)),Za(e.id,n);let i=Xa(r,n);this.setState({sessions:[i,...this.getState().sessions.filter(t=>t.id!==e.id)],error:``}),await this.selectSession(i,{updateUrl:!1}),this.updateUrl(t?.updateUrl===!1?{replace:!0}:void 0)}catch(e){this.setState({error:String(e)})}}markCachedNewSessionPersisted(e){if(!$a(e))return;let t=this.getState().sessions.find(t=>t.id===e.id)??e;this.replaceSession(eo(t))}applyCommandResult(e){if(e.type===`select`){this.setState({commandDialog:e});return}let t=(e.type,e.message);if(t!==void 0&&t!==``&&this.setState({messages:[...this.getState().messages,uo(e.type===`unsupported`?`system`:`tool`,t)]}),e.type===`done`&&e.session){e.promptDraft!==void 0&&Go(this.sessionCacheKey(e.session.id),e.promptDraft);let t=this.getState().selectedSession,n=[e.session,...this.getState().sessions.filter(t=>t.id!==e.session?.id)];this.setState({sessions:n,selectedSession:t?.id===e.session.id?e.session:t}),t?.id!==e.session.id&&this.selectSession(e.session)}}applyCreatedSession(e){let t=this.getState();if(t.selectedWorkspace?.path!==e.cwd||t.sessions.some(t=>t.id===e.id))return;let n=I(t);if(this.hasPendingStartFor(e.cwd,n)){this.suppressedCreatedSessions.set(e.id,{session:e,machineId:n});return}this.setState({sessions:[e,...t.sessions]})}applyActivity(e){this.setState({sessionActivities:{...this.getState().sessionActivities,[e.sessionId]:e},activity:this.getState().selectedSession?.id===e.sessionId?e:this.getState().activity})}applyStatus(e){let t=this.getState(),n=t.sessionActivities[e.sessionId]?.phase===`active`&&!ca(e);this.setState({sessionStatuses:{...t.sessionStatuses,[e.sessionId]:e},...el(t,e.sessionId,e.messageCount),...n?{sessionActivities:Fc(t.sessionActivities,e.sessionId)}:{},status:t.selectedSession?.id===e.sessionId?e:t.status,activity:t.selectedSession?.id===e.sessionId&&n?void 0:t.activity})}applySessionName(e,t){let n=n=>{if(n.id!==e)return n;let r={...n};return t===void 0||t===``?delete r.name:r.name=t,r},r=this.getState().selectedSession;this.setState({sessions:this.getState().sessions.map(n),selectedSession:r===void 0?void 0:n(r)})}applyEvent(e){if(this.isStreamEventBelowWatermark(e))return;if(e.type===`status.update`){this.queueStatusUpdate(e.status);return}if(e.type===`activity.update`){this.queueActivityUpdate(e.activity);return}if(tl(e)){this.queueTranscriptEvent(e);return}this.flushPendingUpdates();let t=this.transcripts.applyLiveEvent(this.getState().messages,e);t?this.setState({messages:t}):e.type===`session.name`&&this.applySessionName(e.sessionId,e.name)}queueTranscriptEvent(e){this.pendingTranscriptEvents.push(e),this.schedulePendingFlush()}queueStatusUpdate(e){this.pendingStatusBySession.set(e.sessionId,e),this.schedulePendingFlush()}queueActivityUpdate(e){this.pendingActivityBySession.set(e.sessionId,e),this.schedulePendingFlush()}schedulePendingFlush(){this.pendingFrame===void 0&&(this.pendingFrame=requestAnimationFrame(()=>{this.pendingFrame=void 0,this.flushPendingUpdates()}))}flushPendingUpdates(){if(this.pendingTranscriptEvents.length>0){let e=this.pendingTranscriptEvents;this.pendingTranscriptEvents=[];let t=this.getState().messages;for(let n of e)t=this.transcripts.applyLiveEvent(t,n)??t;t!==this.getState().messages&&this.setState({messages:t})}if(this.pendingActivityBySession.size>0){let e=Array.from(this.pendingActivityBySession.values());this.pendingActivityBySession.clear();for(let t of e)this.applyActivity(t)}if(this.pendingStatusBySession.size>0){let e=Array.from(this.pendingStatusBySession.values());this.pendingStatusBySession.clear();for(let t of e)this.applyStatus(t)}}clearPendingUpdates(){this.pendingTranscriptEvents=[],this.pendingStatusBySession.clear(),this.pendingActivityBySession.clear(),this.pendingFrame!==void 0&&(cancelAnimationFrame(this.pendingFrame),this.pendingFrame=void 0)}isStreamEventBelowWatermark(e){let t=this.streamWatermark;return t===void 0||t.sessionId!==this.getState().selectedSession?.id?!1:e.seq!==void 0&&e.seq<=t.seq}};function Fc(e,t){return Ic(e,t)}function Ic(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>e!==t))}function Lc(e,t){if(t.length===0)return e;let n=new Set(t);return Object.fromEntries(Object.entries(e).filter(([e])=>!n.has(e)))}function Rc(e,t,n){if(t===n||!(t in e))return e;let r=e[t];return r===void 0?e:{...Ic(e,t),[n]:r}}function zc(e,t,n){let r=[],i=!1;for(let a of e){if(a.id===t){i||=(r.push(n),!0);continue}a.id!==n.id&&r.push(a)}return i?r:[n,...r]}function Bc(e){return e!==void 0&&`clientPendingStart`in e&&e.clientPendingStart===!0}function Vc(e,t=0){return{sessionId:e,phase:`active`,label:`Creating session`,detail:t>0?`${String(t)} queued ${t===1?`message`:`messages`} will send when the backend session is ready`:`Waiting for the backend session to be ready`,at:new Date().toISOString()}}function Hc(e,t,n=0){return{sessionId:e,phase:`error`,label:`Session creation failed`,detail:`${t}${n>0?` · ${String(n)} queued ${n===1?`message`:`messages`} kept below`:``}`,at:new Date().toISOString()}}function Uc(e){return e.type===`prompt`?{kind:e.streamingBehavior===`steer`?`steer`:`followUp`,text:Wc(e.text,e.attachments)}:{kind:`followUp`,text:e.text}}function Wc(e,t){let n=Gc(t);return n===void 0?e:e.trim()===``?n:`${e}\n\n${n}`}function Gc(e){if(e===void 0||e.length===0)return;let t=e.map(e=>e.name?.trim()).filter(e=>e!==void 0&&e!==``),n=e.length,r=`${String(n)} ${n===1?`attachment`:`attachments`}`;return t.length===0?`[${r} queued]`:`[${r} queued: ${t.slice(0,3).join(`, `)}${t.length>3?`, +${String(t.length-3)} more`:``}]`}function Kc(e){let t=new Set,n=[];for(let r of e)t.has(r.id)||(t.add(r.id),n.push(r));return n}function qc(e){return e.filter(Zc).map(e=>e.value)}function Jc(e){return e.map(e=>`${e.sessionId}: ${e.error}`)}function Yc(e,t){return t.flatMap((t,n)=>Qc(t)?[`${e[n]?.id??`unknown`}: ${$c(t.reason)}`]:[])}async function Xc(e,t,n){let r=e.map((e,t)=>({item:e,index:t})),i=[],a=0;async function o(){for(;a<r.length;){let e=r[a];if(e===void 0)return;a+=1;try{i[e.index]={status:`fulfilled`,value:await n(e.item)}}catch(t){i[e.index]={status:`rejected`,reason:t}}}}let s=Math.min(Math.max(1,t),r.length);return await Promise.all(Array.from({length:s},()=>o())),i}function Zc(e){return e.status===`fulfilled`}function Qc(e){return e.status===`rejected`}function $c(e){return e instanceof Error?e.message:String(e)}function el(e,t,n){if(n===void 0)return{};let r=e.sessions.some(e=>e.id===t&&e.messageCount!==n)?e.sessions.map(e=>e.id===t?{...e,messageCount:n}:e):void 0,i=e.selectedSession?.id===t&&e.selectedSession.messageCount!==n?{...e.selectedSession,messageCount:n}:e.selectedSession;return{...r===void 0?{}:{sessions:r},...i===e.selectedSession?{}:{selectedSession:i}}}function tl(e){return e.type===`assistant.delta`||e.type===`assistant.thinking.delta`||e.type===`shell.chunk`}function nl(e){return e instanceof Error&&e.message.toLowerCase().includes(`session not found`)}var rl=class{constructor(){this.workspaceIdsByProject=new Map}latestWorkspaceId(e){return this.workspaceIdsByProject.get(e)}rememberWorkspace(e){this.workspaceIdsByProject.set(e.projectId,e.id)}forgetProject(e){this.workspaceIdsByProject.delete(e)}},il=`pi-web:workspace-selection:v1`,al=class{constructor(e=gc()){this.workspaceIdsByProject=new _c(il,vc,e)}latestWorkspaceId(e){return this.workspaceIdsByProject.get(e)}rememberWorkspace(e){this.workspaceIdsByProject.set(e.projectId,e.id)}forgetProject(e){this.workspaceIdsByProject.delete(e)}};function ol(e,t){let n=t?.targetWorkspaceId;if(n!==void 0&&n!==``)return e.find(e=>e.id===n);let r=t?.latestWorkspaceId;return r!==void 0&&r!==``?e.find(e=>e.id===r)??e[0]:e[0]}var sl=class{constructor(e,t,n,r,i=new rl,a={}){this.getState=e,this.setState=t,this.updateUrl=n,this.sessions=r,this.workspaceSelection=i,this.api=a.api??F}clearSelection(e){this.sessions.clearActiveSession(),this.setState({selectedProject:void 0,selectedWorkspace:void 0,workspaces:[],isLoadingWorkspaces:!1,...oa()}),e?.updateUrl!==!1&&this.updateUrl()}forgetProject(e){this.workspaceSelection.forgetProject(ua(I(this.getState()),e));let t=Object.fromEntries(Object.entries(this.getState().workspacesByProjectId).filter(([t])=>t!==e));this.setState({workspacesByProjectId:t})}async selectProject(e,t){let n=I(this.getState());this.sessions.clearActiveSession(),this.setState({selectedProject:e,selectedWorkspace:void 0,workspaces:[],isLoadingWorkspaces:!0,...oa()});try{let r=await this.api.workspaces(e.id,n);if(I(this.getState())!==n||this.getState().selectedProject?.id!==e.id)return;this.setState({workspaces:r,workspacesByProjectId:{...this.getState().workspacesByProjectId,[e.id]:r},isLoadingWorkspaces:!1});let i=ol(r,{targetWorkspaceId:t?.workspaceId,latestWorkspaceId:this.workspaceSelection.latestWorkspaceId(ua(n,e.id))});i?await this.selectWorkspace(i,{sessionId:t?.sessionId,updateUrl:t?.updateUrl}):t?.updateUrl!==!1&&this.updateUrl()}catch(t){I(this.getState())===n&&this.getState().selectedProject?.id===e.id&&this.setState({error:String(t),isLoadingWorkspaces:!1})}}async selectWorkspace(e,t){let n=I(this.getState());this.workspaceSelection.rememberWorkspace({...e,projectId:ua(n,e.projectId)}),this.sessions.clearActiveSession(),this.setState({selectedWorkspace:e,isLoadingWorkspaces:!1,...oa()});try{let r=Qa(e.path,await this.api.sessions(e.path,n),n);if(I(this.getState())!==n||this.getState().selectedWorkspace?.id!==e.id||this.getState().selectedProject?.id!==e.projectId)return;this.setState({sessions:r});let i=this.sessions.preferredSession(e.path,r,t?.sessionId);i?await this.sessions.selectSession(i,{updateUrl:t?.updateUrl}):t?.updateUrl!==!1&&this.updateUrl()}catch(t){I(this.getState())===n&&this.getState().selectedWorkspace?.id===e.id&&this.setState({error:String(t)})}}async refreshProjectWorkspaces(e){let t=this.getState().projects.find(t=>t.id===e);if(t===void 0)throw Error(`Project not found`);let n=await this.api.workspaces(t.id,I(this.getState()));return this.applyProjectWorkspaces(t.id,n),n}async refreshAfterWorkspaceDeleted(e,t){let n=await this.refreshProjectWorkspaces(e),r=this.getState();if(r.selectedProject?.id!==e||r.selectedWorkspace?.id!==t)return;let i=ll(n);i===void 0?this.clearSelection():await this.selectWorkspace(i)}applyProjectWorkspaces(e,t){let n=this.getState(),r={...n.workspacesByProjectId,[e]:t};n.selectedProject?.id===e?this.setState({workspaces:t,workspacesByProjectId:r}):this.setState({workspacesByProjectId:r})}};function cl(e){return e!==void 0&&e.isGitWorktree&&!e.isMain}function ll(e){return e.find(e=>e.isMain)??e[0]}var ul=`pi-web:machine-navigation:v1`,dl=class{constructor(e=gc()){this.snapshotsByMachine=new _c(ul,gl,e)}latest(e){let t=this.snapshotsByMachine.get(e);return t?.machineId===e?hl(t):void 0}remember(e){this.snapshotsByMachine.set(e.machineId,hl(e))}forget(e){this.snapshotsByMachine.delete(e)}};function fl(e){return{machineId:e,surface:{}}}function pl(e){let t=e.selectedWorkspace!==void 0;return{machineId:e.selectedMachine?.id??`local`,projectId:e.selectedProject?.id,workspaceId:e.selectedWorkspace?.id,sessionId:e.selectedSession?.id,tool:e.workspaceTool,view:e.mainView,surface:{selectedFilePath:t?e.selectedFilePath:void 0,selectedDiffPath:t?e.selectedDiffPath:void 0,selectedTerminalId:t?e.selectedTerminalId:void 0}}}function ml(e){return{machineId:e.machineId,projectId:e.projectId,workspaceId:e.workspaceId,sessionId:e.sessionId,tool:e.tool,view:e.view===`navigation`?void 0:e.view}}function hl(e){return{...e,surface:{...e.surface}}}function gl(e){if(!Sl(e))return;let t=xl(e,`machineId`);if(t===void 0)return;let n=yl(xl(e,`tool`)),r=vl(xl(e,`view`));return{machineId:t,projectId:xl(e,`projectId`),workspaceId:xl(e,`workspaceId`),sessionId:xl(e,`sessionId`),...n===void 0?{}:{tool:n},...r===void 0?{}:{view:r},surface:_l(e.surface)}}function _l(e){return Sl(e)?{selectedFilePath:xl(e,`selectedFilePath`),selectedDiffPath:xl(e,`selectedDiffPath`),selectedTerminalId:xl(e,`selectedTerminalId`)}:{}}function vl(e){return e===`navigation`||e===`chat`?e:yl(e)}function yl(e){return bl(e)?e:void 0}function bl(e){return e!==void 0&&/^[a-z][a-z0-9.-]*:[a-z][a-z0-9.-]*$/u.test(e)}function xl(e,t){let n=e[t];return typeof n==`string`&&n!==``?n:void 0}function Sl(e){return typeof e==`object`&&!!e}var Cl=`pi-web:terminal-selection:v1`,wl=class{constructor(e=gc()){this.terminalIdsByCwd=new _c(Cl,vc,e)}latestTerminalId(e){return this.terminalIdsByCwd.get(e)}rememberTerminal(e,t){this.terminalIdsByCwd.set(e,t)}forgetWorkspace(e){this.terminalIdsByCwd.delete(e)}forgetTerminal(e){for(let[t,n]of this.terminalIdsByCwd.entries())n===e&&this.terminalIdsByCwd.delete(t)}};function Tl(e,t){let n=t?.targetTerminalId;if(n!==void 0&&n!==``)return e.find(e=>e.id===n);let r=t?.latestTerminalId;return r!==void 0&&r!==``?e.find(e=>e.id===r)??e.find(e=>!e.exited)??e[0]:e.find(e=>!e.exited)??e[0]}function El(e){return e.find(e=>!e.exited)??e[0]}var Dl=1200,Ol=[`mod`,`alt`,`shift`],kl=class{constructor(){this.pendingTokens=[]}handle(e,t,n={}){let r=Pl(e);if(r===void 0)return!1;let i=Al(t,n.shortcuts,{enabledOnly:!0}).filter(e=>e.active).map(e=>({action:e.action,tokens:e.tokens}));if(this.pendingTokens.length>0){if(this.handleSequence([...this.pendingTokens,r],i))return!0;if(this.clearPending(),!Fl(r))return!1}else if(!Fl(r))return!1;return this.handleSequence([r],i)}reset(){this.clearPending()}handleSequence(e,t){let n=t.find(t=>Ql(t.tokens,e));return n===void 0?t.some(t=>$l(t.tokens,e))?(this.setPending(e),!0):!1:(this.clearPending(),n.action.run(),!0)}setPending(e){this.clearPending(),this.pendingTokens=e,this.pendingTimer=globalThis.setTimeout(()=>{this.pendingTokens=[],this.pendingTimer=void 0},Dl)}clearPending(){this.pendingTokens=[],this.pendingTimer!==void 0&&(globalThis.clearTimeout(this.pendingTimer),this.pendingTimer=void 0)}};function Al(e,t,n={}){let r=e.flatMap((e,r)=>{if(n.enabledOnly===!0&&e.enabled===!1)return[];let i=Il(e,t,r);return i===void 0?[]:[i]}),i=new Map;for(let e of r)i.set(e.key,[...i.get(e.key)??[],e]);let a=new Map;for(let e of i.values()){let t=[...e].sort(Bl)[0];t!==void 0&&a.set(t.key,t)}let o=[...a.values()].sort(Vl),s=new Map,c=new Map;for(let e of r){let t=a.get(e.key);if(t===void 0)continue;let n=Hl(t,o)??t;c.set(e,n),e!==n&&s.set(n,[...s.get(n)??[],e])}return r.map(e=>{let t=c.get(e),n=t===e,r=t===void 0||n?void 0:zl(t),i=n?[...s.get(e)??[]].sort(Bl).map(zl):[];return{...e,active:n,shadows:i,...r===void 0?{}:{shadowedBy:r}}}).sort((e,t)=>e.order-t.order)}function jl(e){return Gl(e,{requireFirstChordActivator:!0})}function Ml(e){let t=Gl(e,{requireFirstChordActivator:!1});return t.ok?t.tokens:[]}function Nl(e){return Ml(e).map(e=>e.split(`+`).map(Zl).join(`+`)).join(` `)}function Pl(e){if(e.isComposing)return;let t=Yl(e.key);if(t===void 0)return;let n=[];return(e.metaKey||e.ctrlKey)&&n.push(`mod`),e.altKey&&n.push(`alt`),e.shiftKey&&n.push(`shift`),n.push(t),n.join(`+`)}function Fl(e){return e.split(`+`).includes(`mod`)||e.split(`+`).includes(`alt`)}function Il(e,t,n){let r=Ll(e.id,t);if(r===null)return;let i=r??e.shortcut;if(i===void 0||i===``)return;let a=Ml(i),o=a[0];if(!(o===void 0||!Fl(o)))return{action:e,shortcut:a.join(` `),source:r===void 0?`default`:`custom`,tokens:a,key:Rl(a),order:n}}function Ll(e,t){if(!(t===void 0||!Object.hasOwn(t,e)))return t[e]}function Rl(e){return e.join(`\0`)}function zl(e){return{action:e.action,shortcut:e.shortcut,source:e.source}}function Bl(e,t){return Ul(e.source)-Ul(t.source)||Wl(e.action.id,t.action.id)||Wl(e.action.title,t.action.title)||e.order-t.order}function Vl(e,t){return e.tokens.length-t.tokens.length||Bl(e,t)}function Hl(e,t){return t.find(t=>t!==e&&t.tokens.length<e.tokens.length&&$l(e.tokens,t.tokens))}function Ul(e){switch(e){case`custom`:return 0;case`default`:return 1}}function Wl(e,t){return e<t?-1:+(e>t)}function Gl(e,t){let n=e.trim().toLowerCase().replace(/\s*\+\s*/gu,`+`);if(n===``)return{ok:!1,message:`Enter a shortcut, choose None, or reset to the default.`};let r=[],i=n.split(/\s+/u).filter(e=>e!==``);for(let[e,n]of i.entries()){let i=Kl(n);if(!i.ok)return i;if(e===0&&t.requireFirstChordActivator&&!Fl(i.token))return{ok:!1,message:`Shortcuts must start with Ctrl/⌘ or Alt so normal typing is not captured.`};r.push(i.token)}return{ok:!0,shortcut:r.join(` `),tokens:r}}function Kl(e){let t=e.split(`+`).filter(e=>e!==``);if(t.length===0)return{ok:!1,message:`Shortcut chords must include a key.`};let n=new Set,r;for(let e of t){let t=ql(e);if(t!==void 0){if(n.has(t))return{ok:!1,message:`Shortcut has duplicate ${Zl(t)} modifiers.`};n.add(t);continue}let i=Jl(e);if(i===void 0)return{ok:!1,message:`Unsupported shortcut key: ${e}`};if(r!==void 0)return{ok:!1,message:`Each shortcut chord can include only one non-modifier key.`};r=i}return r===void 0?{ok:!1,message:`Shortcut chords must include a key.`}:{ok:!0,token:[...Ol.filter(e=>n.has(e)),r].join(`+`)}}function ql(e){switch(e){case`mod`:case`meta`:case`cmd`:case`command`:case`ctrl`:case`control`:case`primary`:return`mod`;case`alt`:case`option`:case`opt`:return`alt`;case`shift`:return`shift`;default:return}}function Jl(e){let t=Xl(e);if(t!==void 0)return t;if(/^f(?:[1-9]|1[0-9]|2[0-4])$/u.test(e)||e.length===1)return e}function Yl(e){return e===` `?`space`:Jl(e.toLowerCase())}function Xl(e){switch(e){case` `:case`spacebar`:case`space`:return`space`;case`esc`:case`escape`:return`escape`;case`return`:case`enter`:return`enter`;case`del`:case`delete`:return`delete`;case`backspace`:return`backspace`;case`tab`:return`tab`;case`up`:case`arrowup`:return`arrowup`;case`down`:case`arrowdown`:return`arrowdown`;case`left`:case`arrowleft`:return`arrowleft`;case`right`:case`arrowright`:return`arrowright`;case`pageup`:case`pagedown`:case`home`:case`end`:return e;case`+`:case`plus`:return`plus`;case`period`:case`dot`:return`.`;case`comma`:return`,`;case`slash`:return`/`;case`backslash`:return`\\`;case`minus`:return`-`;default:return}}function Zl(e){return e===`mod`?eu()?`⌘`:`Ctrl`:e===`shift`?`Shift`:e===`alt`?eu()?`⌥`:`Alt`:e===`enter`?`Enter`:e===`escape`?`Esc`:e===`space`?`Space`:e===`tab`?`Tab`:e===`backspace`?`Backspace`:e===`delete`?`Delete`:e===`arrowup`?`↑`:e===`arrowdown`?`↓`:e===`arrowleft`?`←`:e===`arrowright`?`→`:e===`pageup`?`PageUp`:e===`pagedown`?`PageDown`:e===`home`?`Home`:e===`end`?`End`:e===`plus`?`+`:/^f(?:[1-9]|1[0-9]|2[0-4])$/u.test(e)||e.length===1?e.toUpperCase():`${e.charAt(0).toUpperCase()}${e.slice(1)}`}function Ql(e,t){return e.length===t.length&&$l(e,t)}function $l(e,t){return t.every((t,n)=>e[n]===t)}function eu(){return typeof navigator<`u`&&navigator.userAgent.toLowerCase().includes(`mac`)}var tu={archiveIdleEnabled:!0,archiveIdleDays:`30`,deleteArchivedEnabled:!1,deleteArchivedDays:`90`};function nu(e){if(!e.archiveIdleEnabled&&!e.deleteArchivedEnabled)return{ok:!1,error:`Enable at least one cleanup action.`};let t={archiveIdleDays:null,deleteArchivedDays:null};if(e.archiveIdleEnabled){let n=du(e.archiveIdleDays,`Archive idle sessions after`);if(typeof n==`string`)return{ok:!1,error:n};t.archiveIdleDays=n}if(e.deleteArchivedEnabled){let n=du(e.deleteArchivedDays,`Delete archived sessions after`);if(typeof n==`string`)return{ok:!1,error:n};t.deleteArchivedDays=n}return{ok:!0,request:t}}function ru(e){return JSON.stringify({archiveIdleDays:e?.archiveIdleDays??null,deleteArchivedDays:e?.deleteArchivedDays??null})}function iu(e){if(!e.canCleanup||e.loading===!0||e.running===!0||e.preview===void 0)return!1;let t=nu(e.draft);return!t.ok||ru(t.request)!==ru(e.previewRequest)?!1:au(e.preview)}function au(e){return e.totals.archiveCount>0||e.totals.deleteCount>0}function ou(e,t){let n=e.projects.map(e=>e.cwd);if(t===void 0)return n;let r=new Set(t);return n.filter(e=>r.has(e))}function su(e,t){let n=new Set(ou(e,t)),r=e.projects.filter(e=>n.has(e.cwd));return{...e,projects:r,totals:r.reduce((e,t)=>({archiveCount:e.archiveCount+t.archiveCount,deleteCount:e.deleteCount+t.deleteCount}),{archiveCount:0,deleteCount:0})}}function cu(e,t){return t(lu(e))}function lu(e){let t=e.totals.archiveCount,n=e.totals.deleteCount,r=[];return t>0&&r.push(`archive ${String(t)} idle ${t===1?`session`:`sessions`}`),n>0&&r.push(`permanently delete ${String(n)} archived ${n===1?`session`:`sessions`}`),`Run cleanup and ${r.length===0?`run cleanup`:r.join(` and `)}?\n\nPermanent deletion only applies to archived sessions and cannot be undone.`}function uu(e){return`Update and restart Pi-Web on ${e??`this machine`} to clean up sessions.`}function du(e,t){let n=e.trim();if(n===``)return`${t} must be set.`;let r=Number(n);return!Number.isInteger(r)||r<0?`${t} must be a non-negative whole number of days.`:r}var fu=`themes:classic`,pu={themeId:`themes:pi-web-dark`,auto:!0},mu=`pi-web-app-theme`,hu=`--pi-bg.--pi-surface.--pi-surface-hover.--pi-terminal-bg.--pi-terminal-text.--pi-border.--pi-border-muted.--pi-text.--pi-text-secondary.--pi-text-bright.--pi-muted.--pi-dim.--pi-accent.--pi-accent-border.--pi-selection-bg.--pi-success.--pi-success-border.--pi-success-bg.--pi-success-surface.--pi-success-ring.--pi-warning.--pi-warning-border.--pi-warning-surface.--pi-danger.--pi-purple.--pi-purple-border.--pi-purple-surface.--pi-overlay.--pi-shadow-soft.--pi-shadow.--pi-shadow-strong.--pi-bg-overlay-soft.--pi-bg-overlay.--pi-success-bg-overlay.--pi-terminal-selection`.split(`.`),gu=/^[a-z][a-z0-9.-]*:[a-z][a-z0-9.-]*$/u;function _u(){try{let e=window.localStorage.getItem(mu);return e===null?void 0:Cu(e)}catch{return}}function vu(e){try{window.localStorage.setItem(mu,JSON.stringify(e))}catch{}}function yu(e){let t=document.documentElement;t.dataset.piWebTheme=e.id,t.style.colorScheme=e.colorScheme;for(let n of hu){let r=e.tokens[n];typeof r==`string`&&r!==``?t.style.setProperty(n,r):t.style.removeProperty(n)}}function bu(e){let t=xu(e.themes,e.fallbackThemeId??`themes:classic`),n=e.themes.find(t=>t.id===e.preference.themeId)??t;if(n===void 0)return{selectedTheme:void 0,activeTheme:void 0,selectedThemePair:void 0,fallbackTheme:t};let r=Su(e.themePairs,n.id);if(!e.preference.auto||r===void 0)return{selectedTheme:n,activeTheme:n,selectedThemePair:r,fallbackTheme:t};let i=e.prefersLight?r.light:r.dark;return{selectedTheme:n,activeTheme:e.themes.find(e=>e.id===i)??n,selectedThemePair:r,fallbackTheme:t}}function xu(e,t=fu){return e.find(e=>e.id===t)??e[0]}function Su(e,t){return e.find(e=>e.light===t||e.dark===t)}function Cu(e){let t=e.trim();if(t!==``)try{let e=JSON.parse(t);return wu(e)?e:void 0}catch{return}}function wu(e){if(!Tu(e))return!1;let t=e.themeId,n=e.auto;return Eu(t)&&typeof n==`boolean`}function Tu(e){return typeof e==`object`&&!!e}function Eu(e){return typeof e==`string`&&gu.test(e)}var Du=`workspace.delete`,Ou=`pi.operation`,ku=`target.workspaceId`;function Au(e){return{...e===void 0?{}:{projectId:e},metadata:{[Ou]:Du}}}function ju(e){let t={};for(let n of e){let e=Pu(n);if(e===void 0)continue;let r=t[e];(r===void 0||n.createdAt.localeCompare(r.createdAt)>=0)&&(t[e]=n)}return t}function Mu(e){return Object.entries(e).filter(([,e])=>Fu(e)).map(([e])=>e)}function Nu(e,t){if(t===void 0)return!1;let n=e.workspaceDeletionRuns[t.id];return n!==void 0&&Fu(n)}function Pu(e){return e.metadata[ku]}function Fu(e){return e.status===`queued`||e.status===`running`}function Iu(){return[{id:`actions.show`,title:`Show Actions`,description:`Open the command palette`,shortcut:`mod+k`,group:`General`,run:e=>{e.openActionPalette()}},{id:`prompt.focus`,title:`Focus Prompt`,description:`Move keyboard focus to the message composer`,shortcut:`mod+g c`,group:`General`,run:e=>{e.focusPrompt()}},{id:`machine.add`,title:`Add Machine`,description:`Register another PI WEB runtime reachable from this gateway`,group:`Machine`,run:e=>e.addMachine()},{id:`machine.refresh`,title:`Refresh Selected Machine`,description:`Check whether the selected PI WEB runtime is online`,group:`Machine`,run:e=>e.refreshSelectedMachine()},{id:`machine.open`,title:`Open Selected Machine PI WEB`,description:`Open the selected remote PI WEB directly in a new tab`,group:`Machine`,enabled:e=>e.state.selectedMachine?.kind===`remote`&&e.state.selectedMachine.baseUrl!==void 0,run:e=>e.openSelectedMachine()},{id:`machine.remove`,title:`Remove Selected Machine`,description:`Remove the selected remote machine from this gateway`,group:`Machine`,enabled:e=>e.state.selectedMachine?.kind===`remote`,run:e=>e.removeSelectedMachine()},{id:`project.add`,title:`Add Project`,group:`Project`,run:e=>e.addProject()},{id:`auth.login`,title:`Configure Provider Authentication`,description:`Run /login without tying authentication to a session`,group:`General`,run:e=>e.configureAuth()},{id:`auth.logout`,title:`Remove Provider Authentication`,description:`Run /logout for stored pi credentials`,group:`General`,run:e=>e.logoutAuth()},{id:`theme.select`,title:`Select Theme`,description:`Choose the PI WEB color theme`,group:`Preferences`,run:e=>{e.openThemePicker()}},{id:`settings.open`,title:`Open Settings`,description:`Manage PI WEB configuration and keyboard shortcuts`,shortcut:`mod+,`,group:`Preferences`,run:e=>{e.piWebUnstable?.openSettings?.()}},{id:`app.reload-page`,title:`Full Page Reload`,description:`Reload the PI WEB browser page`,group:`General`,run:e=>{e.reloadPage()}},{id:`view.chat`,title:`Go to Chat`,shortcut:`mod+1`,group:`Navigation`,run:e=>{e.focusPrompt()}},{id:`view.files`,title:`Go to Files`,shortcut:`mod+2`,group:`Navigation`,enabled:Lu,run:e=>{e.selectMainView(`core:workspace.files`)}},{id:`view.git`,title:`Go to Git`,shortcut:`mod+3`,group:`Navigation`,enabled:Ru,run:e=>{e.selectMainView(`core:workspace.git`)}},{id:`view.terminal`,title:`Go to Terminal`,shortcut:`mod+4`,group:`Navigation`,enabled:Lu,run:e=>{e.selectMainView(`core:workspace.terminal`)}},{id:`workspace.refresh-files`,title:`Refresh Files`,shortcut:`mod+shift+f`,group:`Workspace`,enabled:Lu,run:e=>e.refreshFiles()},{id:`workspace.refresh-git`,title:`Refresh Git`,shortcut:`mod+shift+g`,group:`Workspace`,enabled:Ru,run:e=>e.refreshGit()},{id:`workspace.refresh-current`,title:`Refresh Current Panel`,shortcut:`mod+shift+r`,group:`Workspace`,enabled:Lu,run:e=>e.state.workspaceTool===`core:workspace.git`&&e.state.selectedWorkspace?.isGitRepo===!0?e.refreshGit():e.refreshFiles()},{id:`workspace.delete`,title:`Delete Workspace`,description:`Remove the selected Git worktree`,group:`Workspace`,enabled:zu,run:e=>e.deleteWorkspace()},{id:`session.start`,title:`Start Session`,shortcut:`mod+enter`,group:`Session`,enabled:Lu,run:e=>e.startSession()},{id:`session.archive`,title:`Archive Session`,description:`Archive the selected session`,group:`Session`,enabled:Bu,run:e=>e.archiveSession()},{id:`session.reload`,title:`Reload Session from Disk`,description:`Close and re-open the selected session from its session file. Use /reload in the prompt for Pi runtime resources.`,group:`Session`,enabled:Hu,disabledReason:Uu,run:e=>e.reloadSession()},{id:`session.delete`,title:`Delete New Session`,description:`Delete the selected transient new session`,group:`Session`,enabled:Vu,run:e=>e.deleteCachedNewSession()},{id:`session.stop`,title:`Stop Active Work`,shortcut:`mod+.`,group:`Session`,enabled:e=>e.state.selectedSession!==void 0&&ca(e.state.status,e.state.activity),run:e=>e.stopActiveWork()}]}function Lu(e){return e.state.selectedWorkspace!==void 0}function Ru(e){return e.state.selectedWorkspace?.isGitRepo===!0}function zu(e){let t=e.state.selectedWorkspace;return t!==void 0&&t.isGitWorktree&&!t.isMain&&!Nu(e.state,t)}function Bu(e){return mc(e.state.selectedSession,e.state.status,Wu(e.state))}function Vu(e){return hc(e.state.selectedSession,e.state.status,Wu(e.state))}function Hu(e){return!mc(e.state.selectedSession,e.state.status,Wu(e.state))||Uu(e)!==void 0?!1:!ca(e.state.status,e.state.activity)}function Uu(e){if(mc(e.state.selectedSession,e.state.status,Wu(e.state))&&!ca(e.state.status,e.state.activity))return Gu(e.state,w.sessionsReload,`reload sessions from disk`)}function Wu(e){return fc(e.machineRuntimes[I(e)])}function Gu(e,t,n){let r=e.machineRuntimes[I(e)];if(!(r?.ok===!0&&Rt(r,t)))return`Update and restart Pi-Web on ${e.selectedMachine?.name??`this machine`} to ${n}.`}function Ku(e){return typeof e==`string`?qu(e):g`<span class="tab-custom-icon" aria-hidden="true">${e}</span>`}function qu(e){switch(e){case`navigation`:return Je`
20
- <svg class="tab-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
21
- <circle cx="6" cy="7" r="1.5"></circle>
22
- <path d="M10 7h8"></path>
23
- <circle cx="6" cy="12" r="1.5"></circle>
24
- <path d="M10 12h8"></path>
25
- <circle cx="6" cy="17" r="1.5"></circle>
26
- <path d="M10 17h8"></path>
27
- </svg>
28
- `;case`chat`:return Je`
29
- <svg class="tab-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
30
- <path d="M7 5h10a3 3 0 0 1 3 3v5a3 3 0 0 1-3 3h-6l-5 4v-4H7a3 3 0 0 1-3-3V8a3 3 0 0 1 3-3Z"></path>
31
- <path d="M8 9h8"></path>
32
- <path d="M8 13h5"></path>
33
- </svg>
34
- `;case`files`:return Je`
35
- <svg class="tab-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
36
- <path d="M3 7a2 2 0 0 1 2-2h4l2 2.5h8a2 2 0 0 1 2 2V17a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z"></path>
37
- </svg>
38
- `;case`git`:return Je`
39
- <svg class="tab-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
40
- <circle cx="6" cy="6" r="2"></circle>
41
- <circle cx="18" cy="6" r="2"></circle>
42
- <circle cx="12" cy="18" r="2"></circle>
43
- <path d="M8 6h6"></path>
44
- <path d="M6 8v2a6 6 0 0 0 6 6"></path>
45
- <path d="M18 8v2a6 6 0 0 1-6 6"></path>
46
- </svg>
47
- `;case`terminal`:return Je`
48
- <svg class="tab-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
49
- <rect x="3" y="5" width="18" height="14" rx="2"></rect>
50
- <path d="m7 10 3 3-3 3"></path>
51
- <path d="M12 16h5"></path>
52
- </svg>
53
- `}}var Ju=`10 MB`,Yu=h`
54
- /* Mobile browsers already subtract browser controls from 100dvh; reserve bottom safe area only in standalone PWA modes. */
55
- :host { --pi-app-safe-area-bottom: 0px; position: fixed; top: 0; right: 0; left: 0; display: block; height: 100dvh; box-sizing: border-box; overflow: hidden; padding: env(safe-area-inset-top) env(safe-area-inset-right) var(--pi-app-safe-area-bottom) env(safe-area-inset-left); color: var(--pi-text); background: var(--pi-bg); font: 14px system-ui, sans-serif; }
56
- :host([pwa-display-mode]) { --pi-app-safe-area-bottom: env(safe-area-inset-bottom); }
57
- @media (display-mode: standalone), (display-mode: fullscreen), (display-mode: minimal-ui) {
58
- :host { --pi-app-safe-area-bottom: env(safe-area-inset-bottom); }
59
- }
60
- .shell { --navigation-panel-size: 340px; --workspace-panel-size: minmax(360px, 42vw); --navigation-panel-width: var(--navigation-panel-size); --workspace-panel-width: var(--workspace-panel-size); display: grid; grid-template-columns: var(--navigation-panel-width) 1px minmax(320px, 1fr) 1px var(--workspace-panel-width); height: 100%; min-height: 0; }
61
- aside { grid-column: 1; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
62
- aside app-navigation-panel { flex: 1 1 auto; min-height: 0; }
63
- header { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px; border-bottom: 1px solid var(--pi-border); }
64
- .header-actions { display: flex; align-items: center; gap: 8px; }
65
- project-list, workspace-list { flex: 0 0 auto; max-height: 26%; min-height: 0; overflow: hidden; border-bottom: 1px solid var(--pi-border-muted); }
66
- session-list { flex: 1 1 auto; min-height: 0; overflow: hidden; }
67
- main { grid-column: 3; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
68
- .context-bar { position: relative; flex: 0 0 auto; min-width: 0; display: none; align-items: center; gap: 0; padding: 6px 0; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-bg); }
69
- .context-bar::before, .context-bar::after { content: ""; position: absolute; top: 0; bottom: 0; z-index: 2; width: 20px; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
70
- .context-bar::before { left: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
71
- .context-bar::after { right: 0; background: linear-gradient(270deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
72
- .context-bar.can-scroll-left::before, .context-bar.can-scroll-right::after { opacity: 1; }
73
- .context-bar-label { display: none; }
74
- .context-items { flex: 1 1 auto; min-width: 0; display: flex; align-items: stretch; gap: 5px; margin: 0; padding: 0 8px; list-style: none; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scroll-padding-inline: 8px; scrollbar-width: thin; }
75
- .context-bar.has-context-actions .context-items { padding-right: 52px; scroll-padding-inline: 8px 52px; }
76
- .context-item { flex: 0 0 auto; min-width: 0; display: flex; }
77
- .context-actions { position: absolute; top: 6px; right: 0; bottom: 6px; z-index: 3; display: flex; align-items: center; padding: 0 8px 0 0; pointer-events: none; }
78
- .context-actions::after { content: ""; position: absolute; top: 0; right: 0; bottom: 0; z-index: 0; width: 26px; background: var(--pi-bg); pointer-events: none; }
79
- .context-chip { flex: 0 0 auto; min-width: 0; display: inline-flex; align-items: baseline; gap: 5px; border: 1px solid var(--pi-border-muted); border-radius: 999px; background: var(--pi-surface); color: var(--pi-text); padding: 4px 8px; font: inherit; text-align: left; }
80
- .context-chip:hover { background: var(--pi-surface-hover); }
81
- .context-chip:focus-visible { outline: 2px solid var(--pi-accent); outline-offset: 2px; }
82
- .context-chip.empty { border-style: dashed; color: var(--pi-muted); }
83
- .context-kind { display: none; }
84
- .context-value { min-width: 0; overflow: visible; text-overflow: clip; white-space: nowrap; }
85
- app-mobile-main-tabs { display: none; }
86
- .mobile-tabs-frame { position: relative; display: none; flex: 0 0 auto; min-width: 0; border-bottom: 1px solid var(--pi-border); background: var(--pi-bg); }
87
- .mobile-tabs-frame::before, .mobile-tabs-frame::after { content: ""; position: absolute; top: 0; bottom: 0; z-index: 2; width: 20px; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
88
- .mobile-tabs-frame::before { left: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
89
- .mobile-tabs-frame::after { right: 0; background: linear-gradient(270deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
90
- .mobile-tabs-frame.can-scroll-left::before, .mobile-tabs-frame.can-scroll-right::after { opacity: 1; }
91
- .mobile-tabs { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; padding: 8px; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: thin; }
92
- .mobile-tabs button { flex: 0 0 auto; white-space: nowrap; }
93
- .mobile-navigation-tab, .mobile-navigation-panel { display: none; }
94
- .mobile-tabs button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
95
- .tab-badge { display: inline-block; min-width: 14px; margin-left: 4px; border: 1px solid var(--pi-success-border); border-radius: 999px; background: var(--pi-success-surface); color: var(--pi-success); padding: 0 5px; font-size: 11px; line-height: 16px; text-align: center; }
96
- .navigation-panel-edge, .workspace-panel-edge { min-width: 0; min-height: 0; display: flex; align-items: center; justify-content: center; overflow: visible; background: var(--pi-border-muted); z-index: 2; }
97
- .navigation-panel-edge { grid-column: 2; }
98
- .workspace-panel-edge { grid-column: 4; }
99
- .navigation-panel-edge-button, .workspace-panel-edge-button { position: relative; z-index: 1; box-sizing: border-box; display: grid; place-items: center; width: 18px; height: 48px; padding: 0; border: 1px solid var(--pi-border-muted); border-radius: 999px; background: var(--pi-bg); color: var(--pi-muted); opacity: .75; cursor: pointer; }
100
- .navigation-panel-edge-button:hover, .navigation-panel-edge-button:focus-visible, .workspace-panel-edge-button:hover, .workspace-panel-edge-button:focus-visible { color: var(--pi-text); background: var(--pi-surface-hover); opacity: 1; }
101
- .shell.navigation-panel-collapsed .navigation-panel-edge-button { transform: translateX(calc(50% - .5px)); }
102
- .shell.workspace-panel-collapsed .workspace-panel-edge-button { transform: translateX(calc(-50% + .5px)); }
103
- .navigation-panel-edge-icon, .workspace-panel-edge-icon { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
104
- workspace-panel { grid-column: 5; min-width: 0; min-height: 0; overflow: hidden; }
105
- @media (min-width: 1181px) {
106
- .shell.navigation-panel-collapsed { --navigation-panel-width: 0px; }
107
- .shell.navigation-panel-collapsed > aside { display: none; }
108
- .shell.workspace-panel-collapsed { --workspace-panel-width: 0px; }
109
- .shell.workspace-panel-collapsed > workspace-panel { display: none; }
110
- }
111
- @media (max-width: 1180px) {
112
- .shell { grid-template-columns: var(--navigation-panel-width) 1px minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
113
- .shell.navigation-panel-collapsed { --navigation-panel-width: 0px; }
114
- .shell.navigation-panel-collapsed > aside { display: none; }
115
- aside { grid-row: 1 / 3; }
116
- .navigation-panel-edge { grid-row: 1 / 3; }
117
- main { grid-column: 3; grid-row: 1 / 3; }
118
- app-mobile-main-tabs { display: block; flex: 0 0 auto; min-width: 0; }
119
- .mobile-tabs-frame { display: flex; }
120
- .shell.workspace-view main { grid-row: 1; min-height: auto; }
121
- .shell.workspace-view > workspace-panel { grid-column: 3; grid-row: 2; display: flex; border-left: 0; }
122
- .shell:not(.workspace-view) > workspace-panel { display: none; }
123
- .workspace-panel-edge { display: none; }
124
- main.workspace-view chat-view, main.workspace-view prompt-editor, main.workspace-view status-bar,
125
- main.workspace-view .empty { display: none; }
126
- main.workspace-view { overflow: hidden; }
127
- }
128
- @media (max-width: 760px) {
129
- .shell { grid-template-columns: minmax(0, 1fr); }
130
- aside, .navigation-panel-edge { display: none; }
131
- main, .shell.workspace-view > workspace-panel { grid-column: 1; }
132
- .context-bar { display: flex; }
133
- .mobile-navigation-tab { display: block; }
134
- main.navigation-view chat-view, main.navigation-view prompt-editor, main.navigation-view status-bar,
135
- main.navigation-view .empty { display: none; }
136
- main.navigation-view .mobile-navigation-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
137
- main.navigation-view .mobile-navigation-panel app-navigation-panel { flex: 1 1 auto; min-height: 0; }
138
- main.navigation-view .mobile-navigation-panel project-list,
139
- main.navigation-view .mobile-navigation-panel workspace-list,
140
- main.navigation-view .mobile-navigation-panel session-list { flex: 1 1 auto; max-height: none; min-height: 0; overflow: hidden; }
141
- main.navigation-view .mobile-navigation-panel project-list[collapsed],
142
- main.navigation-view .mobile-navigation-panel workspace-list[collapsed],
143
- main.navigation-view .mobile-navigation-panel session-list[collapsed] { flex: 0 0 auto; min-height: auto; overflow: hidden; }
144
- }
145
- status-bar { flex: 0 0 auto; }
146
- chat-view { flex: 1 1 auto; min-height: 0; overflow: hidden; }
147
- prompt-editor { flex: 0 0 auto; }
148
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
149
- .empty { margin: auto; color: var(--pi-muted); }
150
- .error { padding: 10px 16px; border-bottom: 1px solid var(--pi-border); color: var(--pi-danger); }
151
- `,Xu=h`
152
- :host { display: flex; flex-direction: column; min-height: 0; color: var(--pi-text); background: var(--pi-bg); font: 13px system-ui, sans-serif; container-type: inline-size; }
153
- header { flex: 0 0 auto; min-width: 0; border-bottom: 1px solid var(--pi-border); }
154
- .workspace-header-scroll-frame { position: relative; min-width: 0; background: var(--pi-bg); }
155
- .workspace-header-scroll-frame::before, .workspace-header-scroll-frame::after { content: ""; position: absolute; top: 0; bottom: 0; z-index: 2; width: 18px; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
156
- .workspace-header-scroll-frame::before { left: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
157
- .workspace-header-scroll-frame::after { right: 0; background: linear-gradient(270deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
158
- .workspace-header-scroll-frame.can-scroll-left::before, .workspace-header-scroll-frame.can-scroll-right::after { opacity: 1; }
159
- .workspace-header-strip { display: flex; justify-content: space-between; align-items: center; gap: 8px; min-width: 0; padding: 8px; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: thin; }
160
- .tabs { flex: 0 0 auto; display: flex; gap: 6px; align-items: center; }
161
- .tabs button { flex: 0 0 auto; white-space: nowrap; }
162
- .tabs button.icon-tab { min-width: 34px; }
163
- button { display: inline-flex; align-items: center; gap: 5px; border: 1px solid var(--pi-border); border-radius: 7px; background: var(--pi-surface); color: var(--pi-text); padding: 5px 7px; cursor: pointer; }
164
- button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
165
- .tab-icon { flex: 0 0 auto; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
166
- .tab-custom-icon { flex: 0 0 auto; width: 16px; height: 16px; display: inline-grid; place-items: center; color: currentColor; pointer-events: none; }
167
- .tab-custom-icon svg { width: 16px; height: 16px; pointer-events: none; }
168
- .tab-label { min-width: 0; }
169
- .tab-badge { flex: 0 0 auto; display: inline-block; min-width: 14px; border: 1px solid var(--pi-success-border); border-radius: 999px; background: var(--pi-success-surface); color: var(--pi-success); padding: 0 5px; font-size: 11px; line-height: 16px; text-align: center; }
170
- @container (max-width: 430px) {
171
- .tabs button.icon-tab { justify-content: center; padding-inline: 7px; }
172
- .tabs button.icon-tab .tab-label { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
173
- }
174
- .panel-content { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: auto; }
175
- .empty-state { box-sizing: border-box; width: min(100%, 380px); margin: auto; padding: 24px; display: grid; gap: 8px; color: var(--pi-muted); text-align: center; }
176
- .empty-state h2 { margin: 0; color: var(--pi-text); font-size: 15px; line-height: 1.3; }
177
- .empty-state p { margin: 0; line-height: 1.45; }
178
- small, .muted { color: var(--pi-muted); }
179
- @media (max-width: 1180px) { header { display: none; } }
180
- .workspace-label { min-width: 0; display: inline-flex; align-items: baseline; gap: 5px; max-width: 100%; overflow: hidden; white-space: nowrap; }
181
- .workspace-label-base, .workspace-label-item, .workspace-label-render { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
182
- .workspace-label-item, .workspace-label-render, .workspace-label-separator { color: var(--pi-muted); }
183
- .workspace-label-link { color: var(--pi-accent); text-decoration: none; }
184
- .workspace-label-link:hover, .workspace-label-link:focus { text-decoration: underline; }
185
- .toolbar { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; padding: 8px; border-bottom: 1px solid var(--pi-border-muted); }
186
- .toolbar button { margin-left: auto; }
187
- .stale { border: 1px solid var(--pi-warning-border); border-radius: 999px; color: var(--pi-warning); padding: 1px 6px; font-size: 12px; }
188
- .split { flex: 1 1 auto; min-height: 0; display: grid; grid-template-rows: minmax(160px, 34%) minmax(0, 1fr); }
189
- .list { min-height: 0; overflow: auto; border-bottom: 1px solid var(--pi-border); padding: 6px; }
190
- .row { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 4px; width: 100%; border: 0; border-radius: 5px; background: transparent; text-align: left; padding: 4px 6px 4px calc(6px + var(--depth, 0) * 14px); }
191
- .row:hover, .row.selected { background: var(--pi-selection-bg); }
192
- .row span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
193
- .summary { margin: 4px 6px 8px; color: var(--pi-muted); }
194
- .viewer { min-height: 0; overflow: auto; display: flex; flex-direction: column; }
195
- .diffs { flex: 1 1 auto; min-height: 0; overflow: auto; display: grid; grid-template-rows: minmax(120px, 1fr) minmax(120px, 1fr); }
196
- .diffs.single { grid-template-rows: minmax(0, 1fr); }
197
- .diff-section { min-height: 0; display: flex; flex-direction: column; border-bottom: 1px solid var(--pi-border); }
198
- .diff-section:last-child { border-bottom: 0; }
199
- .viewer-header { position: sticky; top: 0; display: flex; justify-content: space-between; gap: 8px; padding: 8px; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-bg); }
200
- .viewer-header strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
201
- code-viewer, unified-diff-viewer { flex: 1 1 auto; min-height: 0; }
202
- .image-preview { flex: 1 1 auto; min-height: 0; box-sizing: border-box; display: flex; align-items: center; justify-content: center; overflow: auto; padding: 16px; }
203
- .image-preview img { display: block; max-width: 100%; max-height: 100%; object-fit: contain; border: 1px solid var(--pi-border-muted); border-radius: 8px; background-color: var(--pi-surface); background-image: linear-gradient(45deg, color-mix(in srgb, var(--pi-border-muted) 45%, transparent) 25%, transparent 25%), linear-gradient(-45deg, color-mix(in srgb, var(--pi-border-muted) 45%, transparent) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, color-mix(in srgb, var(--pi-border-muted) 45%, transparent) 75%), linear-gradient(-45deg, transparent 75%, color-mix(in srgb, var(--pi-border-muted) 45%, transparent) 75%); background-position: 0 0, 0 8px, 8px -8px, -8px 0; background-size: 16px 16px; box-shadow: 0 8px 24px var(--pi-shadow-soft); }
204
- pre { margin: 0; padding: 10px; overflow: auto; font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
205
- p { margin: 10px; }
206
- `,Zu=h`
207
- :host { display: flex; flex-direction: column; min-height: 0; overflow: hidden; color: var(--pi-text); font: 14px system-ui, sans-serif; }
208
- :host([collapsed]) { flex: 0 0 auto; min-height: auto; overflow: hidden; }
209
- section { box-sizing: border-box; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding: 10px; }
210
- h2 { flex: 0 0 auto; display: flex; justify-content: space-between; align-items: center; gap: 8px; margin: 0 0 8px; color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
211
- .list-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
212
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
213
- section > button { display: block; width: 100%; text-align: left; margin: 6px 0; }
214
- .subheading { margin-top: 14px; }
215
- .section-toggle { display: flex; flex: 1 1 auto; min-width: 0; align-items: center; justify-content: space-between; gap: 8px; width: 100%; border: 0; background: transparent; color: inherit; padding: 0; font: inherit; text-align: left; text-transform: inherit; }
216
- .section-toggle span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
217
- .section-title { display: grid; gap: 2px; min-width: 0; }
218
- .section-toggle .section-selected { display: block; color: var(--pi-text); font-size: 12px; font-weight: 600; line-height: 1.25; text-transform: none; }
219
- .section-toggle .section-count { flex: 0 0 auto; display: inline; color: var(--pi-muted); font-size: inherit; }
220
- .section-toggle small { display: inline; color: inherit; font-size: inherit; }
221
- .action-row { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; margin: 6px 0; cursor: pointer; }
222
- .action-row:focus-visible { outline: 2px solid var(--pi-accent); outline-offset: 2px; border-radius: 8px; }
223
- .action-row.selected .action-main, .action-row.selected .action-menu-toggle { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
224
- .action-row.archived .action-main { color: var(--pi-muted); }
225
- .action-main { position: relative; box-sizing: border-box; min-width: 0; width: 100%; border: 1px solid var(--pi-border); border-top-right-radius: 0; border-bottom-right-radius: 0; border-top-left-radius: 8px; border-bottom-left-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 22px 7px calc(9px + var(--depth, 0) * 16px); text-align: left; }
226
- .action-name { display: -webkit-box; max-height: 2.5em; overflow: hidden; overflow-wrap: anywhere; line-height: 1.25; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
227
- .action-row:not(.selected):hover .action-main { background: var(--pi-surface-hover); }
228
- .workspace-row .action-main { border-radius: 8px 0 0 8px; }
229
- .workspace-primary { min-width: 0; display: flex; align-items: baseline; gap: 6px; }
230
- .workspace-primary-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
231
- .workspace-status { flex: 0 0 auto; color: var(--pi-warning); font-size: 12px; }
232
- .workspace-secondary { margin-top: 3px; }
233
- .workspace-menu-panel { width: max-content; min-width: min(120px, calc(100vw - 16px)); padding: 8px; }
234
- .workspace-menu-actions { margin: 0 0 8px; padding-bottom: 8px; border-bottom: 1px solid var(--pi-border-muted); }
235
- .workspace-menu-actions button.danger { color: var(--pi-danger); }
236
- .workspace-menu-actions button.danger:hover, .workspace-menu-actions button.danger:focus { background: color-mix(in srgb, var(--pi-danger) 14%, transparent); }
237
- .workspace-menu-details { display: grid; gap: 6px; margin: 0; }
238
- .workspace-detail-row { display: grid; grid-template-columns: minmax(58px, max-content) minmax(0, 1fr); gap: 8px; align-items: baseline; }
239
- .workspace-detail-row dt { color: var(--pi-muted); font-size: 12px; white-space: normal; }
240
- .workspace-detail-row dd { min-width: 0; margin: 0; overflow-wrap: anywhere; white-space: normal; }
241
- .tree-marker { color: var(--pi-dim); margin-right: 5px; }
242
- .badge { display: inline-block; margin-left: 5px; border: 1px solid var(--pi-border); border-radius: 999px; color: var(--pi-muted); padding: 0 5px; font-size: 11px; font-weight: 400; }
243
- .action-activity { position: absolute; top: 5px; right: 6px; z-index: 1; display: grid; place-items: center; width: 10px; height: 10px; }
244
- .action-activity .activity-indicator { margin: 0; vertical-align: 0; }
245
- .activity-indicator { display: inline-block; width: 7px; height: 7px; margin-right: 6px; background: var(--pi-success); animation: pulse 1s ease-in-out infinite; vertical-align: 1px; }
246
- .activity-indicator.session { border-radius: 50%; background: var(--pi-success); }
247
- .activity-indicator.terminal { border-radius: 2px; background: var(--pi-accent); }
248
- /* Client-side sending (upload in flight); distinct from server activity, which propagates to workspace/machine rows. */
249
- .activity-indicator.sending { border-radius: 50%; background: var(--pi-warning); }
250
- .action-menu { position: relative; align-self: stretch; }
251
- .action-menu-toggle { display: grid; place-items: center; height: 100%; min-width: 32px; padding: 0; color: var(--pi-muted); border-left: 0; border-top-left-radius: 0; border-bottom-left-radius: 0; }
252
- .action-menu-toggle:hover { color: var(--pi-text); background: var(--pi-surface-hover); }
253
- .action-menu-panel { position: fixed; z-index: 50; box-sizing: border-box; min-width: min(120px, calc(100vw - 16px)); overflow: auto; padding: 4px; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); box-shadow: 0 8px 24px var(--pi-shadow); overflow-wrap: anywhere; }
254
- .action-menu-panel button { display: block; width: 100%; text-align: left; white-space: normal; overflow-wrap: anywhere; border: 0; background: transparent; color: var(--pi-text); }
255
- .action-menu-panel button:hover { background: var(--pi-selection-bg); }
256
- button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
257
- button:disabled { opacity: .5; cursor: not-allowed; }
258
- small { display: block; color: var(--pi-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
259
- .workspace-label { min-width: 0; display: inline-flex; align-items: baseline; gap: 5px; max-width: 100%; overflow: hidden; white-space: nowrap; }
260
- .workspace-label-base, .workspace-label-item, .workspace-label-render { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
261
- .workspace-label-item, .workspace-label-render, .workspace-label-separator { color: var(--pi-muted); }
262
- .workspace-label-link { color: var(--pi-accent); text-decoration: none; }
263
- .workspace-label-link:hover, .workspace-label-link:focus { text-decoration: underline; }
264
- .workspace-detail-row .workspace-label { overflow: visible; white-space: normal; flex-wrap: wrap; }
265
- .workspace-detail-row .workspace-label-base, .workspace-detail-row .workspace-label-item, .workspace-detail-row .workspace-label-render { overflow: visible; text-overflow: clip; overflow-wrap: anywhere; white-space: normal; }
266
- @keyframes pulse { 0%, 100% { transform: scale(.75); opacity: .55; } 50% { transform: scale(1.2); opacity: 1; } }
267
- `,Qu=h`
268
- :host { position: relative; z-index: 0; display: flex; flex-direction: column; min-height: 0; overflow: hidden; color: var(--pi-text); font: 14px system-ui, sans-serif; }
269
- .chat-wrap { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; }
270
- .session-warnings { flex: 0 0 auto; display: grid; gap: 8px; max-height: 40%; overflow-y: auto; box-sizing: border-box; padding: 10px 16px; border-bottom: 1px solid var(--pi-border); background: var(--pi-bg-overlay); }
271
- .session-warning { position: relative; display: grid; gap: 4px; box-sizing: border-box; padding: 10px 34px 10px 12px; border: 1px solid var(--pi-warning-border); border-radius: 10px; background: var(--pi-warning-surface); color: var(--pi-text); }
272
- .session-warning.error { border-color: var(--pi-danger); background: color-mix(in srgb, var(--pi-danger) 12%, var(--pi-surface)); }
273
- .session-warning.info { border-color: var(--pi-accent-border); background: var(--pi-selection-bg); }
274
- .session-warning-head { display: flex; align-items: center; gap: 8px; min-height: 16px; }
275
- .session-warning-icon { flex: 0 0 auto; font-size: 14px; line-height: 1.4; }
276
- .session-warning-body { min-width: 0; display: grid; gap: 3px; }
277
- .session-warning-message { margin: 0; overflow-wrap: anywhere; }
278
- .session-warning-path { margin: 0; color: var(--pi-muted); font-size: 12px; font-family: var(--pi-mono, ui-monospace, monospace); overflow-wrap: anywhere; }
279
- .session-warning-source { color: var(--pi-muted); font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
280
- .session-warning-dismiss { position: absolute; top: 6px; right: 6px; display: inline-grid; place-items: center; width: 22px; height: 22px; padding: 0; border: 1px solid var(--pi-border); border-radius: 6px; background: var(--pi-surface); color: var(--pi-muted); font: 15px/1 system-ui, sans-serif; cursor: pointer; }
281
- .session-warning-dismiss:hover, .session-warning-dismiss:focus-visible { color: var(--pi-text-bright); border-color: var(--pi-accent); background: var(--pi-bg-overlay); }
282
- .session-warning-dismiss:focus-visible { outline: 1px solid var(--pi-border); outline-offset: 2px; }
283
- .chat { height: 100%; min-height: 0; overflow: auto; overflow-anchor: none; padding: 26px 16px 64px; box-sizing: border-box; }
284
- .scroll-marker { display: block; height: 0; overflow: hidden; pointer-events: none; }
285
- .activity-dock { position: absolute; left: 16px; right: 16px; bottom: 12px; z-index: 20; display: flex; align-items: center; gap: 8px; min-width: 0; box-sizing: border-box; border: 1px solid var(--pi-border); border-radius: 999px; background: var(--pi-bg-overlay); color: var(--pi-muted); padding: 8px 12px; font-size: 13px; pointer-events: none; box-shadow: 0 8px 28px var(--pi-shadow); backdrop-filter: blur(6px); }
286
- .activity-dock.active { border-color: var(--pi-success-border); color: var(--pi-success); background: var(--pi-success-bg-overlay); }
287
- .activity-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
288
- .dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; opacity: .45; flex: 0 0 auto; }
289
- .activity-dock.active .dot { animation: pulse 1s ease-in-out infinite; opacity: 1; }
290
- .msg { max-width: 100%; min-width: 0; box-sizing: border-box; margin: 0 0 14px; padding: 12px; border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); overflow: visible; }
291
- .msg.assistant, .msg.tool-image-output { background: var(--pi-surface); }
292
- .msg.user { border-color: var(--pi-accent-border); background: var(--pi-selection-bg); }
293
- .msg.tool { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); color: var(--pi-warning); }
294
- .msg.tool-execution-shell { padding: 0; border: 0; background: transparent; color: var(--pi-text); }
295
- .msg.system { color: var(--pi-danger); }
296
- .msg.bash { border-color: var(--pi-success); background: var(--pi-success-bg); }
297
- .msg.skill { border-color: var(--pi-purple-border); background: var(--pi-purple-surface); }
298
- .msg.event-group { padding: 0; border-color: var(--pi-border); background: var(--pi-bg); color: var(--pi-muted); }
299
- .msg.event-group.live { border-color: var(--pi-success-border); background: var(--pi-success-bg); }
300
- .msg.event-group > summary { position: sticky; top: -26px; z-index: 5; display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: 9px 9px 0 0; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-bg); color: var(--pi-muted); }
301
- .msg.event-group.live > summary { border-bottom-color: var(--pi-success-border); background: var(--pi-success-bg); color: var(--pi-success); }
302
- .msg.event-group > summary .label { margin: 0; }
303
- .group-body { padding: 0 12px 12px; }
304
- .chat-image { display: block; max-width: 100%; max-height: 320px; margin: 8px 0 0; border: 1px solid var(--pi-border-muted); border-radius: 8px; object-fit: contain; cursor: zoom-in; }
305
- .chat-image:focus-visible { outline: 2px solid var(--pi-accent, var(--pi-success-border)); outline-offset: 2px; }
306
- dialog.image-zoom { position: fixed; inset: 0; margin: auto; max-width: calc(96vw - env(safe-area-inset-left) - env(safe-area-inset-right)); max-height: calc(96vh - env(safe-area-inset-top) - env(safe-area-inset-bottom)); width: fit-content; height: fit-content; padding: 0; border: none; background: transparent; overflow: visible; }
307
- dialog.image-zoom[open] { display: flex; }
308
- dialog.image-zoom::backdrop { background: rgba(0, 0, 0, 0.8); }
309
- .image-zoom-full { display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; border-radius: 8px; object-fit: contain; cursor: zoom-out; }
310
- .image-zoom-close { position: absolute; top: max(8px, env(safe-area-inset-top)); right: max(8px, env(safe-area-inset-right)); display: inline-grid; place-items: center; width: 28px; height: 28px; padding: 0; font: 16px/1 system-ui, sans-serif; color: var(--pi-muted); background: color-mix(in srgb, var(--pi-surface) 88%, transparent); border: 1px solid var(--pi-border); border-radius: 6px; cursor: pointer; }
311
- .image-zoom-close:hover, .image-zoom-close:focus-visible { color: var(--pi-text-bright); border-color: var(--pi-accent); }
312
- .image-zoom-close:focus-visible { outline: 1px solid var(--pi-border); outline-offset: 2px; }
313
- .group-msg { max-width: 100%; min-width: 0; box-sizing: border-box; padding: 10px 0; border-top: 1px solid var(--pi-border-muted); color: var(--pi-text); overflow: visible; }
314
- .group-msg.tool { color: var(--pi-warning); }
315
- .group-msg.tool-execution-shell { color: var(--pi-text); }
316
- .group-msg.system { color: var(--pi-danger); }
317
- .group-msg.bash { color: var(--pi-success); }
318
- .history-boundary { position: relative; z-index: 5; display: grid; gap: 3px; justify-items: center; margin: 0 0 14px; color: var(--pi-muted); font-size: 12px; text-align: center; }
319
- .history-load-button { border: 1px solid var(--pi-border); border-radius: 999px; background: var(--pi-surface); color: var(--pi-text-secondary); padding: 5px 12px; font: 12px system-ui, sans-serif; cursor: pointer; }
320
- .history-load-button:hover, .history-load-button:focus { border-color: var(--pi-accent); color: var(--pi-text-bright); }
321
- .history-load-button:disabled { cursor: default; opacity: .55; }
322
- .queued-messages { max-width: 100%; min-width: 0; box-sizing: border-box; display: grid; gap: 8px; margin: 0 0 14px; padding: 12px; border: 1px solid var(--pi-warning-border); border-radius: 10px; background: var(--pi-warning-surface); color: var(--pi-text); overflow: hidden; }
323
- .queued-header { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 10px; }
324
- .queued-heading { min-width: 0; flex: 1 1 180px; display: grid; gap: 2px; }
325
- .queued-heading strong { color: var(--pi-warning); }
326
- .queued-heading small { color: var(--pi-muted); }
327
- .queued-clear-button { flex: 0 0 auto; border: 1px solid var(--pi-warning-border); border-radius: 999px; background: var(--pi-surface); color: var(--pi-warning); padding: 5px 10px; font: 12px system-ui, sans-serif; white-space: nowrap; cursor: pointer; }
328
- .queued-clear-button:hover, .queued-clear-button:focus { border-color: var(--pi-warning); color: var(--pi-text-bright); }
329
- .queued-message { display: grid; gap: 4px; padding-top: 8px; border-top: 1px solid var(--pi-border); }
330
- .queued-message:first-of-type { padding-top: 0; border-top: 0; }
331
- .queued-kind { color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
332
- .session-activity { max-width: 100%; min-width: 0; box-sizing: border-box; display: grid; gap: 4px; margin: 0 0 14px; padding: 12px; border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); color: var(--pi-text); overflow: hidden; }
333
- .session-activity.compacting { border-color: var(--pi-purple-border); background: var(--pi-purple-surface); }
334
- .session-activity strong { color: var(--pi-purple); }
335
- .session-activity span, .session-activity small { color: var(--pi-muted); }
336
- .history-boundary small { color: var(--pi-dim); }
337
- .msg-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 22px; margin-bottom: 8px; }
338
- .msg > .msg-header { position: sticky; top: -26px; z-index: 4; margin: -12px -12px 8px; padding: 7px 10px 6px; border-radius: 9px 9px 0 0; border-bottom: 1px solid color-mix(in srgb, var(--pi-border-muted) 35%, transparent); background: var(--pi-surface); box-shadow: 0 8px 18px var(--pi-shadow-soft); }
339
- .msg.user > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-accent-border) 35%, transparent); background: var(--pi-selection-bg); }
340
- .msg.assistant > .msg-header .label, .msg.tool-image-output > .msg-header .label { color: var(--pi-text-secondary); }
341
- .msg.user > .msg-header .label { color: var(--pi-accent); }
342
- .msg.tool > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-warning-border) 35%, transparent); background: var(--pi-warning-surface); }
343
- .msg.bash > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-success) 35%, transparent); background: var(--pi-success-bg); }
344
- .msg.skill > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-purple-border) 35%, transparent); background: var(--pi-purple-surface); }
345
- .group-msg > .msg-header { position: sticky; top: -26px; z-index: 4; margin: -10px 0 8px; padding: 7px 0 6px; border-bottom: 1px solid color-mix(in srgb, var(--pi-border-muted) 35%, transparent); background: var(--pi-bg); }
346
- .msg-header-trailing { min-width: 0; flex: 1 1 auto; display: inline-flex; align-items: center; justify-content: flex-end; gap: 8px; }
347
- .msg-actions { flex: 0 0 auto; display: inline-flex; gap: 6px; opacity: 0; transition: opacity .12s ease; }
348
- .msg-action { display: inline-grid; place-items: center; width: 24px; height: 24px; border: 1px solid var(--pi-border); border-radius: 6px; background: var(--pi-surface); color: var(--pi-muted); padding: 0; font: 14px system-ui, sans-serif; line-height: 1; cursor: pointer; }
349
- .msg-action:hover, .msg-action:focus { color: var(--pi-text); border-color: var(--pi-accent); }
350
- .msg:hover > .msg-header .msg-actions, .msg:focus-within > .msg-header .msg-actions, .group-msg:hover > .msg-header .msg-actions, .group-msg:focus-within > .msg-header .msg-actions { opacity: 1; }
351
- .label { display: block; color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
352
- .msg-header .label { margin: 0; }
353
- .msg-meta { min-width: 0; opacity: .28; border: 0; background: transparent; color: var(--pi-dim); padding: 0; font: 11px system-ui, sans-serif; text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity .12s ease; cursor: pointer; user-select: text; -webkit-user-select: text; }
354
- .msg:hover > .msg-header .msg-meta, .msg:focus-within > .msg-header .msg-meta, .group-msg:hover > .msg-header .msg-meta, .group-msg:focus-within > .msg-header .msg-meta, .msg-meta:focus, .msg-meta.expanded { opacity: 1; }
355
- .msg-meta.expanded { flex: 1 1 auto; max-width: 100%; white-space: normal; overflow: visible; overflow-wrap: anywhere; text-overflow: clip; }
356
- .msg-meta:focus { outline: 1px solid var(--pi-border); outline-offset: 3px; border-radius: 4px; }
357
- @media (hover: none) {
358
- .msg-actions { opacity: 1; }
359
- .msg-meta { opacity: .75; max-width: 26px; }
360
- .msg-meta:not(.expanded) { display: inline-grid; width: 26px; height: 22px; place-items: center; font-size: 0; text-overflow: clip; }
361
- .msg-meta::before { content: "ⓘ"; font-size: 13px; }
362
- .msg-meta.expanded { opacity: 1; max-width: 100%; }
363
- .msg-meta.expanded::before { content: ""; }
364
- }
365
- formatted-text.part { display: block; }
366
- formatted-text.part, .queued-message formatted-text { text-align: start; unicode-bidi: plaintext; }
367
- .part { max-width: 100%; min-width: 0; box-sizing: border-box; overflow: visible; }
368
- .part + .part { margin-top: 10px; }
369
- .tool-line { color: var(--pi-warning); }
370
- .summary { color: var(--pi-muted); margin-left: 6px; }
371
- .part:is(details) { border-top: 1px solid var(--pi-border); padding-top: 8px; }
372
- .part > formatted-text { display: block; max-width: 100%; min-width: 0; overflow: visible; }
373
- .skill-invocation, .skill-read { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); padding: 8px 10px; }
374
- .skill-invocation > summary, .skill-read > strong { color: var(--pi-purple); }
375
- .skill-invocation > small, .skill-read > small { display: block; margin: 6px 0 0; color: var(--pi-muted); }
376
- summary { cursor: pointer; color: var(--pi-muted); }
377
- pre { margin: 6px 0 0; white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; direction: ltr; text-align: left; unicode-bidi: isolate; }
378
- .shell-output { color: var(--pi-text); font: 13px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; line-height: 1.45; direction: ltr; text-align: left; unicode-bidi: isolate; }
379
- @keyframes pulse { 0%, 100% { transform: scale(.75); opacity: .55; } 50% { transform: scale(1.2); opacity: 1; } }
380
- `,$u=h`
381
- :host { display: block; }
382
- .formatted { white-space: normal; overflow-wrap: anywhere; line-height: 1.45; text-align: start; unicode-bidi: plaintext; }
383
- p, ul, ol, pre, blockquote, table, .code-block-wrapper { margin: 0 0 10px; }
384
- :is(p, ul, ol, pre, blockquote, table, .code-block-wrapper):last-child { margin-bottom: 0; }
385
- ul, ol { padding-left: 22px; }
386
- li + li { margin-top: 3px; }
387
- code { border: 1px solid var(--pi-border); border-radius: 4px; background: var(--pi-bg); padding: 1px 4px; font: 13px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; direction: ltr; text-align: left; unicode-bidi: isolate; }
388
- .code-block-wrapper { position: relative; }
389
- .code-block-wrapper pre { margin: 0; padding-right: 40px; }
390
- pre { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); padding: 10px; overflow-x: auto; overflow-y: hidden; direction: ltr; text-align: left; unicode-bidi: isolate; }
391
- pre code { border: 0; padding: 0; background: transparent; }
392
- .code-copy-button { position: absolute; top: 6px; right: 6px; z-index: 1; display: inline-grid; place-items: center; width: 24px; height: 24px; border: 1px solid var(--pi-border); border-radius: 6px; background: var(--pi-surface); color: var(--pi-muted); padding: 0; font: 14px system-ui, sans-serif; line-height: 1; cursor: pointer; }
393
- .code-copy-button:hover, .code-copy-button:focus { color: var(--pi-text); border-color: var(--pi-accent); }
394
- blockquote { border-left: 3px solid var(--pi-border); padding-left: 10px; color: var(--pi-muted); }
395
- a { color: var(--pi-accent); }
396
- h1, h2, h3, h4 { margin: 14px 0 8px; line-height: 1.2; }
397
- h1:first-child, h2:first-child, h3:first-child, h4:first-child { margin-top: 0; }
398
- h1 { font-size: 20px; }
399
- h2 { font-size: 17px; }
400
- h3 { font-size: 15px; }
401
- h4 { font-size: 14px; }
402
- table { border-collapse: collapse; display: block; overflow-x: auto; overflow-y: hidden; }
403
- th, td { border: 1px solid var(--pi-border); padding: 4px 8px; }
404
- th { background: var(--pi-surface); }
405
- `,ed=h`
406
- :host { display: block; color: var(--pi-muted); font: 12px system-ui, sans-serif; }
407
- .bar { display: flex; justify-content: flex-end; gap: 12px; align-items: center; min-width: 0; padding: 7px 12px; border-top: 1px solid var(--pi-border); background: var(--pi-bg); white-space: nowrap; overflow: hidden; }
408
- span { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
409
- .activity { display: inline-flex; align-items: center; gap: 6px; color: var(--pi-muted); }
410
- .activity.active { color: var(--pi-success); }
411
- .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; opacity: .45; flex: 0 0 auto; }
412
- .activity.active .dot { animation: pulse 1s ease-in-out infinite; opacity: 1; }
413
- .muted { color: var(--pi-dim); }
414
- @keyframes pulse { 0%, 100% { transform: scale(.75); opacity: .55; } 50% { transform: scale(1.2); opacity: 1; } }
415
- `,td=h`
416
- :host { display: block; }
417
- .menu { position: absolute; left: 0; right: 0; bottom: calc(100% + 6px); z-index: 10; max-height: 260px; overflow: auto; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); box-shadow: 0 10px 30px var(--pi-shadow); }
418
- button { display: grid; grid-template-columns: minmax(120px, 1fr) auto; gap: 4px 10px; width: 100%; border: 0; border-bottom: 1px solid var(--pi-border); border-radius: 0; background: transparent; color: var(--pi-text); padding: 8px 10px; text-align: left; cursor: pointer; }
419
- button:last-child { border-bottom: 0; }
420
- button.selected, button:hover { background: var(--pi-selection-bg); }
421
- span { color: var(--pi-muted); font-size: 12px; }
422
- small { grid-column: 1 / -1; color: var(--pi-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
423
- `,nd=h`
424
- :host { position: fixed; inset: 0; z-index: 10; color: var(--pi-text); font: 14px system-ui, sans-serif; }
425
- .backdrop { display: grid; place-items: center; width: 100%; height: 100%; background: var(--pi-overlay); }
426
- section { width: min(720px, calc(100vw - 40px)); max-height: min(640px, calc(100vh - 40px)); display: flex; flex-direction: column; border: 1px solid var(--pi-border); border-radius: 12px; background: var(--pi-bg); box-shadow: 0 20px 60px var(--pi-shadow-strong); overflow: hidden; }
427
- header { display: flex; align-items: center; justify-content: space-between; padding: 12px; border-bottom: 1px solid var(--pi-border); }
428
- .options { min-height: 0; overflow: auto; outline: none; }
429
- button { border: 0; background: transparent; color: var(--pi-text); cursor: pointer; }
430
- header button { font-size: 20px; color: var(--pi-muted); }
431
- input { margin: 10px 12px; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); color: var(--pi-text); font: var(--pi-control-font-size, 16px) var(--pi-control-font-family, system-ui, sans-serif); padding: 8px 10px; outline: none; }
432
- input:focus { border-color: var(--pi-accent); }
433
- .options button { display: block; width: 100%; padding: 10px 12px; border-bottom: 1px solid var(--pi-border-muted); text-align: left; }
434
- .options button.selected, .options button:hover { background: var(--pi-selection-bg); }
435
- small { display: block; margin-top: 4px; color: var(--pi-muted); }
436
- .empty { padding: 24px; color: var(--pi-muted); text-align: center; }
437
- `,rd=h`
438
- :host { position: fixed; inset: 0; z-index: 20; color: var(--pi-text); font: 14px system-ui, sans-serif; }
439
- .backdrop { --palette-top: min(12dvh, 90px); --palette-bottom: max(20px, env(safe-area-inset-bottom)); display: grid; align-items: start; justify-items: center; width: 100%; height: 100dvh; background: var(--pi-overlay); padding: var(--palette-top) 20px var(--palette-bottom); box-sizing: border-box; overflow: hidden; }
440
- section { width: min(720px, 100%); max-height: min(640px, calc(100dvh - var(--palette-top) - var(--palette-bottom))); display: flex; flex-direction: column; border: 1px solid var(--pi-border); border-radius: 12px; background: var(--pi-bg); box-shadow: 0 20px 60px var(--pi-shadow-strong); overflow: hidden; }
441
- header { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 10px; border-bottom: 1px solid var(--pi-border); }
442
- input { min-width: 0; border: 0; outline: none; background: transparent; color: var(--pi-text); font: var(--pi-control-font-size, 16px) var(--pi-control-font-family, system-ui, sans-serif); padding: 8px; }
443
- input::placeholder { color: var(--pi-dim); }
444
- button { border: 0; background: transparent; color: var(--pi-text); cursor: pointer; }
445
- header button { color: var(--pi-muted); font-size: 22px; padding: 2px 8px; }
446
- .options { flex: 1 1 auto; min-height: 0; overflow: auto; }
447
- .options button { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px 12px; width: 100%; padding: 10px 12px; border-bottom: 1px solid var(--pi-border-muted); text-align: left; }
448
- .options button.selected, .options button:hover:not(:disabled) { background: var(--pi-selection-bg); }
449
- .options button:disabled { cursor: not-allowed; opacity: .68; }
450
- .options button.disabled.selected { background: color-mix(in srgb, var(--pi-selection-bg) 55%, transparent); }
451
- .main { min-width: 0; }
452
- strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
453
- small { display: block; color: var(--pi-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
454
- .disabled-reason { color: var(--pi-warning); }
455
- .group { grid-column: 1 / -1; font-size: 12px; }
456
- kbd { align-self: center; border: 1px solid var(--pi-border); border-radius: 6px; background: var(--pi-surface); color: var(--pi-muted); padding: 2px 6px; font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; white-space: nowrap; }
457
- .empty { padding: 24px; color: var(--pi-muted); text-align: center; }
458
- `,id=h`
459
- :host { position: relative; z-index: 5; display: block; color: var(--pi-text); font: 14px system-ui, sans-serif; }
460
- footer { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 12px; border-top: 1px solid var(--pi-border); }
461
- footer.shell-mode { border-top-color: var(--pi-success); background: var(--pi-success-bg); }
462
- .editor-wrap { position: relative; min-width: 0; }
463
- .actions { display: flex; gap: 8px; align-items: center; justify-content: flex-end; flex-wrap: nowrap; white-space: nowrap; }
464
- .compact-status { display: flex; min-width: 0; align-items: center; gap: 6px; color: var(--pi-muted); font-size: 12px; flex: 1 1 0; }
465
- .compact-status > button { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
466
- .select-model { max-width: min(42vw, 320px); }
467
- .icon-button { flex: 0 0 auto; display: inline-grid; place-items: center; width: 36px; height: 36px; padding: 0; }
468
- .icon-button .prompt-action-icon, .icon-button .prompt-thinking-gauge { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
469
- .icon-button .prompt-action-icon-filled { fill: currentColor; stroke: none; }
470
- .send-button:not(:disabled) { color: var(--pi-accent, var(--pi-text)); }
471
- .stop-button:not(:disabled) { color: var(--pi-danger); }
472
- .select-thinking .prompt-thinking-gauge .gauge-bar { fill: currentColor; stroke: none; opacity: .28; }
473
- .select-thinking .prompt-thinking-gauge .gauge-bar-active { opacity: 1; }
474
- .editor-attach { position: absolute; right: 8px; bottom: 8px; z-index: 2; width: 30px; height: 30px; }
475
- .editor-attach .prompt-action-icon { width: 16px; height: 16px; }
476
- textarea, .markdown-editor .cm-editor { box-sizing: border-box; width: 100%; min-height: 54px; max-height: 220px; resize: none; overflow: hidden; border-radius: 8px; border: 1px solid var(--pi-border); background: var(--pi-bg); color: var(--pi-text); font: var(--pi-control-font-size, 16px)/1.4 var(--pi-control-font-family, system-ui, sans-serif); }
477
- textarea { overflow-y: auto; padding: 8px; }
478
- .markdown-editor .cm-scroller { max-height: 220px; overflow-y: auto; font-family: var(--pi-control-font-family, system-ui, sans-serif); line-height: 1.4; }
479
- .markdown-editor .cm-content { min-height: 38px; padding: 8px 44px 8px 8px; caret-color: var(--pi-text); text-align: start; unicode-bidi: plaintext; }
480
- .markdown-editor .cm-line { padding: 0; unicode-bidi: plaintext; }
481
- .markdown-editor .cm-placeholder { color: var(--pi-dim); }
482
- .markdown-editor .cm-focused { outline: none; }
483
- .shell-mode textarea, .shell-mode .markdown-editor .cm-editor { border-color: var(--pi-success); box-shadow: 0 0 0 1px var(--pi-success-ring); }
484
- .mode-hint { position: absolute; right: 46px; bottom: 8px; max-width: calc(100% - 54px); border: 1px solid var(--pi-success-border); border-radius: 999px; background: var(--pi-success-surface); color: var(--pi-success); padding: 2px 8px; font-size: 12px; pointer-events: none; }
485
- .attachments { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
486
- .attachment-chip { position: relative; width: 56px; height: 56px; border: 1px solid var(--pi-border); border-radius: 8px; overflow: hidden; background: var(--pi-bg); }
487
- .attachment-chip img { width: 100%; height: 100%; object-fit: cover; display: block; }
488
- .attachment-chip-file { display: grid; place-items: center; }
489
- .attachment-file-preview { display: grid; place-items: center; width: 34px; height: 26px; border: 1px solid var(--pi-border-muted); border-radius: 4px; background: var(--pi-surface); color: var(--pi-muted); font: 700 10px/1 system-ui, sans-serif; letter-spacing: .03em; }
490
- .attachment-file-name { position: absolute; right: 4px; bottom: 3px; left: 4px; overflow: hidden; color: var(--pi-muted); font-size: 10px; line-height: 1.2; text-align: center; text-overflow: ellipsis; white-space: nowrap; }
491
- .attachment-remove { position: absolute; top: 1px; right: 1px; width: 18px; height: 18px; padding: 0; line-height: 16px; border-radius: 50%; border: 1px solid var(--pi-border); background: var(--pi-surface); color: var(--pi-text); font-size: 13px; cursor: pointer; }
492
- .attachment-delivery select { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 5px 7px; font: var(--pi-control-font-size, 16px) var(--pi-control-font-family, system-ui, sans-serif); }
493
- .attachment-error { flex-basis: 100%; color: var(--pi-danger); font-size: 12px; }
494
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
495
- button:disabled, textarea:disabled, .markdown-editor-disabled .cm-editor { opacity: .5; cursor: not-allowed; }
496
- @media (max-width: 640px) {
497
- footer { gap: 8px; padding: 8px; }
498
- .actions { gap: 6px; }
499
- .compact-status { flex: 1 1 220px; gap: 4px; }
500
- .select-model { max-width: min(58vw, 260px); }
501
- button { padding: 6px 8px; }
502
- }
503
- @media (max-width: 430px) {
504
- .compact-status { flex-basis: 170px; font-size: 11px; }
505
- .select-model { max-width: 48vw; }
506
- button { padding: 5px 7px; }
507
- .icon-button { width: 34px; height: 34px; }
508
- }
509
- `;function R(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var ad=`modulepreload`,od=function(e,t){return new URL(e,t).href},sd={},cd=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=od(t,n),t=s(t),t in sd)return;sd[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:ad,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},ld=class extends v{constructor(...e){super(...e),this.destinationFolder=``,this.overwrite=!1,this.createDirs=!0,this.formError=``,this.dragActive=!1,this.dragDepth=0,this.openFilePicker=()=>{this.uploadInput?.click()},this.handleFileInputChange=e=>{let t=e.currentTarget instanceof HTMLInputElement?e.currentTarget:void 0,n=gd(t?.files);t!==void 0&&(t.value=``),n.length>0&&this.openUploadReview(n)},this.handleDragEnter=e=>{_d(e)&&(e.preventDefault(),this.dragDepth+=1,this.dragActive=!0)},this.handleDragOver=e=>{_d(e)&&(e.preventDefault(),e.dataTransfer!==null&&(e.dataTransfer.dropEffect=`copy`),this.dragActive=!0)},this.handleDragLeave=e=>{_d(e)&&(e.preventDefault(),this.dragDepth=Math.max(0,this.dragDepth-1),this.dragDepth===0&&(this.dragActive=!1))},this.handleDrop=e=>{if(!_d(e))return;e.preventDefault(),this.dragDepth=0,this.dragActive=!1;let t=gd(e.dataTransfer?.files),n=this.context;t.length>0&&n!==void 0&&md(n,t)},this.handleDestinationInput=e=>{let t=e.currentTarget instanceof HTMLInputElement?e.currentTarget:void 0;this.destinationFolder=t?.value??``,this.formError=``},this.handleCreateDirsChange=e=>{let t=e.currentTarget instanceof HTMLInputElement?e.currentTarget:void 0;this.createDirs=t?.checked??!0},this.handleOverwriteChange=e=>{let t=e.currentTarget instanceof HTMLInputElement?e.currentTarget:void 0;this.overwrite=t?.checked??!1},this.handleDialogKeyDown=e=>{e.key===`Escape`&&(e.preventDefault(),this.closeUploadDialog())}}willUpdate(e){if(!e.has(`context`))return;let t=e.get(`context`);t!==void 0&&this.context!==void 0&&hd(t)!==hd(this.context)&&this.resetPendingUpload()}render(){let e=this.context;return e===void 0?g`<p class="muted">Files unavailable.</p>`:g`
510
- <section
511
- class=${this.dragActive?`files-panel dragging`:`files-panel`}
512
- @dragenter=${this.handleDragEnter}
513
- @dragover=${this.handleDragOver}
514
- @dragleave=${this.handleDragLeave}
515
- @drop=${this.handleDrop}
516
- >
517
- <section class="toolbar">
518
- <strong>Files</strong>
519
- ${e.fileTreeStale?g`<span class="stale">stale</span>`:null}
520
- <div class="toolbar-actions">
521
- <button @click=${this.openFilePicker}>Upload</button>
522
- <button @click=${e.onRefreshFiles}>Refresh</button>
523
- </div>
524
- <input id="workspace-upload-input" class="visually-hidden" type="file" multiple @change=${this.handleFileInputChange} />
525
- </section>
526
- ${this.renderUploadProgress(e)}
527
- <section class="split">
528
- <div class="list tree">
529
- ${e.fileTree.length===0?g`<p class="muted">No files loaded.</p>`:e.fileTree.map(t=>this.renderTreeEntry(e,t,0))}
530
- </div>
531
- <div class="viewer">
532
- ${this.renderFileViewer(e)}
533
- </div>
534
- </section>
535
- <div class="drop-overlay" aria-hidden=${this.dragActive?`false`:`true`}>
536
- <div>
537
- <strong>Drop files to upload</strong>
538
- <span>Uploads immediately to the default folder.</span>
539
- </div>
540
- </div>
541
- ${this.pendingUpload===void 0?null:this.renderUploadDialog(e,this.pendingUpload)}
542
- </section>
543
- `}renderTreeEntry(e,t,n){let r=e.expandedDirs[t.path],i=r!==void 0;return g`
544
- <button class=${t.type!==`directory`&&e.selectedFilePath===t.path?`row selected`:`row`} style=${`--depth:${String(n)}`} @click=${()=>{this.selectTreeEntry(e,t)}}>
545
- <span>${t.type===`directory`?i?`▾`:`▸`:`·`}</span>
546
- <span>${t.name}</span>
547
- </button>
548
- ${i?r.map(t=>this.renderTreeEntry(e,t,n+1)):null}
549
- `}selectTreeEntry(e,t){t.type===`directory`?e.onExpandDir(t.path):e.onSelectFile(t.path)}renderFileViewer(e){let t=pd(e);if(t!==void 0)return g`<p class="muted">${t}</p>`;let n=e.selectedFileContent;return n===void 0?g`<p class="muted">Select a file.</p>`:n.mediaType===`image`?this.renderImageViewer(e,n):(Td(),g`
550
- <div class="viewer-header"><strong>${n.path}</strong><small>${n.language??`text`}${n.truncated?` · truncated`:``}</small></div>
551
- <code-viewer .content=${n.content} .language=${n.language}></code-viewer>
552
- `)}renderImageViewer(e,t){let n=`${t.mimeType??`image`} · ${Ed(t.size)}`;if(t.size>10485760)return g`
553
- <div class="viewer-header"><strong>${t.path}</strong><small>${n}</small></div>
554
- <p class="muted">Image too large to preview: ${Ed(t.size)} · limit ${Ju}</p>
555
- `;let r=ai(e.workspace.projectId,e.workspace.id,t.path,{modifiedAt:t.modifiedAt,machineId:e.machine.id});return g`
556
- <div class="viewer-header"><strong>${t.path}</strong><small>${n}</small></div>
557
- <div class="image-preview">
558
- <img src=${r} alt=${t.path} decoding="async" />
559
- </div>
560
- `}renderUploadProgress(e){let t=ud(e.state.workspaceUploadBatches,{projectId:e.workspace.projectId,workspaceId:e.workspace.id,machineId:e.machine.id});return t.length===0?null:g`
561
- <section class="upload-progress" aria-label="Workspace uploads">
562
- <div class="upload-progress-header">
563
- <strong>Uploads</strong>
564
- <small>${vd(t)}</small>
565
- </div>
566
- ${t.map(t=>this.renderUploadBatch(e,t))}
567
- </section>
568
- `}renderUploadBatch(e,t){return g`
569
- <article class=${`upload-batch ${t.status}`}>
570
- <div class="upload-batch-heading">
571
- <div>
572
- <strong>${yd(t)}</strong>
573
- <small>${t.destinationFolder===``?`workspace root`:t.destinationFolder}</small>
574
- </div>
575
- <span>${bd(t)}</span>
576
- </div>
577
- <progress max="1" .value=${xd(t)}></progress>
578
- <div class="upload-file-list">
579
- ${t.files.map(e=>this.renderUploadFile(e))}
580
- </div>
581
- <div class="upload-actions">
582
- ${t.status===`uploading`?g`<button @click=${()=>{e.onCancelWorkspaceUpload(t.id)}}>Cancel</button>`:g`<button @click=${()=>{e.onClearWorkspaceUpload(t.id)}}>Dismiss</button>`}
583
- </div>
584
- </article>
585
- `}renderUploadFile(e){let t=Cd(e);return g`
586
- <div class=${`upload-file ${e.status}`}>
587
- <div class="upload-file-main">
588
- <span>${e.name}</span>
589
- <small>${t}</small>
590
- </div>
591
- <span class="upload-file-status">${Sd(e)}</span>
592
- </div>
593
- `}renderUploadDialog(e,t){let n=t.files.length;return g`
594
- <div class="dialog-backdrop" @mousedown=${()=>{this.closeUploadDialog()}}>
595
- <section class="upload-dialog" role="dialog" aria-modal="true" aria-label="Review file upload" @mousedown=${e=>{e.stopPropagation()}} @keydown=${this.handleDialogKeyDown}>
596
- <header>
597
- <div>
598
- <span class="eyebrow">Upload</span>
599
- <h2>Review ${n===1?`file`:`${String(n)} files`}</h2>
600
- </div>
601
- <button class="close-button" title="Cancel upload" aria-label="Cancel upload" @click=${()=>{this.closeUploadDialog()}}>×</button>
602
- </header>
603
- <form @submit=${n=>{this.submitUploadReview(n,e,t)}}>
604
- <label>
605
- <span>Destination folder</span>
606
- <input .value=${this.destinationFolder} placeholder=${e.workspaceUploadDefaultFolder} @input=${this.handleDestinationInput} />
607
- <small>Workspace-relative. Leave empty to upload at the workspace root.</small>
608
- </label>
609
- <div class="dialog-options">
610
- <label>
611
- <input type="checkbox" .checked=${this.createDirs} @change=${this.handleCreateDirsChange} />
612
- <span>Create parent folders</span>
613
- </label>
614
- <label>
615
- <input type="checkbox" .checked=${this.overwrite} @change=${this.handleOverwriteChange} />
616
- <span>Overwrite existing files</span>
617
- </label>
618
- </div>
619
- <section class="review-files" aria-label="Files to upload">
620
- <strong>${n===1?`File`:`Files`}</strong>
621
- ${t.files.map(e=>g`
622
- <div class="review-file">
623
- <span>${e.name}</span>
624
- <small>${Ed(e.size)}</small>
625
- </div>
626
- `)}
627
- </section>
628
- ${this.formError===``?null:g`<div class="dialog-error" role="alert">${this.formError}</div>`}
629
- <footer>
630
- <button type="button" @click=${()=>{this.closeUploadDialog()}}>Cancel</button>
631
- <button type="submit">Upload</button>
632
- </footer>
633
- </form>
634
- </section>
635
- </div>
636
- `}openUploadReview(e){let t=this.context,n=fd(t?.workspaceUploadDefaultFolder??``);this.pendingUpload={files:e},this.destinationFolder=n.destinationFolder,this.overwrite=n.overwrite,this.createDirs=n.createDirs,this.formError=``}submitUploadReview(e,t,n){e.preventDefault();let r=dd(n.files,this.destinationFolder);if(r!==void 0){this.formError=r;return}t.onStartWorkspaceUpload(n.files,{destinationFolder:this.destinationFolder,createDirs:this.createDirs,overwrite:this.overwrite,selectUploadedFile:!0})!==void 0&&this.closeUploadDialog()}closeUploadDialog(){this.pendingUpload=void 0,this.formError=``}resetPendingUpload(){this.closeUploadDialog(),this.dragDepth=0,this.dragActive=!1}static{this.styles=[Xu,h`
637
- :host { flex: 1 1 auto; }
638
- .files-panel { position: relative; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
639
- .toolbar-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
640
- .toolbar .toolbar-actions button { margin-left: 0; }
641
- .visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
642
- .drop-overlay { position: absolute; inset: 52px 10px 10px; z-index: 15; display: grid; place-items: center; border: 2px dashed var(--pi-accent); border-radius: 12px; background: color-mix(in srgb, var(--pi-bg-overlay) 90%, var(--pi-accent) 10%); color: var(--pi-text); opacity: 0; pointer-events: none; transition: opacity .12s ease; }
643
- .files-panel.dragging .drop-overlay { opacity: 1; }
644
- .drop-overlay div { display: grid; gap: 4px; justify-items: center; padding: 18px; border-radius: 10px; background: var(--pi-bg-overlay); box-shadow: 0 8px 24px var(--pi-shadow); }
645
- .drop-overlay span { color: var(--pi-muted); }
646
- .upload-progress { flex: 0 0 auto; display: grid; gap: 8px; padding: 8px; border-bottom: 1px solid var(--pi-border-muted); background: color-mix(in srgb, var(--pi-surface) 55%, transparent); }
647
- .upload-progress-header, .upload-batch-heading, .upload-actions { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
648
- .upload-batch { display: grid; gap: 6px; border: 1px solid var(--pi-border-muted); border-radius: 8px; background: var(--pi-bg); padding: 8px; }
649
- .upload-batch.error { border-color: var(--pi-danger); }
650
- .upload-batch.cancelled { border-color: var(--pi-warning-border); }
651
- .upload-batch.completed { border-color: var(--pi-success-border); }
652
- .upload-batch-heading > div { min-width: 0; display: grid; gap: 2px; }
653
- .upload-batch-heading strong, .upload-batch-heading small { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
654
- progress { width: 100%; accent-color: var(--pi-accent); }
655
- .upload-file-list { display: grid; gap: 4px; max-height: 180px; overflow: auto; padding-right: 2px; }
656
- .upload-file { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 8px; color: var(--pi-muted); }
657
- .upload-file.completed .upload-file-status { color: var(--pi-success); }
658
- .upload-file.error { color: var(--pi-danger); }
659
- .upload-file.cancelled .upload-file-status { color: var(--pi-warning); }
660
- .upload-file-main { min-width: 0; display: grid; gap: 1px; }
661
- .upload-file-main span, .upload-file-main small { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
662
- .upload-file-status { font-size: 12px; white-space: nowrap; }
663
- .upload-actions { justify-content: end; }
664
- .dialog-backdrop { position: fixed; inset: 0; z-index: 100; box-sizing: border-box; display: grid; place-items: center; padding: max(20px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) max(20px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left)); background: var(--pi-overlay); }
665
- .upload-dialog { box-sizing: border-box; width: min(560px, 100%); max-height: min(720px, 100%); display: flex; flex-direction: column; overflow: hidden; border: 1px solid var(--pi-border); border-radius: 14px; background: var(--pi-bg); box-shadow: 0 18px 70px var(--pi-shadow-strong); }
666
- .upload-dialog header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--pi-border-muted); }
667
- .upload-dialog h2 { margin: 2px 0 0; font-size: 18px; line-height: 1.2; }
668
- .eyebrow { color: var(--pi-muted); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; }
669
- .close-button { font-size: 20px; line-height: 1; padding: 4px 9px; }
670
- form { min-height: 0; display: flex; flex-direction: column; gap: 12px; overflow: auto; padding: 16px; }
671
- form > label { display: grid; gap: 6px; }
672
- form > label > span, .review-files > strong { font-weight: 600; }
673
- input[type="text"], form > label > input:not([type]) { box-sizing: border-box; width: 100%; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 8px 9px; font: var(--pi-control-font-size, 16px) var(--pi-control-font-family, system-ui, sans-serif); }
674
- input:focus-visible { outline: 2px solid var(--pi-accent); outline-offset: 1px; }
675
- .dialog-options { display: grid; gap: 8px; }
676
- .dialog-options label { display: flex; align-items: center; gap: 8px; color: var(--pi-text); }
677
- .review-files { display: grid; gap: 6px; min-height: 0; max-height: 180px; overflow: auto; border: 1px solid var(--pi-border-muted); border-radius: 8px; padding: 8px; }
678
- .review-file { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: baseline; }
679
- .review-file span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
680
- .dialog-error { border: 1px solid var(--pi-danger); border-radius: 8px; background: color-mix(in srgb, var(--pi-danger) 10%, transparent); color: var(--pi-danger); padding: 9px; line-height: 1.35; overflow-wrap: anywhere; }
681
- footer { display: flex; justify-content: flex-end; gap: 8px; padding-top: 4px; }
682
- `]}};R([b({attribute:!1})],ld.prototype,`context`,void 0),R([S(`#workspace-upload-input`)],ld.prototype,`uploadInput`,void 0),R([x()],ld.prototype,`pendingUpload`,void 0),R([x()],ld.prototype,`destinationFolder`,void 0),R([x()],ld.prototype,`overwrite`,void 0),R([x()],ld.prototype,`createDirs`,void 0),R([x()],ld.prototype,`formError`,void 0),R([x()],ld.prototype,`dragActive`,void 0),ld=R([y(`workspace-files-panel`)],ld);function ud(e,t){return Object.values(e).filter(e=>e.projectId===t.projectId&&e.workspaceId===t.workspaceId&&e.machineId===t.machineId).sort((e,t)=>t.startedAt.localeCompare(e.startedAt))}function dd(e,t){if(e.length===0)return`Choose at least one file to upload.`;for(let n of e)try{Ui(t,n.name)}catch(e){return e instanceof Error?e.message:String(e)}}function fd(e){return{destinationFolder:e,createDirs:!0,overwrite:!1}}function pd(e){let t=e.selectedFileContent;if(e.selectedFilePath===void 0||e.selectedFilePath===``)return`Select a file.`;if(t===void 0)return`Loading ${e.selectedFilePath}…`;if(t.mediaType!==`image`&&t.binary)return`Binary file: ${t.path} · ${Ed(t.size)}`}function md(e,t){if(t.length!==0)return e.onStartWorkspaceUpload(t,{destinationFolder:e.workspaceUploadDefaultFolder,createDirs:!0,overwrite:!1,selectUploadedFile:!0})}function hd(e){return`${e.machine.id}:${e.workspace.projectId}:${e.workspace.id}`}function gd(e){return e==null?[]:Array.from(e)}function _d(e){return Array.from(e.dataTransfer?.types??[]).includes(`Files`)}function vd(e){let t=e.filter(e=>e.status===`uploading`).length;return t===0?`${String(e.length)} recent`:`${String(t)} uploading`}function yd(e){let t=e.files.length,n=t===1?`file`:`files`;switch(e.status){case`completed`:return`Uploaded ${String(t)} ${n}`;case`error`:return`Upload failed for ${String(t)} ${n}`;case`cancelled`:return`Upload cancelled for ${String(t)} ${n}`;case`uploading`:return`Uploading ${String(t)} ${n}`}}function bd(e){switch(e.status){case`completed`:return`Done`;case`error`:return`Failed`;case`cancelled`:return`Cancelled`;case`uploading`:return wd(e.percent)}}function xd(e){return e.status===`uploading`?e.percent:1}function Sd(e){switch(e.status){case`pending`:return`Pending`;case`uploading`:return wd(e.percent);case`completed`:return`Done`;case`error`:return`Error`;case`cancelled`:return`Cancelled`}}function Cd(e){return e.error===void 0?e.response===void 0?`${e.path} · ${Ed(e.loaded)} / ${Ed(e.total)}`:`Wrote ${e.response.path}`:e.error}function wd(e){return`${String(Math.round(Math.max(0,Math.min(1,e))*100))}%`}function Td(){cd(()=>import(`./CodeViewer-uASb28Y1.js`),__vite__mapDeps([0,1,2,3]),import.meta.url)}function Ed(e){if(!Number.isFinite(e)||e<0)return`0 B`;if(e<1024)return`${String(e)} B`;let t=e/1024;if(t<1024)return`${Dd(t)} KB`;let n=t/1024;return n<1024?`${Dd(n)} MB`:`${Dd(n/1024)} GB`}function Dd(e){return e>=10?String(Math.round(e)):e.toFixed(1)}function Od(){return[{id:`workspace.files`,title:`Files`,icon:qu(`files`),order:10,render:kd},{id:`workspace.git`,title:`Git`,icon:qu(`git`),order:20,visible:({workspace:e})=>e.isGitRepo,render:jd},{id:`workspace.terminal`,title:`Terminal`,icon:qu(`terminal`),order:30,badge:e=>e.activeTerminalCount>0?e.activeTerminalCount:void 0,render:Ad}]}function kd(e){return g`<workspace-files-panel .context=${e}></workspace-files-panel>`}function Ad(e){return Fd(),g`<terminal-panel .workspace=${e.workspace} .machineId=${e.machine.id} .selectedTerminalId=${e.selectedTerminalId} .autoStart=${e.terminalAutoStart} .onSelectTerminal=${e.onSelectTerminal}></terminal-panel>`}function jd(e){let t=e.gitStatus;return g`
683
- <section class="toolbar">
684
- <strong>Git</strong>
685
- ${e.gitStale?g`<span class="stale">stale</span>`:null}
686
- <button @click=${e.onRefreshGit}>Refresh</button>
687
- </section>
688
- <section class="split">
689
- <div class="list">
690
- ${t===void 0?g`<p class="muted">No status loaded.</p>`:t.isGitRepo?g`
691
- <p class="summary">${Id(t)}</p>
692
- ${t.files.length===0?g`<p class="muted">No changes.</p>`:t.files.map(t=>g`
693
- <button class="row ${e.selectedDiffPath===t.path?`selected`:``}" @click=${()=>{e.onSelectDiff(t.path)}}>
694
- <span>${Ld(t.index,t.workingTree)}</span>
695
- <span>${t.path}</span>
696
- </button>
697
- `)}
698
- `:g`<p class="muted">Not a git repository.</p>`}
699
- </div>
700
- <div class="viewer">
701
- ${Md(e)}
702
- </div>
703
- </section>
704
- `}function Md(e){if(e.selectedDiffPath===void 0||e.selectedDiffPath===``)return g`<p class="muted">Select a changed file.</p>`;let t=e.selectedDiff,n=e.selectedStagedDiff;if(t===void 0||n===void 0)return g`<p class="muted">Loading diff…</p>`;let r=[n,t].filter(e=>e.diff!==``);return r.length===0?g`<p class="muted">No staged or unstaged diff.</p>`:g`
705
- <div class=${r.length===1?`diffs single`:`diffs`}>
706
- ${r.map(e=>Nd(e))}
707
- </div>
708
- `}function Nd(e){return Pd(),g`
709
- <section class="diff-section">
710
- <div class="viewer-header"><strong>${e.path??`diff`}</strong><small>${e.staged?`staged`:`unstaged`}${e.truncated?` · truncated`:``}</small></div>
711
- <unified-diff-viewer .diff=${e.diff}></unified-diff-viewer>
712
- </section>
713
- `}function Pd(){cd(()=>import(`./UnifiedDiffViewer-laQN1x7P.js`),[],import.meta.url)}function Fd(){cd(()=>import(`./TerminalPanel-DfTmykFw.js`),__vite__mapDeps([4,5,6]),import.meta.url)}function Id(e){let t=e.branch??`detached`,n=e.ahead??0,r=e.behind??0;return n===0&&r===0?t:`${t} · ↑${String(n)} ↓${String(r)}`}function Ld(e,t){return(t===`unmodified`?e:t).slice(0,1).toUpperCase()}var Rd={apiVersion:1,name:`PI WEB Core`,activate:()=>({contributions:{actions:Iu(),workspacePanels:Od()}})},zd={"--pi-bg":`#0d1117`,"--pi-surface":`#161b22`,"--pi-surface-hover":`#21262d`,"--pi-terminal-bg":`#05070a`,"--pi-terminal-text":`#e6edf3`,"--pi-border":`#30363d`,"--pi-border-muted":`#21262d`,"--pi-text":`#e6edf3`,"--pi-text-secondary":`#c9d1d9`,"--pi-text-bright":`#f0f6fc`,"--pi-muted":`#8b949e`,"--pi-dim":`#6e7681`,"--pi-accent":`#58a6ff`,"--pi-accent-border":`#2f81f7`,"--pi-selection-bg":`#0d2847`,"--pi-success":`#3fb950`,"--pi-success-border":`#238636`,"--pi-success-bg":`#0f1b12`,"--pi-success-surface":`#0f2a16`,"--pi-success-ring":`#3fb95055`,"--pi-warning":`#d29922`,"--pi-warning-border":`#6e5200`,"--pi-warning-surface":`#1f1a10`,"--pi-danger":`#ff7b72`,"--pi-purple":`#d2a8ff`,"--pi-purple-border":`#a371f7`,"--pi-purple-surface":`#21132f`,"--pi-overlay":`#0008`,"--pi-shadow-soft":`#0006`,"--pi-shadow":`#0008`,"--pi-shadow-strong":`#000b`,"--pi-bg-overlay-soft":`#0d1117dd`,"--pi-bg-overlay":`#0d1117e6`,"--pi-success-bg-overlay":`#0f1b12ee`,"--pi-terminal-selection":`#264f78`},Bd={"--pi-bg":`#070912`,"--pi-surface":`#101527`,"--pi-surface-hover":`#151b31`,"--pi-terminal-bg":`#050710`,"--pi-terminal-text":`#f7f4ff`,"--pi-border":`#26304f`,"--pi-border-muted":`#26304f`,"--pi-text":`#f7f4ff`,"--pi-text-secondary":`#aaa4bd`,"--pi-text-bright":`#ffffff`,"--pi-muted":`#aaa4bd`,"--pi-dim":`#817a99`,"--pi-accent":`#7c3cff`,"--pi-accent-border":`#5a47b0`,"--pi-selection-bg":`#1d2547`,"--pi-success":`#00f0d8`,"--pi-success-border":`#00f0d8`,"--pi-success-bg":`#071e22`,"--pi-success-surface":`#092d31`,"--pi-success-ring":`#00f0d855`,"--pi-warning":`#ffb000`,"--pi-warning-border":`#ffb000`,"--pi-warning-surface":`#16140d`,"--pi-danger":`#ff4f7b`,"--pi-purple":`#b7a2ff`,"--pi-purple-border":`#7c3cff`,"--pi-purple-surface":`#181026`,"--pi-overlay":`#0008`,"--pi-shadow-soft":`#0006`,"--pi-shadow":`#0008`,"--pi-shadow-strong":`#000b`,"--pi-bg-overlay-soft":`#070912dd`,"--pi-bg-overlay":`#070912e6`,"--pi-success-bg-overlay":`#071e22ee`,"--pi-terminal-selection":`#3d4a78`},Vd={"--pi-bg":`#f7f1e6`,"--pi-surface":`#fff9ee`,"--pi-surface-hover":`#f0e6d6`,"--pi-terminal-bg":`#15131b`,"--pi-terminal-text":`#fff9ee`,"--pi-border":`#c9bca8`,"--pi-border-muted":`#d8cdbc`,"--pi-text":`#15131b`,"--pi-text-secondary":`#15131b`,"--pi-text-bright":`#15131b`,"--pi-muted":`#5f586a`,"--pi-dim":`#766f7e`,"--pi-accent":`#6430d8`,"--pi-accent-border":`#6430d8`,"--pi-selection-bg":`#eadff8`,"--pi-success":`#008c82`,"--pi-success-border":`#008c82`,"--pi-success-bg":`#e1f4ef`,"--pi-success-surface":`#d7f0ec`,"--pi-success-ring":`#008c8255`,"--pi-warning":`#b05f00`,"--pi-warning-border":`#b05f00`,"--pi-warning-surface":`#fff2d2`,"--pi-danger":`#b51d49`,"--pi-purple":`#6430d8`,"--pi-purple-border":`#6430d8`,"--pi-purple-surface":`#eadff8`,"--pi-overlay":`#15131b66`,"--pi-shadow-soft":`#15131b22`,"--pi-shadow":`#15131b33`,"--pi-shadow-strong":`#15131b44`,"--pi-bg-overlay-soft":`#f7f1e6dd`,"--pi-bg-overlay":`#f7f1e6e6`,"--pi-success-bg-overlay":`#e1f4efee`,"--pi-terminal-selection":`#8d7b64`},Hd={apiVersion:1,name:`PI WEB Themes`,activate:()=>({contributions:{themes:[{id:`pi-web-dark`,name:`PI WEB Dark`,description:`Dark PI WEB palette.`,order:10,colorScheme:`dark`,tokens:Bd},{id:`pi-web-light`,name:`PI WEB Light`,description:`Light PI WEB palette.`,order:20,colorScheme:`light`,tokens:Vd},{id:`classic`,name:`PI WEB Classic`,description:`The original PI WEB dark palette.`,order:30,colorScheme:`dark`,tokens:zd}],themePairs:[{id:`pi-web`,name:`PI WEB`,description:`Follow the system light/dark preference with PI WEB themes.`,order:10,light:`pi-web-light`,dark:`pi-web-dark`}]}})},Ud=/^[a-z][a-z0-9.-]*$/u;function Wd(e){return Ud.test(e)}var Gd=`machine.`;function Kd(e,t){if(e===``)throw Error(`Machine id is required`);if(!Wd(t))throw Error(`Invalid PI WEB plugin id: ${t}`);return`${Gd}${qd(e)}.${t}`}function qd(e){return[...new TextEncoder().encode(e)].map(e=>e.toString(16).padStart(2,`0`)).join(``)}async function Jd(e=`pi-web-plugins/manifest.json`,t={}){let n=_t(e),r=await Zd(n);if(r===void 0)return[];let i=[];for(let e of r.plugins)if(t.shouldLoadPlugin?.(e)!==!1)try{let r=Yd(e.module,n),a=ef(await(t.moduleLoader??Xd)(r),r);i.push({id:t.machineId===void 0?e.id:Kd(t.machineId,e.id),plugin:a,machineSpecific:e.machineSpecific,...t.machineId===void 0?{}:{machineId:t.machineId,sourcePluginId:e.id}})}catch(t){console.warn(`Failed to load PI WEB plugin ${e.module}`,t)}return i}function Yd(e,t,n){return e.startsWith(`/`)?n===void 0?_t(e):_t(e,n):new URL(e,t).toString()}async function Xd(e){return cd(()=>import(e),[],import.meta.url)}async function Zd(e){let t=await fetch(e,{cache:`no-store`});if(t.status!==404){if(!t.ok)throw Error(`Failed to load plugin manifest: ${t.statusText}`);return Qd(await t.json())}}function Qd(e){if(!nf(e)||!Array.isArray(e.plugins))throw Error(`Invalid plugin manifest`);return{plugins:e.plugins.map(e=>{if(!nf(e)||typeof e.id!=`string`||e.id===``||typeof e.module!=`string`||e.module===``)throw Error(`Invalid plugin manifest entry`);return{id:e.id,module:e.module,machineSpecific:$d(e.machineSpecific)}})}}function $d(e){if(e===void 0)return!1;if(typeof e!=`boolean`)throw Error(`Invalid plugin manifest entry`);return e}function ef(e,t){if(!nf(e))throw Error(`Plugin module ${t} did not export an object`);let n=e.default;if(!tf(n))throw Error(`Plugin module ${t} default export is not a PiWebPlugin`);return n}function tf(e){return nf(e)&&e.apiVersion===1&&typeof e.name==`string`&&typeof e.activate==`function`}function nf(e){return typeof e==`object`&&!!e}var rf=/^[a-z][a-z0-9.-]*$/u,af=/^[a-z][a-z0-9.-]*$/u,of=new WeakMap,sf=new WeakMap,cf=class{constructor(){this.actions=[],this.workspacePanels=[],this.workspaceLabels=[],this.themes=[],this.themePairs=[],this.pluginIds=new Set,this.gatewayPluginIds=new Set,this.gatewayMachineSpecificPluginIds=new Set,this.remoteMachineSpecificPluginIds=new Map,this.contributionIds=new Set}register(e){let{id:t,plugin:n}=e;this.validatePluginId(t);let r=this.parseMachineSpecific(t,e.machineSpecific);if(this.pluginIds.has(t))throw Error(`Duplicate plugin id: ${t}`);if(this.isRemoteDuplicateHiddenByGateway(e.sourcePluginId,e.machineId,r))return;this.pluginIds.add(t);let i=n.apiVersion;if(i!==1)throw Error(`Unsupported plugin API version for ${t}: ${String(i)}`);let a=n.activate({apiVersion:1,pluginId:t,html:g,svg:Je}).contributions;for(let n of a.actions??[])this.actions.push(this.qualifyAction(t,n,e.machineId,e.sourcePluginId));for(let n of a.workspacePanels??[])this.workspacePanels.push(this.qualifyWorkspacePanel(t,n,e.machineId,e.sourcePluginId));for(let n of a.workspaceLabels??[])this.workspaceLabels.push(this.qualifyWorkspaceLabelContribution(t,n,e.machineId,e.sourcePluginId));if(e.machineId===void 0){for(let e of a.themes??[])this.themes.push(this.qualifyTheme(t,e));for(let e of a.themePairs??[])this.themePairs.push(this.qualifyThemePair(t,e));this.gatewayPluginIds.add(t),r&&this.gatewayMachineSpecificPluginIds.add(t)}else e.sourcePluginId!==void 0&&r&&pf(this.remoteMachineSpecificPluginIds,e.sourcePluginId,e.machineId)}shouldLoadRemotePlugin(e,t=!1){return!this.gatewayPluginIds.has(e)||this.gatewayMachineSpecificPluginIds.has(e)||t}getActions(e){let t=hf(e);return this.actions.filter(e=>this.isContributionActive(e.pluginId,e.machineId,t,e.sourcePluginId)).map(t=>{let n=lf(e,t.pluginId),r=t.enabled?.(n),i=r===!1?t.disabledReason?.(n):void 0,a={id:t.id,pluginId:t.pluginId,localId:t.localId,...t.machineId===void 0?{}:{machineId:t.machineId},title:t.title,run:()=>t.run(n)};return t.description!==void 0&&(a.description=t.description),t.shortcut!==void 0&&(a.shortcut=t.shortcut),t.group!==void 0&&(a.group=t.group),r!==void 0&&(a.enabled=r),i!==void 0&&i!==``&&(a.disabledReason=i),a})}getWorkspacePanels(){return[...this.workspacePanels].sort((e,t)=>(e.order??1e3)-(t.order??1e3)||e.title.localeCompare(t.title))}getThemes(){return[...this.themes].sort((e,t)=>(e.order??1e3)-(t.order??1e3)||e.name.localeCompare(t.name))}getThemePairs(){return[...this.themePairs].sort((e,t)=>(e.order??1e3)-(t.order??1e3)||e.name.localeCompare(t.name))}getWorkspaceLabelItems(e){return[...this.workspaceLabels].sort((e,t)=>(e.order??1e3)-(t.order??1e3)||e.id.localeCompare(t.id)).flatMap(t=>t.visible?.(e)===!1?[]:t.items(e))}qualifyAction(e,t,n,r){let i=this.qualify(e,t.id);return{...t,id:i,pluginId:e,localId:t.id,...n===void 0?{}:{machineId:n},...r===void 0?{}:{sourcePluginId:r}}}qualifyWorkspacePanel(e,t,n,r){let i=this.qualify(e,t.id),a=t.badge,o=t.visible;return{...t,id:i,pluginId:e,localId:t.id,...n===void 0?{}:{machineId:n},visible:t=>this.isContributionActive(e,n,t.machine.id,r)&&(o?.(uf(t,e))??!0),...a===void 0?{}:{badge:t=>this.isContributionActive(e,n,t.machine.id,r)?a(uf(t,e)):void 0},render:n=>t.render(uf(n,e))}}qualifyWorkspaceLabelContribution(e,t,n,r){let i=this.qualify(e,t.id),a=t.visible,o=t.items;return{...t,id:i,pluginId:e,localId:t.id,...n===void 0?{}:{machineId:n},visible:t=>this.isContributionActive(e,n,t.machine.id,r)&&(a?.(t)??!0),items:t=>this.isContributionActive(e,n,t.machine.id,r)?o(t):[]}}qualifyTheme(e,t){let n=this.qualify(e,t.id);return{...t,id:n,pluginId:e,localId:t.id}}qualifyThemePair(e,t){let n=this.qualify(e,t.id);return{...t,id:n,pluginId:e,localId:t.id,light:this.qualifyReference(e,t.light),dark:this.qualifyReference(e,t.dark)}}qualify(e,t){this.validateLocalId(t);let n=`${e}:${t}`;if(this.contributionIds.has(n))throw Error(`Duplicate contribution id: ${n}`);return this.contributionIds.add(n),n}qualifyReference(e,t){return this.validateLocalId(t),`${e}:${t}`}isContributionActive(e,t,n,r){return t===void 0?!this.isGatewayPluginHiddenForMachine(e,n):t===n&&!this.isRemotePluginHiddenByGateway(r,t)}isRemoteDuplicateHiddenByGateway(e,t,n){return e!==void 0&&t!==void 0&&this.gatewayPluginIds.has(e)&&!this.gatewayMachineSpecificPluginIds.has(e)&&!n}isRemotePluginHiddenByGateway(e,t){return e===void 0||this.gatewayMachineSpecificPluginIds.has(e)||this.remoteMachineSpecificPluginIds.get(e)?.has(t)===!0?!1:this.gatewayPluginIds.has(e)}isGatewayPluginHiddenForMachine(e,t){return t!==`local`&&(this.gatewayMachineSpecificPluginIds.has(e)||this.remoteMachineSpecificPluginIds.get(e)?.has(t)===!0)}validatePluginId(e){if(!rf.test(e))throw Error(`Invalid plugin id: ${e}`)}validateLocalId(e){if(!af.test(e))throw Error(`Invalid contribution id: ${e}`)}parseMachineSpecific(e,t){if(t===void 0)return!1;if(typeof t!=`boolean`)throw Error(`Invalid plugin machineSpecific value for ${e}: ${mf(t)}`);return t}};function lf(e,t){return of.get(e)?.(t)??e}function uf(e,t){return sf.get(e)?.(t)??e}function df(e,t){return of.set(e,t),e}function ff(e,t){return sf.set(e,t),e}function pf(e,t,n){let r=e.get(t);r===void 0?e.set(t,new Set([n])):r.add(n)}function mf(e){if(typeof e==`string`)return e;if(typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`||typeof e==`symbol`||typeof e==`function`||e==null)return String(e);try{return JSON.stringify(e)}catch{return Object.prototype.toString.call(e)}}function hf(e){return e.state.selectedMachine?.id??`local`}var gf=[`(display-mode: standalone)`,`(display-mode: fullscreen)`,`(display-mode: minimal-ui)`];function _f(){return typeof window>`u`||!(`matchMedia`in window)?[]:gf.map(e=>window.matchMedia(e))}function vf(e,t=yf()){return e.some(e=>e.matches)||bf(t)}function yf(){return typeof navigator>`u`?void 0:navigator}function bf(e){return e!==void 0&&`standalone`in e&&e.standalone===!0}var xf=class{constructor(e=Sf()){this.scheduler=e}repair(e){if(!e){this.clear();return}this.resetViewportScroll(),this.repairFrame!==void 0&&this.scheduler.cancelAnimationFrame(this.repairFrame),this.repairFrame=this.scheduler.requestAnimationFrame(()=>{this.repairFrame=void 0,this.resetViewportScroll(),this.repairFrame=this.scheduler.requestAnimationFrame(()=>{this.repairFrame=void 0,this.resetViewportScroll()})}),this.repairTimer!==void 0&&this.scheduler.clearTimeout(this.repairTimer),this.repairTimer=this.scheduler.setTimeout(()=>{this.repairTimer=void 0,this.resetViewportScroll()},250)}clear(){this.repairFrame!==void 0&&(this.scheduler.cancelAnimationFrame(this.repairFrame),this.repairFrame=void 0),this.repairTimer!==void 0&&(this.scheduler.clearTimeout(this.repairTimer),this.repairTimer=void 0)}resetViewportScroll(){this.scheduler.scrollTo(0,0);let e=this.scheduler.documentElement;e!==void 0&&(e.scrollTop=0);let t=this.scheduler.body;t!==void 0&&(t.scrollTop=0)}};function Sf(){return{requestAnimationFrame(e){return window.requestAnimationFrame(e)},cancelAnimationFrame(e){window.cancelAnimationFrame(e)},setTimeout(e,t){return window.setTimeout(e,t)},clearTimeout(e){window.clearTimeout(e)},scrollTo(e,t){window.scrollTo(e,t)},get documentElement(){return typeof document>`u`?void 0:document.documentElement},get body(){return typeof document>`u`?void 0:document.body}}}var Cf=`(max-width: 760px)`,wf=class{constructor(e,t={}){this.host=e,this.onMobileNavigationMediaChange=e=>{this.isMobileNavigationLayout!==e.matches&&(this.isMobileNavigationLayout=e.matches,this.host.requestUpdate())},this.onPwaDisplayModeChange=()=>{let e=vf(this.pwaDisplayModeMedia);this.isPwaDisplayMode!==e&&(this.isPwaDisplayMode=e,this.host.requestUpdate())},e.addController(this),this.mobileNavigationMedia=t.mobileNavigationMedia??Tf(),this.pwaDisplayModeMedia=t.pwaDisplayModeMedia??_f(),this.viewportPositionRepairer=t.viewportPositionRepairer??new xf,this.isMobileNavigationLayout=this.mobileNavigationMedia?.matches??!1,this.isPwaDisplayMode=vf(this.pwaDisplayModeMedia)}hostConnected(){this.mobileNavigationMedia?.addEventListener(`change`,this.onMobileNavigationMediaChange);for(let e of this.pwaDisplayModeMedia)e.addEventListener(`change`,this.onPwaDisplayModeChange)}hostDisconnected(){this.mobileNavigationMedia?.removeEventListener(`change`,this.onMobileNavigationMediaChange);for(let e of this.pwaDisplayModeMedia)e.removeEventListener(`change`,this.onPwaDisplayModeChange);this.viewportPositionRepairer.clear()}shouldAutoFocusPrompt(){return!this.isMobileNavigationLayout&&!this.isPwaDisplayMode}shouldShowAppRefreshInHeader(){return this.isPwaDisplayMode&&!this.isMobileNavigationLayout}shouldShowAppRefreshInContextBar(){return this.isPwaDisplayMode&&this.isMobileNavigationLayout}defaultRouteView(){return this.isMobileNavigationLayout?`navigation`:`chat`}repairViewportPosition(){this.viewportPositionRepairer.repair(this.shouldRepairViewportPosition())}shouldRepairViewportPosition(){return this.isMobileNavigationLayout||this.isPwaDisplayMode}};function Tf(){if(!(typeof window>`u`||!(`matchMedia`in window)))return window.matchMedia(Cf)}var Ef=class{constructor(e,t={}){this.callbacks=e,this.refreshes=new fa,this.connected=!1,this.onFocus=()=>{this.handleResumeSignal()},this.onVisibilityChange=()=>{this.isDocumentVisible()&&this.handleResumeSignal()},this.windowTarget=t.windowTarget??Df(),this.documentTarget=t.documentTarget??Of(),this.isDocumentVisible=t.isDocumentVisible??kf,this.scheduleFrame=t.scheduleFrame??Af}connect(){this.connected||(this.connected=!0,this.windowTarget?.addEventListener(`focus`,this.onFocus),this.documentTarget?.addEventListener(`visibilitychange`,this.onVisibilityChange))}disconnect(){this.connected&&(this.connected=!1,this.windowTarget?.removeEventListener(`focus`,this.onFocus),this.documentTarget?.removeEventListener(`visibilitychange`,this.onVisibilityChange),this.scheduledRefresh?.cancel(),this.scheduledRefresh=void 0)}handleResumeSignal(){this.callbacks.onResumeSignal(),this.scheduledRefresh===void 0&&(this.scheduledRefresh=this.scheduleFrame(()=>{this.scheduledRefresh=void 0,this.connected&&this.refreshes.request(`browser-resume`,async()=>{this.connected&&await this.callbacks.refreshAfterResume()}).catch(e=>{this.callbacks.onRefreshError(e)})}))}};function Df(){return typeof window>`u`?void 0:window}function Of(){return typeof document>`u`?void 0:document}function kf(){return typeof document>`u`||document.visibilityState===`visible`}function Af(e){if(typeof window<`u`&&typeof window.requestAnimationFrame==`function`){let t=window.requestAnimationFrame(()=>{e()});return{cancel:()=>{window.cancelAnimationFrame(t)}}}let t=globalThis.setTimeout(e,0);return{cancel:()=>{globalThis.clearTimeout(t)}}}var jf=[`machines`,`projects`,`workspaces`,`sessions`];function Mf(e){return e.selectedProject===void 0?`projects`:e.selectedWorkspace===void 0?`workspaces`:`sessions`}function Nf(e,t){if(e!==`none`)return e??Mf(t)}function Pf(e,t){return t.isMobileLayout?Nf(t.expanded,t.state)!==e:t.collapsedSections?.includes(e)??!1}function Ff(e,t,n){return n.isMobileLayout?Nf(e,n.state)===t?`none`:t:e}function If(e,t,n){return n?t:e}function Lf(e,t){let n=new Set(e);return n.has(t)?n.delete(t):n.add(t),Bf(n)}function Rf(e){return jf[jf.indexOf(e)+1]}var zf=class{hostConnected(){}constructor(e,t,n){this.host=e,this.getState=t,this.isMobileLayout=n,this.collapsedSections=[],e.addController(this)}expandedSection(){return Nf(this.expanded,this.getState())}isCollapsed(e){return Pf(e,{isMobileLayout:this.isMobileLayout(),expanded:this.expanded,state:this.getState(),collapsedSections:this.collapsedSections})}toggle(e){if(this.isMobileLayout()){this.setExpanded(Ff(this.expanded,e,{isMobileLayout:!0,state:this.getState()}));return}this.setCollapsedSections(Lf(this.collapsedSections,e))}expand(e){if(this.isMobileLayout()){this.setExpanded(If(this.expanded,e,!0));return}this.setCollapsedSections(this.collapsedSections.filter(t=>t!==e))}advanceAfterSelection(e){if(!this.isMobileLayout())return;let t=Rf(e);t!==void 0&&this.expand(t)}open(e,t){this.isMobileLayout()&&(this.expand(e),t())}setExpanded(e){this.expanded!==e&&(this.expanded=e,this.host.requestUpdate())}setCollapsedSections(e){Vf(this.collapsedSections,e)||(this.collapsedSections=e,this.host.requestUpdate())}};function Bf(e){let t=new Set(e);return jf.filter(e=>t.has(e))}function Vf(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}var Hf=class{hostConnected(){}constructor(e){this.host=e,this.navigationPanelCollapsed=!1,this.workspacePanelCollapsed=!1,e.addController(this)}toggleNavigationPanel(){this.navigationPanelCollapsed=!this.navigationPanelCollapsed,this.host.requestUpdate()}toggleWorkspacePanel(){this.workspacePanelCollapsed=!this.workspacePanelCollapsed,this.host.requestUpdate()}expandNavigationPanel(){this.navigationPanelCollapsed&&(this.navigationPanelCollapsed=!1,this.host.requestUpdate())}expandWorkspacePanel(){this.workspacePanelCollapsed&&(this.workspacePanelCollapsed=!1,this.host.requestUpdate())}shellClass(e){return[`shell`,Uf(e),...this.navigationPanelCollapsed?[`navigation-panel-collapsed`]:[],...this.workspacePanelCollapsed?[`workspace-panel-collapsed`]:[]].join(` `)}};function Uf(e){return e===`navigation`?`navigation-view`:e===`chat`?`chat-view`:`workspace-view`}var Wf=`pi-web:panel-sizes:v1`,Gf={navigation:{minWidth:180,maxWidth:4096,defaultWidth:340,keyboardStep:24,largeKeyboardStep:72},workspace:{minWidth:240,maxWidth:4096,defaultWidth:480,keyboardStep:24,largeKeyboardStep:72}},Kf=class{constructor(e,t={}){this.host=e,e.addController(this),this.storage=t.storage??op(),this.panelSizes=Qf(this.storage)}hostConnected(){}constraints(e){return qf(e)}panelWidth(e,t){return Zf(e,t??this.storedPanelWidth(e)??this.constraints(e).defaultWidth)}resizePanel(e,t,n={}){let r=Zf(e,t);this.storedPanelWidth(e)!==r&&(this.panelSizes=np(this.panelSizes,e,r),n.persist!==!1&&this.persistPanelSizes(),this.host.requestUpdate())}resetPanel(e,t={}){this.storedPanelWidth(e)!==void 0&&(this.panelSizes=rp(this.panelSizes,e),t.persist!==!1&&this.persistPanelSizes(),this.host.requestUpdate())}resetPanels(e={}){this.panelSizes.navigationPanelWidth===void 0&&this.panelSizes.workspacePanelWidth===void 0||(this.panelSizes={},e.persist!==!1&&this.persistPanelSizes(),this.host.requestUpdate())}persistPanelSizes(){$f(this.panelSizes,this.storage)}shellStyle(e={}){let t=[];return this.panelSizes.navigationPanelWidth!==void 0&&t.push(`--navigation-panel-size: ${ap(Zf(`navigation`,this.panelSizes.navigationPanelWidth,e.navigation))};`),this.panelSizes.workspacePanelWidth!==void 0&&t.push(`--workspace-panel-size: ${ap(Zf(`workspace`,this.panelSizes.workspacePanelWidth,e.workspace))};`),t.join(` `)}storedPanelWidth(e){return e===`navigation`?this.panelSizes.navigationPanelWidth:this.panelSizes.workspacePanelWidth}};function qf(e){return Gf[e]}function Jf(e,t,n){return e===`navigation`?n-t:t-n}function Yf(e,t,n,r,i=qf(e)){return Zf(e,t+Jf(e,n,r),i)}function Xf(e,t,n,r={}){let i=r.constraints??qf(e);if(n===`Home`)return i.minWidth;if(n===`End`)return i.maxWidth;let a=ip(e,n,r.largeStep===!0?i.largeKeyboardStep:i.keyboardStep);if(a!==void 0)return Zf(e,t+a,i)}function Zf(e,t,n=qf(e)){return Number.isFinite(t)?Math.round(Math.min(Math.max(t,n.minWidth),n.maxWidth)):n.defaultWidth}function Qf(e=op()){try{let t=e?.getItem(Wf);return t==null||t===``?{}:ep(JSON.parse(t))}catch{return{}}}function $f(e,t=op()){if(t!==void 0)try{if(e.navigationPanelWidth===void 0&&e.workspacePanelWidth===void 0){t.removeItem(Wf);return}let n={version:1};e.navigationPanelWidth!==void 0&&(n.navigationPanelWidth=Zf(`navigation`,e.navigationPanelWidth)),e.workspacePanelWidth!==void 0&&(n.workspacePanelWidth=Zf(`workspace`,e.workspacePanelWidth)),t.setItem(Wf,JSON.stringify(n))}catch{}}function ep(e){if(!sp(e)||e.version!==1)return{};let t={},n=tp(e.navigationPanelWidth),r=tp(e.workspacePanelWidth);return n!==void 0&&(t.navigationPanelWidth=Zf(`navigation`,n)),r!==void 0&&(t.workspacePanelWidth=Zf(`workspace`,r)),t}function tp(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function np(e,t,n){return t===`navigation`?{...e,navigationPanelWidth:n}:{...e,workspacePanelWidth:n}}function rp(e,t){return t===`navigation`?e.workspacePanelWidth===void 0?{}:{workspacePanelWidth:e.workspacePanelWidth}:e.navigationPanelWidth===void 0?{}:{navigationPanelWidth:e.navigationPanelWidth}}function ip(e,t,n){if(e===`navigation`)return t===`ArrowRight`?n:t===`ArrowLeft`?-n:void 0;if(t===`ArrowLeft`)return n;if(t===`ArrowRight`)return-n}function ap(e){return`${String(Math.round(e))}px`}function op(){try{return typeof window>`u`?void 0:window.localStorage}catch{return}}function sp(e){return typeof e==`object`&&!!e}function cp(){let e=new URLSearchParams(window.location.search);return{machineId:e.get(`machine`)??void 0,projectId:e.get(`project`)??void 0,workspaceId:e.get(`workspace`)??void 0,sessionId:e.get(`session`)??void 0,tool:up(e.get(`tool`)),view:dp(e.get(`view`))}}function lp(e,t){let n=new URL(window.location.href);n.searchParams.delete(`machine`),n.searchParams.delete(`project`),n.searchParams.delete(`workspace`),n.searchParams.delete(`session`),n.searchParams.delete(`tool`),n.searchParams.delete(`view`),e.machineId!==void 0&&e.machineId!==``&&e.machineId!==`local`&&n.searchParams.set(`machine`,e.machineId),e.projectId!==void 0&&e.projectId!==``&&n.searchParams.set(`project`,e.projectId),e.workspaceId!==void 0&&e.workspaceId!==``&&n.searchParams.set(`workspace`,e.workspaceId),e.sessionId!==void 0&&e.sessionId!==``&&n.searchParams.set(`session`,e.sessionId),e.tool!==void 0&&n.searchParams.set(`tool`,e.tool),e.view!==void 0&&n.searchParams.set(`view`,e.view),`${n.pathname}${n.search}${n.hash}`!=`${window.location.pathname}${window.location.search}${window.location.hash}`&&(t?.replace===!0?window.history.replaceState({},``,n):window.history.pushState({},``,n))}function up(e){return e===`files`?`core:workspace.files`:e===`git`?`core:workspace.git`:fp(e)?e:void 0}function dp(e){return e===`chat`?`chat`:e===`files`?`core:workspace.files`:e===`git`?`core:workspace.git`:fp(e)?e:void 0}function fp(e){return e!==null&&/^[a-z][a-z0-9.-]*:[a-z][a-z0-9.-]*$/u.test(e)}function pp(){return hp(new URLSearchParams(window.location.search).get(`settings`))}function mp(e,t){let n=new URL(window.location.href);e===void 0?n.searchParams.delete(`settings`):n.searchParams.set(`settings`,e),`${n.pathname}${n.search}${n.hash}`!=`${window.location.pathname}${window.location.search}${window.location.hash}`&&(t?.replace===!0?window.history.replaceState({},``,n):window.history.pushState({},``,n))}function hp(e){if(e===`general`)return`general`;if(e===`sessiond`||e===`sessions`)return`sessiond`;if(e===`packages`||e===`pi-packages`)return`packages`;if(e===`plugins`)return`plugins`;if(e===`shortcuts`||e===`keyboard`||e===`keyboard-shortcuts`)return`shortcuts`}function gp(e,t){return t===void 0?e:e.map(e=>vp(e,t))}function _p(e,t){let n=new Set(Al(e,t,{enabledOnly:!0}).filter(e=>e.active).map(e=>e.action.id));return gp(e,t).map(e=>e.shortcut!==void 0&&!n.has(e.id)?yp(e):e)}function vp(e,t){if(!Object.hasOwn(t,e.id))return e;let n=t[e.id];return n===void 0?e:n===null?yp(e):{...e,shortcut:n}}function yp(e){let t={...e};return delete t.shortcut,t}function bp(e,t){let n=t.api??Di,r=t.pollIntervalMs??1e3,i=t.setTimeout??Cp(),a=t.clearTimeout??wp();return{async runCommand(o){let s=await n.runTerminalCommand(e,o);return o.open===!0&&t.openTerminal(o.workspace,{terminalId:s.terminalId}),{run:s,completed:xp(s,n,r,i,a)}},listCommandRuns:e=>n.listCommandRuns(e),getCommandRun:e=>n.getCommandRun(e),open:e=>{t.openTerminal(void 0,e)}}}function xp(e,t,n,r,i){return Sp(e)?Promise.resolve(e):new Promise((a,o)=>{let s,c=!1,l=e=>{c||(c=!0,s!==void 0&&i(s),a(e))},u=e=>{c||(c=!0,s!==void 0&&i(s),o(e instanceof Error?e:Error(String(e))))},d=()=>{t.getCommandRun(e.id).then(e=>{if(e!==void 0&&Sp(e)){l(e);return}s=r(d,n)}).catch(u)};s=r(d,n)})}function Sp(e){return e.status===`succeeded`||e.status===`failed`}function Cp(){return(e,t)=>globalThis.setTimeout(e,t)}function wp(){return e=>{globalThis.clearTimeout(e)}}function Tp(e,t){return t[e.path]}function Ep(e){if(e?.hasSessionActivity===!0)return`session`;if(e?.hasTerminalActivity===!0)return`terminal`}function Dp(e,t,n){return kp(Ap(e,t,n))}function Op(e){return kp(Object.values(e??{}))}function kp(e){if(e.some(e=>e.hasSessionActivity))return`session`;if(e.some(e=>e.hasTerminalActivity))return`terminal`}function Ap(e,t,n){let r=new Set(t.filter(t=>t.projectId===e.id).map(e=>e.path)),i=new Map;for(let e of r){let t=n[e];t!==void 0&&i.set(t.cwd,t)}for(let t of Object.values(n))(t.cwd===e.path||t.cwd.startsWith(`${e.path}/`))&&i.set(t.cwd,t);return[...i.values()]}var jp=0,Mp=120;function Np(e,t={}){if(typeof HTMLElement>`u`||typeof window>`u`||!(e instanceof HTMLElement))return``;let n=e.getBoundingClientRect(),r=t.constrainTo===`viewport`?Fp():Pp(e),i=window.innerWidth,a=window.innerHeight,o=Math.max(0,r.left),s=Math.min(i,r.right),c=Math.max(0,r.top),l=Math.min(a,r.bottom),u=Math.min(n.right,s),d=l-n.bottom-jp,f=n.top-c-jp;return[...d<Mp&&f>d?[`bottom: ${Ip(a-n.top+jp)};`,`max-height: ${Ip(Math.max(0,f))};`]:[`top: ${Ip(n.bottom+jp)};`,`max-height: ${Ip(Math.max(0,d))};`],`right: ${Ip(Math.max(0,i-u))};`,`max-width: ${Ip(Math.max(0,u-o))};`].join(` `)}function Pp(e){let t=e.getRootNode();return typeof ShadowRoot<`u`&&t instanceof ShadowRoot&&t.host instanceof HTMLElement?t.host.getBoundingClientRect():Fp()}function Fp(){return{top:0,right:window.innerWidth,bottom:window.innerHeight,left:0}}function Ip(e){return`${String(Math.round(e))}px`}function Lp(e,t=`Active`){if(e!==void 0)return g`<span class=${`activity-indicator ${e}`} role="img" aria-label=${t} title=${t}></span>`}function Rp(e,t=`Active`){let n=Lp(e,t);if(n!==void 0)return g`<span class="action-activity">${n}</span>`}var zp=[`a[href]`,`button`,`input`,`select`,`textarea`,`summary`,`[role='button']`,`[role='link']`,`[contenteditable='true']`].join(`,`);function Bp(e){return e.composedPath().some(e=>Vp(e,zp))}function Vp(e,t){if(typeof Element<`u`&&e instanceof Element)return e.matches(t);if(!(`matches`in e))return!1;let{matches:n}=e;return typeof n==`function`&&n.call(e,t)===!0}function Hp(e,t){Bp(e)||t()}function Up(e,t){return Bp(e)?!1:e.key===`Enter`||e.key===` `?(e.preventDefault(),t.activate(),!0):e.key===`ArrowUp`?Gp(e,()=>{Kp(e.currentTarget,-1)}):e.key===`ArrowDown`?Gp(e,()=>{Kp(e.currentTarget,1)}):e.key===`Home`?Gp(e,()=>{qp(e.currentTarget,0)}):e.key===`End`?Gp(e,()=>{qp(e.currentTarget,-1)}):e.key===`ArrowLeft`&&t.previousSection!==void 0?Gp(e,t.previousSection):e.key===`ArrowRight`&&t.nextSection!==void 0?Gp(e,t.nextSection):e.key===`Escape`&&t.cancel!==void 0&&Gp(e,t.cancel)}function Wp(e,t={}){let n=e.querySelector(`.action-row.selected`)??e.querySelector(`.action-row`)??(t.fallbackSelector===void 0?void 0:e.querySelector(t.fallbackSelector));return n==null?!1:(n.focus(),n.scrollIntoView({block:`nearest`}),!0)}function Gp(e,t){return e.preventDefault(),e.stopPropagation?.(),t(),!0}function Kp(e,t){let n=Yp(e),r=Zp(e);if(r===void 0||n.length===0)return;let i=n.indexOf(r);i<0||Jp(n,i+t)}function qp(e,t){let n=Yp(e);n.length!==0&&Jp(n,t<0?n.length-1:t)}function Jp(e,t){let n=e[Math.min(Math.max(t,0),e.length-1)];n?.focus(),n?.scrollIntoView({block:`nearest`})}function Yp(e){let t=Zp(e)?.getRootNode();return t===void 0||!Xp(t)?[]:Array.from(t.querySelectorAll(`.action-row`))}function Xp(e){return typeof Document<`u`&&e instanceof Document||typeof DocumentFragment<`u`&&e instanceof DocumentFragment}function Zp(e){if(!(typeof HTMLElement>`u`||!(e instanceof HTMLElement)))return e.closest(`.action-row`)??void 0}var z=class extends v{constructor(...e){super(...e),this.machines=[],this.statuses={},this.activities={},this.collapsible=!1,this.collapsed=!1,this.menuStyle=``,this.onDocumentClick=e=>{e.composedPath().includes(this)||(this.openMenuMachineId=void 0)}}connectedCallback(){super.connectedCallback(),document.addEventListener(`click`,this.onDocumentClick)}disconnectedCallback(){document.removeEventListener(`click`,this.onDocumentClick),super.disconnectedCallback()}updated(e){e.has(`machines`)&&this.openMenuMachineId!==void 0&&!this.machines.some(e=>e.id===this.openMenuMachineId)&&(this.openMenuMachineId=void 0),e.has(`collapsed`)&&this.collapsed&&(this.openMenuMachineId=void 0)}async focusSelectedOrFirst(){return await this.updateComplete,Wp(this.renderRoot,{fallbackSelector:`.section-toggle`})}render(){return g`
714
- <section>
715
- <h2>${this.renderHeading()}</h2>
716
- ${this.collapsed?null:g`
717
- <div class="list-body">
718
- ${this.machines.map(e=>this.renderMachine(e))}
719
- </div>
720
- `}
721
- </section>
722
- `}renderMachine(e){let t=this.statuses[e.id]?.status??e.status??`unknown`,n=t===`online`?`online`:t===`offline`?`offline`:t===`error`?`error`:`unknown`,r=Qp(e)&&this.onRemove!==void 0;return g`
723
- <div
724
- class=${`action-row machine-row ${this.selected?.id===e.id?`selected`:``} ${r?``:`no-actions`}`}
725
- tabindex="0"
726
- title=${e.baseUrl??e.name}
727
- @click=${t=>{Hp(t,()=>this.onSelect?.(e))}}
728
- @keydown=${t=>{this.handleMachineKeydown(t,e)}}
729
- >
730
- <div class="action-main">
731
- <span class="action-name machine-primary"><span class="machine-primary-label">${e.name}</span></span><small>${e.kind===`local`?`Local Pi Web`:e.baseUrl??`Remote Pi Web`} · ${n}</small>
732
- ${this.renderActivity(e)}
733
- </div>
734
- ${r?this.renderMachineMenu(e):null}
735
- </div>
736
- `}renderActivity(e){let t=this.statuses[e.id]?.status??e.status;if(t===`offline`||t===`error`)return;let n=Op(this.activities[e.id]);return Rp(n,n===`terminal`?`Machine terminal active`:`Machine active`)}renderMachineMenu(e){let t=this.openMenuMachineId===e.id,n=$p(e.id);return g`
737
- <div class="action-menu">
738
- <button
739
- class="action-menu-toggle"
740
- title="Machine actions"
741
- aria-label=${`Actions for ${e.name}`}
742
- aria-expanded=${String(t)}
743
- aria-controls=${n}
744
- @click=${t=>{t.stopPropagation(),this.toggleMenu(e.id,t.currentTarget)}}
745
- >⋯</button>
746
- ${t?g`
747
- <div class="action-menu-panel machine-menu-panel" id=${n} style=${this.menuStyle} @click=${e=>{e.stopPropagation()}}>
748
- <button class="danger" title=${`Remove ${e.name}`} @click=${()=>{this.removeMachine(e)}}>Remove</button>
749
- </div>
750
- `:null}
751
- </div>
752
- `}renderHeading(){if(!this.collapsible)return`Machines`;let e=this.selected?.name??`No machine selected`,t=this.selected?.baseUrl??e;return g`<button class="section-toggle" aria-expanded=${String(!this.collapsed)} @click=${()=>{this.onToggleCollapsed?.()}}><span class="section-title"><span class="section-name">${this.collapsed?`▸`:`▾`} Machines</span>${this.collapsed?g`<small class="section-selected" title=${t}>${e}</small>`:null}</span><small class="section-count">${this.machines.length}</small></button>`}toggleMenu(e,t){if(this.openMenuMachineId===e){this.openMenuMachineId=void 0;return}this.menuStyle=Np(t,{constrainTo:`viewport`}),this.openMenuMachineId=e}removeMachine(e){this.openMenuMachineId=void 0,this.onRemove?.(e)}handleMachineKeydown(e,t){if(e.key===`Escape`&&this.openMenuMachineId===t.id){e.preventDefault(),e.stopPropagation(),this.openMenuMachineId=void 0;return}Up(e,{activate:()=>this.onSelect?.(t),nextSection:this.onFocusNextSection===void 0?void 0:()=>{this.onFocusNextSection?.()},cancel:this.onCancelKeyboardNavigation===void 0?void 0:()=>{this.onCancelKeyboardNavigation?.()}})}static{this.styles=[Zu,h`
753
- .machine-row.no-actions .action-main { border-radius: 8px; }
754
- .machine-primary { display: flex; align-items: baseline; gap: 6px; }
755
- .machine-primary-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
756
- .machine-menu-panel button.danger { color: var(--pi-danger); }
757
- .machine-menu-panel button.danger:hover, .machine-menu-panel button.danger:focus { background: color-mix(in srgb, var(--pi-danger) 14%, transparent); }
758
- `]}};R([b({attribute:!1})],z.prototype,`machines`,void 0),R([b({attribute:!1})],z.prototype,`selected`,void 0),R([b({attribute:!1})],z.prototype,`statuses`,void 0),R([b({attribute:!1})],z.prototype,`activities`,void 0),R([b({type:Boolean,reflect:!0})],z.prototype,`collapsible`,void 0),R([b({type:Boolean,reflect:!0})],z.prototype,`collapsed`,void 0),R([b({attribute:!1})],z.prototype,`onSelect`,void 0),R([b({attribute:!1})],z.prototype,`onRemove`,void 0),R([b({attribute:!1})],z.prototype,`onToggleCollapsed`,void 0),R([b({attribute:!1})],z.prototype,`onFocusNextSection`,void 0),R([b({attribute:!1})],z.prototype,`onCancelKeyboardNavigation`,void 0),R([x()],z.prototype,`openMenuMachineId`,void 0),R([x()],z.prototype,`menuStyle`,void 0),z=R([y(`machine-list`)],z);function Qp(e){return e.kind===`remote`}function $p(e){return`machine-menu-${e.replace(/[^a-zA-Z0-9_-]/g,`-`)}`}var B=class extends v{constructor(...e){super(...e),this.projects=[],this.activities={},this.workspacesByProjectId={},this.collapsible=!1,this.collapsed=!1,this.menuStyle=``,this.onDocumentClick=e=>{e.composedPath().includes(this)||(this.openMenuProjectId=void 0)}}connectedCallback(){super.connectedCallback(),document.addEventListener(`click`,this.onDocumentClick)}disconnectedCallback(){document.removeEventListener(`click`,this.onDocumentClick),super.disconnectedCallback()}updated(e){e.has(`projects`)&&this.openMenuProjectId!==void 0&&!this.projects.some(e=>e.id===this.openMenuProjectId)&&(this.openMenuProjectId=void 0),e.has(`collapsed`)&&this.collapsed&&(this.openMenuProjectId=void 0)}async focusSelectedOrFirst(){return await this.updateComplete,Wp(this.renderRoot,{fallbackSelector:`.section-toggle`})}render(){return g`
759
- <section>
760
- <h2>${this.renderHeading()}</h2>
761
- ${this.collapsed?null:g`
762
- <div class="list-body">
763
- ${this.projects.map(e=>g`
764
- <div
765
- class=${`action-row ${this.selected?.id===e.id?`selected`:``}`}
766
- tabindex="0"
767
- title=${e.path}
768
- @click=${t=>{Hp(t,()=>this.onSelect?.(e))}}
769
- @keydown=${t=>{this.handleProjectKeydown(t,e)}}
770
- >
771
- <div class="action-main">
772
- <span class="action-name">${e.name}</span><small>${e.path}</small>
773
- ${this.renderActivity(e)}
774
- </div>
775
- <div class="action-menu">
776
- <button class="action-menu-toggle" title="Project actions" aria-label=${`Actions for ${e.name}`} @click=${t=>{t.stopPropagation(),this.toggleMenu(e.id,t.currentTarget)}}>⋯</button>
777
- ${this.openMenuProjectId===e.id?g`
778
- <div class="action-menu-panel" style=${this.menuStyle}>
779
- <button title="Close project" @click=${()=>{this.close(e)}}>Close</button>
780
- </div>
781
- `:null}
782
- </div>
783
- </div>
784
- `)}
785
- </div>
786
- `}
787
- </section>
788
- `}handleProjectKeydown(e,t){Up(e,{activate:()=>this.onSelect?.(t),previousSection:this.onFocusPreviousSection===void 0?void 0:()=>{this.onFocusPreviousSection?.()},nextSection:this.onFocusNextSection===void 0?void 0:()=>{this.onFocusNextSection?.()},cancel:this.onCancelKeyboardNavigation===void 0?void 0:()=>{this.onCancelKeyboardNavigation?.()}})}renderHeading(){if(!this.collapsible)return`Projects`;let e=this.selected?.name??`No project selected`,t=this.selected?.path??e;return g`<button class="section-toggle" aria-expanded=${String(!this.collapsed)} @click=${()=>{this.onToggleCollapsed?.()}}><span class="section-title"><span class="section-name">${this.collapsed?`▸`:`▾`} Projects</span>${this.collapsed?g`<small class="section-selected" title=${t}>${e}</small>`:null}</span><small class="section-count">${this.projects.length}</small></button>`}renderActivity(e){let t=Dp(e,this.workspacesByProjectId[e.id]??[],this.activities);return Rp(t,t===`terminal`?`Project terminal active`:`Project active`)}toggleMenu(e,t){if(this.openMenuProjectId===e){this.openMenuProjectId=void 0;return}this.menuStyle=Np(t,{constrainTo:`viewport`}),this.openMenuProjectId=e}close(e){this.openMenuProjectId=void 0,confirm(`Close ${e.name}?\n\nThis only removes it from PI WEB; it will not change the project folder.`)&&this.onClose?.(e)}static{this.styles=Zu}};R([b({attribute:!1})],B.prototype,`projects`,void 0),R([b({attribute:!1})],B.prototype,`selected`,void 0),R([b({attribute:!1})],B.prototype,`activities`,void 0),R([b({attribute:!1})],B.prototype,`workspacesByProjectId`,void 0),R([b({type:Boolean,reflect:!0})],B.prototype,`collapsible`,void 0),R([b({type:Boolean,reflect:!0})],B.prototype,`collapsed`,void 0),R([b({attribute:!1})],B.prototype,`onSelect`,void 0),R([b({attribute:!1})],B.prototype,`onClose`,void 0),R([b({attribute:!1})],B.prototype,`onToggleCollapsed`,void 0),R([b({attribute:!1})],B.prototype,`onFocusPreviousSection`,void 0),R([b({attribute:!1})],B.prototype,`onFocusNextSection`,void 0),R([b({attribute:!1})],B.prototype,`onCancelKeyboardNavigation`,void 0),R([x()],B.prototype,`openMenuProjectId`,void 0),R([x()],B.prototype,`menuStyle`,void 0),B=R([y(`project-list`)],B);function em(e=[]){return e.map((e,t)=>g`${t===0?null:g`<span class="workspace-label-separator">·</span>`}${tm(e)}`)}function tm(e){if(e.type===`render`)return g`<span class="workspace-label-render">${e.render()}</span>`;if(e.type===`link`&&nm(e.href)){let t=e.target??`_blank`,n=t===`_blank`?`noopener noreferrer`:void 0;return g`<a class="workspace-label-item workspace-label-link" href=${e.href} title=${e.title??e.text} target=${t} rel=${n??void 0}>${e.text}</a>`}return g`<span class="workspace-label-item" title=${e.title??e.text}>${e.text}</span>`}function nm(e){let t=e.trim().toLowerCase();return t!==``&&!t.startsWith(`javascript:`)&&!t.startsWith(`data:`)}var V=class extends v{constructor(...e){super(...e),this.workspaces=[],this.collapsible=!1,this.collapsed=!1,this.workspaceLabelItems=()=>[],this.activities={},this.deletingWorkspaceIds=[],this.menuStyle=``,this.onDocumentClick=e=>{e.composedPath().includes(this)||(this.openMenuWorkspaceId=void 0)}}connectedCallback(){super.connectedCallback(),document.addEventListener(`click`,this.onDocumentClick)}disconnectedCallback(){document.removeEventListener(`click`,this.onDocumentClick),super.disconnectedCallback()}updated(e){e.has(`workspaces`)&&this.openMenuWorkspaceId!==void 0&&!this.workspaces.some(e=>e.id===this.openMenuWorkspaceId)&&(this.openMenuWorkspaceId=void 0),e.has(`collapsed`)&&this.collapsed&&(this.openMenuWorkspaceId=void 0),(e.has(`selected`)||e.has(`workspaces`)||e.has(`collapsed`))&&!this.collapsed&&this.scrollSelectedIntoView()}async focusSelectedOrFirst(){return await this.updateComplete,Wp(this.renderRoot,{fallbackSelector:`.section-toggle`})}render(){return g`
789
- <section>
790
- <h2>${this.renderHeading()}</h2>
791
- ${this.collapsed?null:g`
792
- <div class="list-body">
793
- ${this.workspaces.map(e=>{let t=rm(e),n=this.workspaceLabelItems(e);return g`
794
- <div
795
- class=${`action-row workspace-row ${this.selected?.id===e.id?`selected`:``}`}
796
- tabindex="0"
797
- title=${t}
798
- @click=${t=>{Hp(t,()=>this.onSelect?.(e))}}
799
- @keydown=${t=>{this.handleWorkspaceKeydown(t,e)}}
800
- >
801
- <div class="action-main">
802
- ${this.renderWorkspaceMain(t,n,e)}
803
- </div>
804
- ${this.renderWorkspaceMenu(t,n,e)}
805
- </div>
806
- `})}
807
- </div>
808
- `}
809
- </section>
810
- `}renderHeading(){if(!this.collapsible)return`Workspaces`;let e=this.selected===void 0?`No workspace selected`:`${this.selected.label}${this.selected.isMain?` · main`:``} · ${this.selected.path}`,t=this.selected?.path??e;return g`<button class="section-toggle" aria-expanded=${String(!this.collapsed)} @click=${()=>{this.onToggleCollapsed?.()}}><span class="section-title"><span class="section-name">${this.collapsed?`▸`:`▾`} Workspaces</span>${this.collapsed?g`<small class="section-selected" title=${t}>${e}</small>`:null}</span><small class="section-count">${this.workspaces.length}</small></button>`}renderActivity(e){let t=Ep(Tp(e,this.activities));return Rp(t,t===`terminal`?`Workspace terminal active`:`Workspace active`)}renderWorkspaceMain(e,t,n){return g`
811
- <span class="workspace-primary">
812
- <span class="workspace-primary-label">${e}</span>
813
- ${this.isDeleting(n)?g`<span class="workspace-status">Deleting…</span>`:null}
814
- </span>
815
- ${t.length===0?null:g`
816
- <small class="workspace-secondary">
817
- <span class="workspace-label">${em(t)}</span>
818
- </small>
819
- `}
820
- ${this.renderActivity(n)}
821
- `}renderWorkspaceMenu(e,t,n){let r=this.openMenuWorkspaceId===n.id,i=am(n.id);return g`
822
- <div class="action-menu">
823
- <button
824
- class="action-menu-toggle"
825
- title="Workspace actions and details"
826
- aria-label=${`Actions and details for ${e}`}
827
- aria-expanded=${String(r)}
828
- aria-controls=${i}
829
- @click=${e=>{e.stopPropagation(),this.toggleMenu(n.id,e.currentTarget)}}
830
- >⋯</button>
831
- ${r?g`
832
- <div class="action-menu-panel workspace-menu-panel" id=${i} style=${this.menuStyle} @click=${e=>{e.stopPropagation()}}>
833
- ${this.renderWorkspaceActions(n)}
834
- ${this.renderWorkspaceDetails(e,t,n)}
835
- </div>
836
- `:null}
837
- </div>
838
- `}renderWorkspaceActions(e){if(!im(e))return;let t=this.isDeleting(e);return g`
839
- <div class="workspace-menu-actions">
840
- <button class="danger" title=${t?`Workspace deletion in progress`:`Delete workspace`} ?disabled=${t} @click=${()=>{this.delete(e)}}>${t?`Deleting…`:`Delete workspace`}</button>
841
- </div>
842
- `}renderWorkspaceDetails(e,t,n){return g`
843
- <dl class="workspace-menu-details">
844
- <div class="workspace-detail-row">
845
- <dt>${n.branch===void 0?`Workspace`:`Branch`}</dt>
846
- <dd>${e}</dd>
847
- </div>
848
- <div class="workspace-detail-row">
849
- <dt>Path</dt>
850
- <dd title=${n.path}>${n.path}</dd>
851
- </div>
852
- ${t.length===0?null:g`
853
- <div class="workspace-detail-row">
854
- <dt>Details</dt>
855
- <dd><span class="workspace-label">${em(t)}</span></dd>
856
- </div>
857
- `}
858
- </dl>
859
- `}delete(e){this.isDeleting(e)||(this.openMenuWorkspaceId=void 0,this.onDelete?.(e))}isDeleting(e){return this.deletingWorkspaceIds.includes(e.id)}toggleMenu(e,t){if(this.openMenuWorkspaceId===e){this.openMenuWorkspaceId=void 0;return}this.menuStyle=Np(t,{constrainTo:`viewport`}),this.openMenuWorkspaceId=e}handleWorkspaceKeydown(e,t){if(e.key===`Escape`&&this.openMenuWorkspaceId===t.id){e.preventDefault(),e.stopPropagation(),this.openMenuWorkspaceId=void 0;return}Up(e,{activate:()=>this.onSelect?.(t),previousSection:this.onFocusPreviousSection===void 0?void 0:()=>{this.onFocusPreviousSection?.()},nextSection:this.onFocusNextSection===void 0?void 0:()=>{this.onFocusNextSection?.()},cancel:this.onCancelKeyboardNavigation===void 0?void 0:()=>{this.onCancelKeyboardNavigation?.()}})}scrollSelectedIntoView(){this.renderRoot.querySelector(`.action-row.selected`)?.scrollIntoView({block:`nearest`})}static{this.styles=Zu}};R([b({attribute:!1})],V.prototype,`workspaces`,void 0),R([b({attribute:!1})],V.prototype,`selected`,void 0),R([b({type:Boolean,reflect:!0})],V.prototype,`collapsible`,void 0),R([b({type:Boolean,reflect:!0})],V.prototype,`collapsed`,void 0),R([b({attribute:!1})],V.prototype,`workspaceLabelItems`,void 0),R([b({attribute:!1})],V.prototype,`activities`,void 0),R([b({attribute:!1})],V.prototype,`deletingWorkspaceIds`,void 0),R([b({attribute:!1})],V.prototype,`onSelect`,void 0),R([b({attribute:!1})],V.prototype,`onDelete`,void 0),R([b({attribute:!1})],V.prototype,`onToggleCollapsed`,void 0),R([b({attribute:!1})],V.prototype,`onFocusPreviousSection`,void 0),R([b({attribute:!1})],V.prototype,`onFocusNextSection`,void 0),R([b({attribute:!1})],V.prototype,`onCancelKeyboardNavigation`,void 0),R([x()],V.prototype,`openMenuWorkspaceId`,void 0),R([x()],V.prototype,`menuStyle`,void 0),V=R([y(`workspace-list`)],V);function rm(e){return`${e.branch??e.label}${e.isMain?` · main`:``}`}function im(e){return e.isGitWorktree&&!e.isMain}function am(e){return`workspace-menu-${e.replace(/[^a-zA-Z0-9_-]/g,`-`)}`}function om(e){return e.slice(-8)}function sm(e){return e.name!==void 0&&e.name!==``?e.name:e.firstMessage===``?om(e.id):e.firstMessage}var H=class extends v{constructor(...e){super(...e),this.sessions=[],this.statuses={},this.activities={},this.sending={},this.startingCount=0,this.canStart=!1,this.canDeleteArchived=!1,this.canReload=!1,this.canCleanup=!1,this.authoritativeSessionPersistence=!1,this.archivedDeleteUnavailableMessage=`Update and restart Pi-Web on this machine to delete archived sessions.`,this.cleanupUnavailableMessage=`Update and restart Pi-Web on this machine to clean up sessions.`,this.collapsible=!1,this.collapsed=!1,this.menuStyle=``,this.archivedExpanded=!1,this.selectionScopes=new Set,this.selectedSessionIds=new Set,this.onDocumentClick=e=>{e.composedPath().includes(this)||(this.openMenuSessionId=void 0)}}connectedCallback(){super.connectedCallback(),document.addEventListener(`click`,this.onDocumentClick)}disconnectedCallback(){document.removeEventListener(`click`,this.onDocumentClick),super.disconnectedCallback()}updated(e){e.has(`sessions`)&&(this.openMenuSessionId!==void 0&&!this.sessions.some(e=>e.id===this.openMenuSessionId)&&(this.openMenuSessionId=void 0),this.sessions.some(e=>e.archived===!0)||(this.archivedExpanded=!1),this.pruneSelectedSessionIds()),e.has(`collapsed`)&&this.collapsed&&(this.openMenuSessionId=void 0);let t=e.get(`selected`);if(e.has(`selected`)&&this.selected?.archived===!0&&(t?.id!==this.selected.id||t.archived!==!0)&&!this.archivedExpanded){this.archivedExpanded=!0,this.updateComplete.then(()=>{this.scrollSelectedIntoView()});return}(e.has(`selected`)||e.has(`sessions`)||e.has(`collapsed`))&&!this.collapsed&&this.scrollSelectedIntoView()}async focusSelectedOrFirst(){return await this.updateComplete,Wp(this.renderRoot,{fallbackSelector:`.section-toggle, h2 button:not([disabled])`})}render(){let e=fm(this.sessions),t=new Set(e.map(e=>e.session.id)),n=e.map(e=>e.session).filter(e=>cm(e)===`current`),r=pm(this.sessions.filter(e=>e.archived===!0&&!t.has(e.id))),i=um(this.sessions);return g`
860
- <section>
861
- ${this.renderHeading(e.length+r.length,n)}
862
- ${this.collapsed?null:g`
863
- <div class="list-body">
864
- ${this.renderCurrentSelectionToolbar(n)}
865
- ${this.startingCount>0?this.renderStartingSession():null}
866
- ${e.map(e=>this.renderSession(e,i.get(e.session.id)??0,`current`))}
867
- ${r.length>0?g`
868
- ${this.renderArchivedHeading(r.map(e=>e.session))}
869
- ${this.archivedExpanded?g`
870
- ${this.renderArchivedSelectionToolbar(r.map(e=>e.session))}
871
- ${r.map(e=>this.renderSession(e,i.get(e.session.id)??0,`archived`))}
872
- `:null}
873
- `:null}
874
- </div>
875
- `}
876
- </section>
877
- `}renderHeading(e,t){if(!this.collapsible)return g`
878
- <h2>
879
- Sessions
880
- ${this.renderCurrentSelectionButton(t)}
881
- ${this.renderCleanupButton()}
882
- ${this.renderStartButton()}
883
- </h2>
884
- `;let n=this.selected===void 0?`No session selected`:sm(this.selected),r=this.selected?.path??n;return g`
885
- <h2>
886
- <button class="section-toggle" aria-expanded=${String(!this.collapsed)} @click=${()=>{this.onToggleCollapsed?.()}}><span class="section-title"><span class="section-name">${this.collapsed?`▸`:`▾`} Sessions</span>${this.collapsed?g`<small class="section-selected" dir="auto" title=${r}>${n}</small>`:null}</span></button>
887
- ${this.renderCurrentSelectionButton(t)}
888
- <small class="section-count">${e}</small>
889
- ${this.renderCleanupButton()}
890
- ${this.renderStartButton()}
891
- </h2>
892
- `}renderCurrentSelectionButton(e){if(this.collapsed||e.length===0)return null;let t=this.selectionScopes.has(`current`);return g`<button class="bulk-select-entry ${t?`selected`:``}" title=${t?`Close current session selection`:`Select current sessions`} aria-label=${t?`Close current session selection`:`Select current sessions`} aria-expanded=${String(t)} aria-pressed=${String(t)} @click=${t=>{t.stopPropagation(),this.toggleSelection(`current`,e)}}>☑</button>`}renderCleanupButton(){return g`<button class="cleanup-entry" title=${this.canCleanup?`Preview session cleanup`:this.cleanupUnavailableMessage} @click=${e=>{e.stopPropagation(),this.onCleanup?.()}}>Clean up</button>`}renderStartButton(){let e=this.startingCount>0?`Start another session`:`Start a new session`;return g`<button class="start-session-button" title=${e} aria-label=${e} ?disabled=${!this.canStart} @click=${e=>{e.stopPropagation(),this.onStart?.()}}>+</button>`}renderStartingSession(){let e=this.startingCount!==1;return g`
893
- <div class="pending-session-row starting-session" role="status" aria-live="polite">
894
- <div class="action-main">
895
- <span class="action-name"><span class="activity-indicator sending" aria-hidden="true"></span>${e?`Starting ${String(this.startingCount)} sessions…`:`Starting session…`}</span>
896
- <small>Waiting for ${e?`new sessions`:`the new session`} to be created</small>
897
- </div>
898
- </div>
899
- `}renderArchivedHeading(e){let t=this.selectionScopes.has(`archived`);return g`
900
- <h2 class="subheading">
901
- <button class="section-toggle" aria-expanded=${String(this.archivedExpanded)} @click=${()=>{this.toggleArchived()}}><span>${this.archivedExpanded?`▾`:`▸`} Archived</span></button>
902
- ${this.archivedExpanded?g`<button class="bulk-select-entry ${t?`selected`:``}" title=${t?`Close archived session selection`:`Select archived sessions`} aria-label=${t?`Close archived session selection`:`Select archived sessions`} aria-expanded=${String(t)} aria-pressed=${String(t)} @click=${()=>{this.toggleSelection(`archived`,e)}}>☑</button>`:null}
903
- <small class="section-count">${e.length}</small>
904
- </h2>
905
- `}renderCurrentSelectionToolbar(e){if(e.length===0||!this.selectionScopes.has(`current`))return null;let t=this.selectedSessions(`current`),n=t.filter(e=>mc(e,this.statuses[e.id],this.sessionPersistenceOptions())),r=e.length>0&&e.every(e=>this.selectedSessionIds.has(e.id)),i=e.filter(e=>this.selectedSessionIds.has(e.id)).length;return g`
906
- <div class="bulk-row selecting">
907
- <button ?disabled=${e.length===0} @click=${()=>{this.toggleVisibleSelection(e,!r)}}>${r?`Clear visible`:`Select visible`}</button>
908
- <small>${t.length} selected${i===t.length?null:g` · ${i} visible`}</small>
909
- <button ?disabled=${n.length===0} @click=${()=>{this.archiveSelectedCurrent()}}>Archive selected</button>
910
- <button @click=${()=>{this.clearSelection(`current`)}}>Clear</button>
911
- <button @click=${()=>{this.closeSelection(`current`)}}>Done</button>
912
- </div>
913
- `}renderArchivedSelectionToolbar(e){if(e.length===0||!this.selectionScopes.has(`archived`))return null;let t=this.selectedSessions(`archived`),n=e.length>0&&e.every(e=>this.selectedSessionIds.has(e.id)),r=e.filter(e=>this.selectedSessionIds.has(e.id)).length;return g`
914
- <div class="bulk-row selecting">
915
- <button ?disabled=${e.length===0} @click=${()=>{this.toggleVisibleSelection(e,!n)}}>${n?`Clear visible`:`Select visible`}</button>
916
- <small>${t.length} selected${r===t.length?null:g` · ${r} visible`}</small>
917
- <button class="danger" title=${this.canDeleteArchived?`Permanently delete selected archived sessions`:this.archivedDeleteUnavailableMessage} ?disabled=${t.length===0||!this.canDeleteArchived} @click=${()=>{this.confirmDeleteSelectedArchived()}}>Delete selected</button>
918
- <button @click=${()=>{this.clearSelection(`archived`)}}>Clear</button>
919
- <button @click=${()=>{this.closeSelection(`archived`)}}>Done</button>
920
- ${this.canDeleteArchived?null:g`<small class="capability-hint">${this.archivedDeleteUnavailableMessage}</small>`}
921
- </div>
922
- `}renderSession(e,t,n){let{session:r}=e,i=Math.min(e.depth,2),a=cm(r)===n,o=this.selectionScopes.has(n),s=o&&a,c=s&&this.selectedSessionIds.has(r.id),l=this.statuses[r.id],u=this.activities[r.id],d=this.sessionPersistenceOptions(),f=mc(r,l,d),p=hc(r,l,d),m=f&&this.canReload;return g`
923
- <div
924
- class="action-row ${this.selected?.id===r.id?`selected`:``} ${c?`bulk-selected`:``} ${r.archived===!0?`archived`:``} ${o?`selecting`:``}"
925
- style=${`--depth:${String(i)}`}
926
- tabindex="0"
927
- title=${r.path}
928
- @click=${e=>{Hp(e,()=>{this.activateSessionRow(r,n)})}}
929
- @keydown=${e=>{this.handleSessionKeydown(e,r,n)}}
930
- >
931
- <div class="action-main ${o?`selecting`:``}">
932
- ${s?g`<input class="session-checkbox" type="checkbox" aria-label=${`Select ${sm(r)}`} .checked=${c} @click=${e=>{e.stopPropagation()}} @change=${()=>{this.toggleSelected(r.id)}}>`:null}
933
- <span class="action-name" dir="auto">${e.depth>0?g`<span class="tree-marker">↳</span>`:null}${sm(r)}${e.depth>2?g` <span class="badge">depth ${e.depth}</span>`:null}${e.hasMissingParent?g` <span class="badge">parent unavailable</span>`:null}</span><small>${this.renderSessionMetaPrefix(r,l,u)}${String(r.messageCount)} messages</small>
934
- ${this.renderActivity(r)}
935
- </div>
936
- <div class="action-menu">
937
- <button class="action-menu-toggle" title="Session actions" @click=${e=>{e.stopPropagation(),this.toggleMenu(r.id,e.currentTarget)}}>⋯</button>
938
- ${this.openMenuSessionId===r.id?g`
939
- <div class="action-menu-panel" style=${this.menuStyle}>
940
- ${r.archived===!0?g`
941
- <button title="Restore session" @click=${()=>{this.openMenuSessionId=void 0,this.onRestore?.(r)}}>Restore</button>
942
- <button class="danger" title=${this.canDeleteArchived?`Permanently delete archived session`:this.archivedDeleteUnavailableMessage} ?disabled=${!this.canDeleteArchived} @click=${()=>{this.openMenuSessionId=void 0,this.confirmDeleteArchived(r)}}>Delete archived session</button>
943
- `:p?g`<button title="Delete transient new session" @click=${()=>{this.openMenuSessionId=void 0,this.onDelete?.(r)}}>Delete</button>`:g`
944
- ${f?g`
945
- <button title="Archive session" @click=${()=>{this.openMenuSessionId=void 0,this.onArchive?.(r)}}>Archive</button>
946
- ${t>0?g`<button title="Archive this session and its descendants" @click=${()=>{this.openMenuSessionId=void 0,this.confirmArchiveWithDescendants(r,t)}}>Archive with descendants (${t})</button>`:null}
947
- `:null}
948
- ${r.parentSessionPath===void 0?null:g`<button title="Detach from parent" @click=${()=>{this.openMenuSessionId=void 0,this.onDetachParent?.(r)}}>Detach from parent</button>`}
949
- ${m?g`<button title=${ca(this.statuses[r.id],this.activities[r.id])?`Stop current session activity before reloading from disk`:`Reload session from disk without refreshing Pi runtime resources`} ?disabled=${ca(this.statuses[r.id],this.activities[r.id])} @click=${()=>{this.openMenuSessionId=void 0,this.onReload?.(r)}}>Reload from disk</button>`:null}
950
- `}
951
- </div>
952
- `:null}
953
- </div>
954
- </div>
955
- `}handleSessionKeydown(e,t,n){Up(e,{activate:()=>{this.activateSessionRow(t,n)},previousSection:this.onFocusPreviousSection===void 0?void 0:()=>{this.onFocusPreviousSection?.()},nextSection:this.onFocusNextSection===void 0?void 0:()=>{this.onFocusNextSection?.()},cancel:this.onCancelKeyboardNavigation===void 0?void 0:()=>{this.onCancelKeyboardNavigation?.()}})}activateSessionRow(e,t){if(this.selectionScopes.has(t)&&cm(e)===t){this.toggleSelected(e.id);return}this.onSelect?.(e)}confirmArchiveWithDescendants(e,t){let n=t===1?`descendant session`:`descendant sessions`;confirm(`Archive “${sm(e)}” and ${String(t)} ${n}?`)&&this.onArchiveWithDescendants?.(e)}confirmDeleteArchived(e){this.canDeleteArchived&&confirm(`Permanently delete archived session “${sm(e)}”? This cannot be undone.`)&&this.onDeleteArchived?.(e)}confirmDeleteSelectedArchived(){if(!this.canDeleteArchived)return;let e=this.selectedSessions(`archived`);if(e.length===0)return;let t=e.length===1?`archived session`:`archived sessions`;confirm(`Permanently delete ${String(e.length)} selected ${t}? This cannot be undone.`)&&(this.selectedSessionIds=lm(this.selectedSessionIds,e.map(e=>e.id)),this.onDeleteArchivedMany?.(e))}archiveSelectedCurrent(){let e=this.selectedSessions(`current`).filter(e=>mc(e,this.statuses[e.id],this.sessionPersistenceOptions()));this.selectedSessionIds=lm(this.selectedSessionIds,e.map(e=>e.id)),this.onArchiveMany?.(e)}toggleSelection(e,t){if(this.selectionScopes.has(e)){this.closeSelection(e);return}this.startSelection(e,t)}startSelection(e,t){this.selectionScopes=new Set([...this.selectionScopes,e]);let n=t.length===1?t[0]:void 0;n!==void 0&&(this.selectedSessionIds=new Set([...this.selectedSessionIds,n.id]))}closeSelection(e){this.selectionScopes=new Set([...this.selectionScopes].filter(t=>t!==e)),this.clearSelection(e)}clearSelection(e){let t=this.sessions.filter(t=>cm(t)===e).map(e=>e.id);this.selectedSessionIds=lm(this.selectedSessionIds,t)}toggleSelected(e){let t=new Set(this.selectedSessionIds);t.has(e)?t.delete(e):t.add(e),this.selectedSessionIds=t}toggleVisibleSelection(e,t){let n=new Set(this.selectedSessionIds);for(let r of e)t?n.add(r.id):n.delete(r.id);this.selectedSessionIds=n}selectedSessions(e){return this.sessions.filter(t=>this.selectedSessionIds.has(t.id)&&cm(t)===e)}pruneSelectedSessionIds(){let e=new Set(this.sessions.map(e=>e.id)),t=new Set([...this.selectedSessionIds].filter(t=>e.has(t)));t.size!==this.selectedSessionIds.size&&(this.selectedSessionIds=t),this.selectionScopes.has(`archived`)&&!this.sessions.some(e=>e.archived===!0)&&this.closeSelection(`archived`),this.selectionScopes.has(`current`)&&!this.sessions.some(e=>e.archived!==!0)&&this.closeSelection(`current`)}toggleMenu(e,t){if(this.openMenuSessionId===e){this.openMenuSessionId=void 0;return}this.menuStyle=Np(t,{constrainTo:`viewport`}),this.openMenuSessionId=e}toggleArchived(){this.archivedExpanded=!this.archivedExpanded,this.archivedExpanded||(this.openMenuSessionId=void 0,this.selectionScopes.has(`archived`)&&this.closeSelection(`archived`),this.onArchivedCollapsed?.())}scrollSelectedIntoView(){this.renderRoot.querySelector(`.action-row.selected`)?.scrollIntoView({block:`nearest`})}renderSessionMetaPrefix(e,t,n){return hc(e,t,this.sessionPersistenceOptions())?n?.phase===`active`?`creating · `:n?.phase===`error`?`error · `:`new · `:e.archived===!0?`read-only · `:``}sessionPersistenceOptions(){return{authoritative:this.authoritativeSessionPersistence}}renderActivity(e){let t=dm(e,this.statuses[e.id],this.activities[e.id],this.sending[e.id]===!0);return Rp(t,t===`sending`?`Sending message`:`Session active`)}static{this.styles=[Zu,h`
956
- h2 { min-height: 30px; }
957
- h2 > .section-count { flex: 0 0 auto; display: inline; color: var(--pi-muted); font-size: inherit; }
958
- .bulk-select-entry { box-sizing: border-box; flex: 0 0 auto; display: inline-grid; place-items: center; width: 30px; height: 30px; padding: 0; font-size: 13px; line-height: 1; text-transform: none; }
959
- .start-session-button { box-sizing: border-box; flex: 0 0 auto; display: inline-grid; place-items: center; min-width: 30px; height: 30px; padding: 0 9px; }
960
- .cleanup-entry { flex: 0 0 auto; padding: 5px 7px; font-size: 12px; text-transform: none; }
961
- .bulk-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 6px; }
962
- .bulk-row button { padding: 5px 7px; font-size: 12px; }
963
- .bulk-row small { display: inline; min-width: 0; color: var(--pi-muted); }
964
- .action-name, .section-selected { text-align: start; unicode-bidi: plaintext; }
965
- .bulk-row .capability-hint { flex: 1 0 100%; color: var(--pi-warning); }
966
- .bulk-row.selecting { padding: 6px; border: 1px solid var(--pi-border-muted); border-radius: 8px; background: color-mix(in srgb, var(--pi-surface) 65%, transparent); }
967
- button.danger, .action-menu-panel button.danger { color: var(--pi-danger); }
968
- button.danger:hover, .action-menu-panel button.danger:hover { background: color-mix(in srgb, var(--pi-danger) 14%, transparent); }
969
- .action-row.bulk-selected .action-main { border-color: var(--pi-accent); box-shadow: inset 3px 0 0 var(--pi-accent); }
970
- .pending-session-row { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); margin: 6px 0; cursor: default; }
971
- .pending-session-row.starting-session .action-main { border-radius: 8px; border-style: dashed; color: var(--pi-muted); }
972
- .pending-session-row.starting-session .action-name { display: flex; align-items: center; gap: 6px; max-height: none; -webkit-line-clamp: 1; }
973
- .pending-session-row.starting-session .activity-indicator { flex: 0 0 auto; margin: 0; }
974
- .action-main.selecting { padding-left: calc(32px + var(--depth, 0) * 16px); }
975
- .session-checkbox { position: absolute; top: 9px; left: calc(8px + var(--depth, 0) * 16px); z-index: 2; margin: 0; }
976
- `]}};R([b({attribute:!1})],H.prototype,`sessions`,void 0),R([b({attribute:!1})],H.prototype,`statuses`,void 0),R([b({attribute:!1})],H.prototype,`activities`,void 0),R([b({attribute:!1})],H.prototype,`sending`,void 0),R([b({attribute:!1})],H.prototype,`selected`,void 0),R([b({type:Number})],H.prototype,`startingCount`,void 0),R([b({type:Boolean})],H.prototype,`canStart`,void 0),R([b({type:Boolean})],H.prototype,`canDeleteArchived`,void 0),R([b({type:Boolean})],H.prototype,`canReload`,void 0),R([b({type:Boolean})],H.prototype,`canCleanup`,void 0),R([b({type:Boolean})],H.prototype,`authoritativeSessionPersistence`,void 0),R([b({type:String})],H.prototype,`archivedDeleteUnavailableMessage`,void 0),R([b({type:String})],H.prototype,`cleanupUnavailableMessage`,void 0),R([b({type:Boolean,reflect:!0})],H.prototype,`collapsible`,void 0),R([b({type:Boolean,reflect:!0})],H.prototype,`collapsed`,void 0),R([b({attribute:!1})],H.prototype,`onSelect`,void 0),R([b({attribute:!1})],H.prototype,`onStart`,void 0),R([b({attribute:!1})],H.prototype,`onToggleCollapsed`,void 0),R([b({attribute:!1})],H.prototype,`onArchivedCollapsed`,void 0),R([b({attribute:!1})],H.prototype,`onFocusPreviousSection`,void 0),R([b({attribute:!1})],H.prototype,`onFocusNextSection`,void 0),R([b({attribute:!1})],H.prototype,`onCancelKeyboardNavigation`,void 0),R([b({attribute:!1})],H.prototype,`onArchive`,void 0),R([b({attribute:!1})],H.prototype,`onArchiveWithDescendants`,void 0),R([b({attribute:!1})],H.prototype,`onArchiveMany`,void 0),R([b({attribute:!1})],H.prototype,`onRestore`,void 0),R([b({attribute:!1})],H.prototype,`onDelete`,void 0),R([b({attribute:!1})],H.prototype,`onDeleteArchived`,void 0),R([b({attribute:!1})],H.prototype,`onDeleteArchivedMany`,void 0),R([b({attribute:!1})],H.prototype,`onDetachParent`,void 0),R([b({attribute:!1})],H.prototype,`onReload`,void 0),R([b({attribute:!1})],H.prototype,`onCleanup`,void 0),R([x()],H.prototype,`openMenuSessionId`,void 0),R([x()],H.prototype,`menuStyle`,void 0),R([x()],H.prototype,`archivedExpanded`,void 0),R([x()],H.prototype,`selectionScopes`,void 0),R([x()],H.prototype,`selectedSessionIds`,void 0),H=R([y(`session-list`)],H);function cm(e){return e.archived===!0?`archived`:`current`}function lm(e,t){let n=new Set(t);return new Set([...e].filter(e=>!n.has(e)))}function um(e){let t=new Map;for(let n of e){if(n.parentSessionPath===void 0)continue;let e=t.get(n.parentSessionPath)??[];e.push(n),t.set(n.parentSessionPath,e)}let n=(e,r)=>{if(r.has(e.path))return 0;let i=new Set(r);i.add(e.path);let a=0;for(let r of t.get(e.path)??[])i.has(r.path)||(r.archived!==!0&&(a+=1),a+=n(r,i));return a};return new Map(e.map(e=>[e.id,n(e,new Set)]))}function dm(e,t,n,r){if(!($a(e)||e.archived===!0))return r?`sending`:ca(t,n)?`session`:void 0}function fm(e){let t=new Map(e.map(e=>[e.path,e])),n=new Set;for(let r of e){if(r.archived===!0)continue;n.add(r.id);let e=r.parentSessionPath,i=new Set([r.path]);for(;e!==void 0&&!i.has(e);){i.add(e);let r=t.get(e);if(r===void 0)break;n.add(r.id),e=r.parentSessionPath}}return pm(e.filter(e=>n.has(e.id)))}function pm(e){let t=new Map(e.map(e=>[e.path,e])),n=new Map,r=[];for(let i of e){let e=i.parentSessionPath,a=e===void 0?void 0:t.get(e);if(a===void 0){r.push(i);continue}let o=n.get(a.path)??[];o.push(i),n.set(a.path,o)}let i=[],a=(e,r,o)=>{if(o.has(e.path))return;let s=e.parentSessionPath;i.push({session:e,depth:r,hasMissingParent:s!==void 0&&!t.has(s)});let c=new Set(o);c.add(e.path);for(let t of n.get(e.path)??[])a(t,r+1,c)};for(let e of r)a(e,0,new Set);return i}var U=class extends v{constructor(...e){super(...e),this.canCleanup=!0,this.unavailableMessage=`Update and restart Pi-Web on this machine to clean up sessions.`,this.loading=!1,this.running=!1,this.error=``,this.draft={...tu},this.formError=``}willUpdate(e){e.has(`preview`)&&(this.selectedProjectCwds=this.preview?.projects.map(e=>e.cwd))}render(){let e=nu(this.draft),t=this.selectedPreview(),n=iu({canCleanup:this.canCleanup,draft:this.draft,preview:t,previewRequest:this.previewRequest,loading:this.loading,running:this.running}),r=n?`Run cleanup`:t!==void 0&&!au(t)?`Select at least one project to run cleanup`:`Preview cleanup before running it`;return g`
977
- <div class="backdrop" @mousedown=${()=>{this.onClose?.()}}>
978
- <section role="dialog" aria-modal="true" aria-label="Clean up sessions" @mousedown=${e=>{e.stopPropagation()}} @keydown=${e=>{this.handleKeyDown(e)}}>
979
- <header>
980
- <div>
981
- <span class="eyebrow">Sessions</span>
982
- <h1>Clean up sessions</h1>
983
- </div>
984
- <button class="close-button" title="Close cleanup" aria-label="Close cleanup" @click=${()=>{this.onClose?.()}}>×</button>
985
- </header>
986
- <div class="body">
987
- <p class="intro">Preview manual cleanup for this machine before archiving idle sessions or permanently deleting old archived sessions.</p>
988
- ${this.canCleanup?this.renderForm(e.ok?``:e.error):this.renderUnavailable()}
989
- ${this.renderMessage()}
990
- ${this.preview===void 0?null:this.renderPreview(this.preview)}
991
- ${this.result===void 0?null:this.renderResult(this.result)}
992
- </div>
993
- <footer>
994
- <button @click=${()=>{this.onClose?.()}}>${this.result===void 0?`Cancel`:`Close`}</button>
995
- <button ?disabled=${!this.canCleanup||this.loading||this.running} @click=${()=>{this.previewCleanup()}}>${this.loading?`Previewing…`:`Preview`}</button>
996
- <button class="danger" ?disabled=${!n} title=${r} @click=${()=>{this.runCleanup()}}>${this.running?`Running…`:`Run cleanup`}</button>
997
- </footer>
998
- </section>
999
- </div>
1000
- `}renderForm(e){let t=this.loading||this.running,n=nu(this.draft),r=this.preview!==void 0&&n.ok&&ru(n.request)!==ru(this.previewRequest)&&au(this.preview);return g`
1001
- <fieldset ?disabled=${t}>
1002
- <label class="toggle-row">
1003
- <input type="checkbox" .checked=${this.draft.archiveIdleEnabled} @change=${e=>{this.updateDraft({archiveIdleEnabled:mm(e)})}}>
1004
- <span>Archive non-archived sessions idle for more than</span>
1005
- <input class="days" type="number" min="0" step="1" inputmode="numeric" .value=${this.draft.archiveIdleDays} ?disabled=${t||!this.draft.archiveIdleEnabled} @input=${e=>{this.updateDraft({archiveIdleDays:hm(e)})}}>
1006
- <span>days</span>
1007
- </label>
1008
- <label class="toggle-row delete-row">
1009
- <input type="checkbox" .checked=${this.draft.deleteArchivedEnabled} @change=${e=>{this.updateDraft({deleteArchivedEnabled:mm(e)})}}>
1010
- <span>Delete archived sessions archived for more than</span>
1011
- <input class="days" type="number" min="0" step="1" inputmode="numeric" .value=${this.draft.deleteArchivedDays} ?disabled=${t||!this.draft.deleteArchivedEnabled} @input=${e=>{this.updateDraft({deleteArchivedDays:hm(e)})}}>
1012
- <span>days</span>
1013
- </label>
1014
- </fieldset>
1015
- <p class="warning"><strong>Deletion is permanent.</strong> Cleanup only deletes sessions that are already archived.</p>
1016
- ${e===``?null:g`<div class="dialog-error" role="alert">${e}</div>`}
1017
- ${r?g`<div class="hint" role="status">Thresholds changed. Preview again before running cleanup.</div>`:null}
1018
- `}renderUnavailable(){return g`<div class="unavailable" role="status">${this.unavailableMessage}</div>`}renderMessage(){let e=this.formError||this.error;return e===``?null:g`<div class="dialog-error" role="alert">${e}</div>`}renderPreview(e){let t=this.selectedProjectCwdsForPreview(),n=new Set(t),r=su(e,t);return g`
1019
- <section class="preview" aria-label="Cleanup preview">
1020
- <h2>Preview</h2>
1021
- ${e.projects.length===0?g`<p class="empty">No sessions match these thresholds.</p>`:g`
1022
- ${this.renderSelectionControls(e,t)}
1023
- <div class="table-scroll" tabindex="0" aria-label="Cleanup projects table">
1024
- <table>
1025
- <thead>
1026
- <tr><th>Clean up</th><th>Project/workspace path</th><th>Archive</th><th>Delete archived</th></tr>
1027
- </thead>
1028
- <tbody>
1029
- ${e.projects.map(e=>this.renderProjectRow(e,n.has(e.cwd)))}
1030
- </tbody>
1031
- <tfoot>
1032
- <tr><th colspan="2">Selected totals</th><td>${r.totals.archiveCount}</td><td>${r.totals.deleteCount}</td></tr>
1033
- </tfoot>
1034
- </table>
1035
- </div>
1036
- `}
1037
- ${e.skippedBusySessionIds===void 0||e.skippedBusySessionIds.length===0?null:g`<p class="hint">${e.skippedBusySessionIds.length} busy ${e.skippedBusySessionIds.length===1?`session was`:`sessions were`} skipped.</p>`}
1038
- </section>
1039
- `}renderSelectionControls(e,t){let n=this.loading||this.running;return g`
1040
- <div class="selection-controls" role="group" aria-label="Project selection">
1041
- <span>${t.length} of ${e.projects.length} projects selected</span>
1042
- <button ?disabled=${n||t.length===e.projects.length} @click=${()=>{this.selectAllProjects()}}>Select all</button>
1043
- <button ?disabled=${n||t.length===0} @click=${()=>{this.deselectAllProjects()}}>Deselect all</button>
1044
- </div>
1045
- ${t.length===0?g`<p class="hint" role="status">Select at least one project to run cleanup.</p>`:null}
1046
- `}renderProjectRow(e,t){return g`
1047
- <tr class=${t?``:`unselected`}>
1048
- <td class="select-cell"><input type="checkbox" aria-label=${`Clean up ${e.cwd}`} .checked=${t} ?disabled=${this.running} @change=${t=>{this.setProjectSelected(e.cwd,mm(t))}}></td>
1049
- <th title=${e.cwd} dir="auto">${e.cwd}</th>
1050
- <td>${e.archiveCount}</td>
1051
- <td>${e.deleteCount}</td>
1052
- </tr>
1053
- `}renderResult(e){return g`
1054
- <section class="result" aria-label="Cleanup result">
1055
- <h2>Cleanup complete</h2>
1056
- <p>Archived ${e.archivedSessionIds.length} ${e.archivedSessionIds.length===1?`session`:`sessions`}; permanently deleted ${e.deletedSessionIds.length} archived ${e.deletedSessionIds.length===1?`session`:`sessions`}.</p>
1057
- </section>
1058
- `}updateDraft(e){this.draft={...this.draft,...e},this.formError=``}selectedPreview(){return this.preview===void 0?void 0:su(this.preview,this.selectedProjectCwdsForPreview())}selectedProjectCwdsForPreview(){return this.preview===void 0?[]:ou(this.preview,this.selectedProjectCwds)}selectAllProjects(){this.selectedProjectCwds=this.preview?.projects.map(e=>e.cwd)??[],this.formError=``}deselectAllProjects(){this.selectedProjectCwds=[],this.formError=``}setProjectSelected(e,t){let n=this.preview;if(n===void 0)return;let r=new Set(this.selectedProjectCwdsForPreview());t?r.add(e):r.delete(e),this.selectedProjectCwds=n.projects.map(e=>e.cwd).filter(e=>r.has(e)),this.formError=``}previewCleanup(){let e=nu(this.draft);if(!e.ok){this.formError=e.error;return}this.formError=``,this.onPreview?.(e.request)}runCleanup(){let e=nu(this.draft);if(!e.ok){this.formError=e.error;return}let t=this.selectedPreview(),n=this.selectedProjectCwdsForPreview();if(!iu({canCleanup:this.canCleanup,draft:this.draft,preview:t,previewRequest:this.previewRequest})){this.formError=t!==void 0&&!au(t)?`Select at least one project to run cleanup.`:`Preview cleanup before running it.`;return}t===void 0||!cu(t,e=>confirm(e))||(this.formError=``,this.onRun?.({...e.request,projectCwds:n}))}handleKeyDown(e){e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),this.onClose?.())}static{this.styles=h`
1059
- :host { position: fixed; inset: 0; z-index: 30; color: var(--pi-text); font: 14px system-ui, sans-serif; }
1060
- .backdrop { box-sizing: border-box; width: 100%; height: 100dvh; display: grid; place-items: center; padding: max(20px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) max(20px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left)); background: var(--pi-overlay); overflow: hidden; }
1061
- section[role="dialog"] { width: min(760px, 100%); max-height: min(760px, 100%); display: grid; grid-template-rows: auto minmax(0, 1fr) auto; border: 1px solid var(--pi-border); border-radius: 14px; background: var(--pi-bg); box-shadow: 0 20px 60px var(--pi-shadow-strong); overflow: hidden; }
1062
- header, footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--pi-border); }
1063
- footer { border-top: 1px solid var(--pi-border); border-bottom: 0; justify-content: end; }
1064
- .body { min-height: 0; overflow: auto; display: grid; gap: 14px; padding: 16px; }
1065
- .eyebrow { display: block; color: var(--pi-muted); font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
1066
- h1, h2, p { margin: 0; }
1067
- h1 { font-size: 20px; line-height: 1.2; }
1068
- h2 { font-size: 15px; }
1069
- .intro, .hint, .empty { color: var(--pi-muted); }
1070
- fieldset { margin: 0; padding: 0; border: 0; display: grid; gap: 10px; }
1071
- .toggle-row { display: grid; grid-template-columns: auto minmax(0, max-content) 88px auto; align-items: center; gap: 8px; color: var(--pi-text); }
1072
- input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--pi-accent); }
1073
- input.days { box-sizing: border-box; width: 88px; min-width: 0; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); color: var(--pi-text); padding: 8px 9px; font: var(--pi-control-font-size, 16px) var(--pi-control-font-family, system-ui, sans-serif); }
1074
- input.days:disabled { opacity: .55; }
1075
- .warning, .unavailable, .dialog-error, .result { border: 1px solid var(--pi-border); border-radius: 10px; padding: 10px 12px; }
1076
- .warning { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); color: var(--pi-text); }
1077
- .unavailable { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); color: var(--pi-warning); }
1078
- .dialog-error { border-color: var(--pi-danger); background: color-mix(in srgb, var(--pi-danger) 10%, var(--pi-bg)); color: var(--pi-danger); }
1079
- .result { border-color: var(--pi-success-border); background: var(--pi-success-bg); }
1080
- .preview { display: grid; gap: 10px; min-width: 0; }
1081
- .selection-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
1082
- .selection-controls span { color: var(--pi-muted); }
1083
- .selection-controls button { padding: 5px 7px; font-size: 12px; }
1084
- .table-scroll { max-width: 100%; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: thin; -webkit-overflow-scrolling: touch; border: 1px solid var(--pi-border); border-radius: 10px; }
1085
- table { width: 100%; min-width: 620px; border-collapse: collapse; }
1086
- th, td { border-bottom: 1px solid var(--pi-border-muted); padding: 8px 10px; text-align: right; }
1087
- thead th:first-child, td.select-cell { width: 72px; text-align: center; }
1088
- th:nth-child(2), td:nth-child(2) { text-align: left; }
1089
- tbody tr.unselected { opacity: .58; }
1090
- tbody th { max-width: 380px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-weight: 500; }
1091
- tfoot th, tfoot td { border-bottom: 0; font-weight: 700; }
1092
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; font: inherit; cursor: pointer; }
1093
- button:disabled { opacity: .5; cursor: not-allowed; }
1094
- button.danger { color: var(--pi-danger); }
1095
- button.danger:not(:disabled):hover { background: color-mix(in srgb, var(--pi-danger) 14%, transparent); }
1096
- .close-button { width: 34px; height: 34px; display: grid; place-items: center; border: 0; background: transparent; color: var(--pi-muted); padding: 0; font-size: 24px; }
1097
- .close-button:hover, .close-button:focus { color: var(--pi-text); background: var(--pi-surface-hover); }
1098
-
1099
- @media (max-width: 680px) {
1100
- .backdrop { padding: 0; place-items: stretch; }
1101
- section[role="dialog"] { width: 100%; height: 100dvh; max-height: none; border: 0; border-radius: 0; }
1102
- .toggle-row { grid-template-columns: auto minmax(0, 1fr); }
1103
- .toggle-row input.days { grid-column: 2; }
1104
- .toggle-row span:last-child { grid-column: 2; }
1105
- table { min-width: 560px; }
1106
- thead th:first-child, td.select-cell { width: 58px; }
1107
- }
1108
- `}};R([b({type:Boolean})],U.prototype,`canCleanup`,void 0),R([b({type:String})],U.prototype,`unavailableMessage`,void 0),R([b({attribute:!1})],U.prototype,`preview`,void 0),R([b({attribute:!1})],U.prototype,`previewRequest`,void 0),R([b({attribute:!1})],U.prototype,`result`,void 0),R([b({type:Boolean})],U.prototype,`loading`,void 0),R([b({type:Boolean})],U.prototype,`running`,void 0),R([b({type:String})],U.prototype,`error`,void 0),R([b({attribute:!1})],U.prototype,`onPreview`,void 0),R([b({attribute:!1})],U.prototype,`onRun`,void 0),R([b({attribute:!1})],U.prototype,`onClose`,void 0),R([x()],U.prototype,`draft`,void 0),R([x()],U.prototype,`formError`,void 0),R([x()],U.prototype,`selectedProjectCwds`,void 0),U=R([y(`session-cleanup-dialog`)],U);function mm(e){return e.target instanceof HTMLInputElement&&e.target.checked}function hm(e){return e.target instanceof HTMLInputElement?e.target.value:``}var gm={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},_m=e=>(...t)=>({_$litDirective$:e,values:t}),vm=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)}},{I:ym}=lt,bm=e=>e,xm=()=>document.createComment(``),Sm=(e,t,n)=>{let r=e._$AA.parentNode,i=t===void 0?e._$AB:t._$AA;if(n===void 0)n=new ym(r.insertBefore(xm(),i),r.insertBefore(xm(),i),e,e.options);else{let t=n._$AB.nextSibling,a=n._$AM,o=a!==e;if(o){let t;n._$AQ?.(e),n._$AM=e,n._$AP!==void 0&&(t=e._$AU)!==a._$AU&&n._$AP(t)}if(t!==i||o){let e=n._$AA;for(;e!==t;){let t=bm(e).nextSibling;bm(r).insertBefore(e,i),e=t}}}return n},Cm=(e,t,n=e)=>(e._$AI(t,n),e),wm={},Tm=(e,t=wm)=>e._$AH=t,Em=e=>e._$AH,Dm=e=>{e._$AR(),e._$AA.remove()},Om=(e,t,n)=>{let r=new Map;for(let i=t;i<=n;i++)r.set(e[i],i);return r},km=_m(class extends vm{constructor(e){if(super(e),e.type!==gm.CHILD)throw Error(`repeat() can only be used in text expressions`)}dt(e,t,n){let r;n===void 0?n=t:t!==void 0&&(r=t);let i=[],a=[],o=0;for(let t of e)i[o]=r?r(t,o):o,a[o]=n(t,o),o++;return{values:a,keys:i}}render(e,t,n){return this.dt(e,t,n).values}update(e,[t,n,r]){let i=Em(e),{values:a,keys:o}=this.dt(t,n,r);if(!Array.isArray(i))return this.ut=o,a;let s=this.ut??=[],c=[],l,u,d=0,f=i.length-1,p=0,m=a.length-1;for(;d<=f&&p<=m;)if(i[d]===null)d++;else if(i[f]===null)f--;else if(s[d]===o[p])c[p]=Cm(i[d],a[p]),d++,p++;else if(s[f]===o[m])c[m]=Cm(i[f],a[m]),f--,m--;else if(s[d]===o[m])c[m]=Cm(i[d],a[m]),Sm(e,c[m+1],i[d]),d++,m--;else if(s[f]===o[p])c[p]=Cm(i[f],a[p]),Sm(e,i[d],i[f]),f--,p++;else if(l===void 0&&(l=Om(o,p,m),u=Om(s,d,f)),l.has(s[d]))if(l.has(s[f])){let t=u.get(o[p]),n=t===void 0?null:i[t];if(n===null){let t=Sm(e,i[d]);Cm(t,a[p]),c[p]=t}else c[p]=Cm(n,a[p]),Sm(e,i[d],n),i[t]=null;p++}else Dm(i[f]),f--;else Dm(i[d]),d++;for(;p<=m;){let t=Sm(e,c[m+1]);Cm(t,a[p]),c[p++]=t}for(;d<=f;){let e=i[d++];e!==null&&Dm(e)}return this.ut=o,Tm(e,c),Ye}}),Am=`pi-web:chat-groups:`,jm={read(e){try{if(typeof localStorage>`u`)return;let t=localStorage.getItem(Nm(e));return t===null||t===``?void 0:Pm(JSON.parse(t))}catch{return}},write(e,t){try{if(typeof localStorage>`u`)return;localStorage.setItem(Nm(e),JSON.stringify(t))}catch{}}},Mm=class{constructor(e=jm){this.storage=e,this.sessionId=``,this.openGroupKeys=new Set,this.closedDefaultOpenGroupKeys=new Set}syncSession(e){if(this.sessionId===e)return;this.sessionId=e;let t=e===``?void 0:this.storage.read(e);this.openGroupKeys=new Set(t?.open??[]),this.closedDefaultOpenGroupKeys=new Set(t?.closedDefaultOpen??[])}isOpen(e,t){return t?!this.closedDefaultOpenGroupKeys.has(e):this.openGroupKeys.has(e)}applyToggle(e,t,n){let r=this.isOpen(e,n),i=new Set(this.openGroupKeys),a=new Set(this.closedDefaultOpenGroupKeys);return n?(i.delete(e),t?a.delete(e):a.add(e)):(a.delete(e),t?i.add(e):i.delete(e)),(n?!a.has(e):i.has(e))===r&&Im(i,this.openGroupKeys)&&Im(a,this.closedDefaultOpenGroupKeys)?!1:(this.openGroupKeys=i,this.closedDefaultOpenGroupKeys=a,this.persist(),!0)}snapshot(){return{open:[...this.openGroupKeys],closedDefaultOpen:[...this.closedDefaultOpenGroupKeys]}}persist(){this.sessionId!==``&&this.storage.write(this.sessionId,this.snapshot())}};function Nm(e){return`${Am}${e}`}function Pm(e){if(Array.isArray(e))return{open:Fm(e),closedDefaultOpen:[]};if(Lm(e))return{open:Array.isArray(e.open)?Fm(e.open):[],closedDefaultOpen:Array.isArray(e.closedDefaultOpen)?Fm(e.closedDefaultOpen):[]}}function Fm(e){return e.filter(e=>typeof e==`string`)}function Im(e,t){if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0}function Lm(e){return typeof e==`object`&&!!e}function Rm(e,t=0){let n=[],r=[],i=0,a=(e,t)=>{r.length||(i=t),r.push(e)},o=()=>{r.length&&(n.push({kind:`group`,messages:r,startIndex:i,endIndex:i+r.length-1}),r=[])};return e.forEach((e,r)=>{let i=e.parts.filter(t=>Hm(e,t)),s=e.parts.filter(t=>!Hm(e,t)),c=t+r,l={...e.source===void 0?{}:{source:e.source},...e.meta===void 0?{}:{meta:e.meta}};if(s.length&&a({role:e.role,parts:s,...l},c),i.length){o();let t={role:i.every(e=>e.type===`skillRead`)?`skill`:e.role,parts:i,...l};if(Bm(t)){let e=Vm(s);n.push({kind:`tool-image`,message:t,index:c,...e===void 0?{}:{toolName:e}})}else n.push({kind:`message`,message:t,index:c})}}),o(),n}function zm(e){if(e.every(e=>e.source===`compaction`))return`${String(e.length)} history compaction ${e.length===1?`summary`:`summaries`}`;if(e.every(e=>e.source===`branch_summary`))return`${String(e.length)} branch ${e.length===1?`summary`:`summaries`}`;let t=e.reduce((e,t)=>(e[t.role]=(e[t.role]??0)+1,e),{}),n=Object.entries(t).map(([e,t])=>`${String(t)} ${e}`).join(` · `);return`${String(e.length)} ${e.length===1?`event`:`events`}${n===``?``:` · ${n}`}`}function Bm(e){return e.role===`tool`&&e.parts.length>0&&e.parts.every(e=>e.type===`image`)}function Vm(e){for(let t of e)if((t.type===`toolCall`||t.type===`toolExecution`||t.type===`toolResult`)&&t.toolName!==``)return t.toolName}function Hm(e,t){return e.source===`compaction`||e.source===`branch_summary`?!1:t.type===`skillInvocation`||t.type===`skillRead`||t.type===`image`||t.type===`text`&&(e.role===`user`||e.role===`assistant`||e.role===`system`||e.role===`bash`)}async function Um(e,t=Wm()){if(!t.isSecureContext)return t.fallbackWriteText(e);if(t.writeText!==void 0)try{return await t.writeText(e),!0}catch{return t.fallbackWriteText(e)}return t.fallbackWriteText(e)}function Wm(){let e=e=>qm(e),t=Km();return t===void 0?{isSecureContext:Gm(),fallbackWriteText:e}:{isSecureContext:Gm(),writeText:t,fallbackWriteText:e}}function Gm(){return typeof window<`u`&&window.isSecureContext}function Km(){if(!(typeof navigator>`u`||!(`clipboard`in navigator)))return navigator.clipboard.writeText.bind(navigator.clipboard)}function qm(e){if(typeof document>`u`)return!1;let t=document.activeElement,n=document.getSelection(),r=n===null?[]:Jm(n),i=document.createElement(`textarea`);i.value=e,i.readOnly=!0,i.setAttribute(`aria-hidden`,`true`),i.style.position=`fixed`,i.style.top=`0`,i.style.left=`-9999px`,i.style.width=`1px`,i.style.height=`1px`,i.style.padding=`0`,i.style.border=`0`,i.style.opacity=`0`,i.style.pointerEvents=`none`,document.body.append(i),i.focus(),i.select(),i.setSelectionRange(0,i.value.length);try{return document.execCommand(`copy`)}catch{return!1}finally{i.remove(),Ym(n,r),Xm(t)}}function Jm(e){let t=[];for(let n=0;n<e.rangeCount;n+=1)t.push(e.getRangeAt(n));return t}function Ym(e,t){if(e!==null)try{e.removeAllRanges();for(let n of t)e.addRange(n)}catch{}}function Xm(e){if(!(typeof HTMLElement>`u`||!(e instanceof HTMLElement)))try{e.focus({preventScroll:!0})}catch{e.focus()}}function Zm(e,t){let n=$m(nh(e,t)),r={distanceFromBottom:e.scrollHeight-e.scrollTop};return n===void 0?r:{...r,markerId:n.id,markerOffset:n.offset}}function Qm(e,t,n){if(n!==void 0&&t.markerOffset!==void 0){let r=n.getBoundingClientRect().top-e.getBoundingClientRect().top;e.scrollTop+=eh(r,t.markerOffset);return}e.scrollTop=th(e.scrollHeight,t.distanceFromBottom)}function $m(e){let t,n=-1/0,r,i=1/0;for(let a of e)a.offset<=0&&a.offset>=n?(t=a,n=a.offset):a.offset>0&&a.offset<i&&(r=a,i=a.offset);return t??r}function eh(e,t){return e-t}function th(e,t){return Math.max(0,e-t)}function nh(e,t){let n=e.getBoundingClientRect().top;return t.flatMap(e=>{let t=e.dataset.markerId;return t===void 0?[]:[{id:t,offset:e.getBoundingClientRect().top-n}]})}var rh=600,ih=1;function ah(e){return!e.hasMore||e.loadingMore||!e.canRequest||e.clientHeight<=0?!1:oh(e)||sh(e)}function oh(e){return e.scrollTop<(e.topThreshold??Math.max(rh,e.clientHeight))}function sh(e){return e.scrollHeight<=e.clientHeight+ih}var ch=`pi-web:chat-scroll:`,lh=180,uh=48,dh=2,fh={getItem(e){return typeof localStorage>`u`?null:localStorage.getItem(e)},setItem(e,t){typeof localStorage>`u`||localStorage.setItem(e,t)},removeItem(e){typeof localStorage>`u`||localStorage.removeItem(e)}},ph={setTimeout(e,t){return window.setTimeout(e,t)},clearTimeout(e){window.clearTimeout(e)}},mh=class{constructor(e=fh,t=ph){this.storage=e,this.scheduler=t}dispose(){this.clearScheduledSave()}clearScheduledSave(){this.saveTimer!==void 0&&(this.scheduler.clearTimeout(this.saveTimer),this.saveTimer=void 0)}scheduleSave(e,t,n=lh){this.clearScheduledSave(),this.saveTimer=this.scheduler.setTimeout(()=>{this.saveTimer=void 0,t(e)},n)}savePosition(e,t,n,r=dh){if(e===``||t===void 0||!_h(t))return`skipped`;try{if(yh(t,r))return this.storage.setItem(hh(e),JSON.stringify({mode:`bottom`})),`saved`;let i=xh(t,n);if(i===void 0)return`skipped`;let a=bh(t,i);return this.storage.setItem(hh(e),JSON.stringify(a)),`saved`}catch{return`skipped`}}restorePosition(e,t,n,r){let i=this.readPosition(e);return i===void 0?this.scrollToBottom(t):this.restoreExplicitPosition(i,t,n,r)}restoreExplicitPosition(e,t,n,r){if(e.mode===`bottom`)return this.scrollToBottom(t);if(t===void 0||!_h(t))return{status:`skipped`};let i=Ch(n,e.anchorId);if(i===void 0)return r?.fallbackToBottom===!1?{status:`missing`,position:e}:this.scrollToBottom(t);let a=t.getBoundingClientRect().top,o=i.getBoundingClientRect().top-a;return t.scrollTop+=o-e.offset,{status:`restored`}}readPosition(e){if(e!==``)try{let t=this.storage.getItem(hh(e));if(t===null||t===``)return;let n=JSON.parse(t);return gh(n)?n:void 0}catch{return}}scrollToBottom(e){return e===void 0||!_h(e)?{status:`skipped`}:(e.scrollTop=e.scrollHeight,{status:`bottom`})}};function hh(e){return`${ch}${e}`}function gh(e){return typeof e!=`object`||!e||!(`mode`in e)?!1:e.mode===`bottom`||e.mode===`anchor`&&`anchorId`in e&&typeof e.anchorId==`string`&&e.anchorId!==``&&`offset`in e&&typeof e.offset==`number`}function _h(e){return e.clientHeight>0&&e.scrollHeight>0}function vh(e){return e.scrollHeight-e.scrollTop-e.clientHeight}function yh(e,t=uh){return vh(e)<t}function bh(e,t){let n=e.getBoundingClientRect().top;return{mode:`anchor`,anchorId:wh(t)??``,offset:t.getBoundingClientRect().top-n}}function xh(e,t){let n=e.getBoundingClientRect(),r,i=-1/0,a,o=1/0;for(let e of t){if(wh(e)===void 0)continue;let t=e.getBoundingClientRect();if(t.bottom<=t.top||t.bottom<n.top||t.top>n.bottom)continue;let s=t.top-n.top;s<=0&&s>=i?(r=e,i=s):s>0&&s<o&&(a=e,o=s)}return r??a}function Sh(e,t){let n=e.getBoundingClientRect();return t.find(e=>{let t=e.getBoundingClientRect();return t.bottom>=n.top&&t.top<=n.bottom})}function Ch(e,t){return e.find(e=>wh(e)===t)}function wh(e){return e.dataset.scrollAnchorId!==void 0&&e.dataset.scrollAnchorId!==``?e.dataset.scrollAnchorId:void 0}var Th=class extends v{constructor(...e){super(...e),this.positionPercent=0,this.loadedPercent=100}render(){let e=Eh(this.positionPercent),t=Eh(this.loadedPercent),n=`Message position: about ${String(Math.round(e))}% through conversation. ${String(Math.round(t))}% of messages loaded.`;return g`
1109
- <div
1110
- class="meter"
1111
- style=${`--position:${e.toFixed(2)}%;`}
1112
- role="meter"
1113
- aria-label=${n}
1114
- aria-valuemin="0"
1115
- aria-valuemax="100"
1116
- aria-valuenow=${String(Math.round(e))}
1117
- title=${n}
1118
- >
1119
- <div class="track" aria-hidden="true">
1120
- <div class="progress"></div>
1121
- <div class="marker"></div>
1122
- </div>
1123
- </div>
1124
- `}static{this.styles=h`
1125
- :host { position: absolute; top: -4px; left: 16px; right: 16px; z-index: 6; display: block; height: 12px; opacity: .58; transition: opacity .15s ease; }
1126
- :host(:hover), :host(:focus-within) { opacity: .92; }
1127
- .meter { height: 100%; }
1128
- .track { position: relative; height: 4px; margin-top: 4px; border-radius: 999px; background: color-mix(in srgb, var(--pi-border-muted) 34%, transparent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--pi-bg) 55%, transparent); }
1129
- .progress { position: absolute; left: 0; width: var(--position); top: 0; bottom: 0; border-radius: 999px; background: color-mix(in srgb, var(--pi-accent) 42%, var(--pi-border-muted)); }
1130
- .marker { position: absolute; left: var(--position); top: 50%; width: 10px; height: 10px; border: 2px solid var(--pi-bg); border-radius: 50%; background: var(--pi-accent); box-shadow: 0 2px 8px var(--pi-shadow); transform: translate(-50%, -50%); }
1131
- `}};R([b({type:Number})],Th.prototype,`positionPercent`,void 0),R([b({type:Number})],Th.prototype,`loadedPercent`,void 0),Th=R([y(`conversation-meter`)],Th);function Eh(e){return Number.isFinite(e)?Math.min(100,Math.max(0,e)):0}var Dh=class extends vm{constructor(e){if(super(e),this.it=_,e.type!==gm.CHILD)throw Error(this.constructor.directiveName+`() can only be used in child bindings`)}render(e){if(e===_||e==null)return this._t=void 0,this.it=e;if(e===Ye)return e;if(typeof e!=`string`)throw Error(this.constructor.directiveName+`() called with a non-string value`);if(e===this.it)return this._t;this.it=e;let t=[e];return t.raw=t,this._t={_$litType$:this.constructor.resultType,strings:t,values:[]}}};Dh.directiveName=`unsafeHTML`,Dh.resultType=1;var Oh=_m(Dh);function kh(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var Ah=kh();function jh(e){Ah=e}var Mh={exec:()=>null};function Nh(e){let t=[];return n=>{let r=Math.max(0,Math.min(3,n-1)),i=t[r];return i||(i=e(r),t[r]=i),i}}function W(e,t=``){let n=typeof e==`string`?e:e.source,r={replace:(e,t)=>{let i=typeof t==`string`?t:t.source;return i=i.replace(G.caret,`$1`),n=n.replace(e,i),r},getRegex:()=>new RegExp(n,t)};return r}var Ph=((e=``)=>{try{return!!RegExp(`(?<=1)(?<!1)`+e)}catch{return!1}})(),G={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] +\S/,listReplaceTask:/^\[[ xX]\] +/,listTaskCheckbox:/\[[ xX]\]/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:e=>RegExp(`^( {0,3}${e})((?:[ ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:Nh(e=>RegExp(`^ {0,${e}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`)),hrRegex:Nh(e=>RegExp(`^ {0,${e}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)),fencesBeginRegex:Nh(e=>RegExp(`^ {0,${e}}(?:\`\`\`|~~~)`)),headingBeginRegex:Nh(e=>RegExp(`^ {0,${e}}#`)),htmlBeginRegex:Nh(e=>RegExp(`^ {0,${e}}<(?:[a-z].*>|!--)`,`i`)),blockquoteBeginRegex:Nh(e=>RegExp(`^ {0,${e}}>`))},Fh=/^(?:[ \t]*(?:\n|$))+/,Ih=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,Lh=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,Rh=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,zh=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,Bh=/ {0,3}(?:[*+-]|\d{1,9}[.)])/,Vh=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,Hh=W(Vh).replace(/bull/g,Bh).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,``).getRegex(),Uh=W(Vh).replace(/bull/g,Bh).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),Wh=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,Gh=/^[^\n]+/,Kh=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,qh=W(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace(`label`,Kh).replace(`title`,/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),Jh=W(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g,Bh).getRegex(),Yh=`address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul`,Xh=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,Zh=W(`^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>[^\\n]*\\n+|$)|<![A-Z][\\s\\S]*?(?:>[^\\n]*\\n+|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>[^\\n]*\\n+|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))`,`i`).replace(`comment`,Xh).replace(`tag`,Yh).replace(`attribute`,/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Qh=e=>W(Wh).replace(`hr`,Rh).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`|lheading`,``).replace(`|table`,``).replace(`blockquote`,` {0,3}>`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace(`list`,e).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,Yh).getRegex(),$h=Qh(/ {0,3}(?:[*+-]|1[.)])[ \t]+[^ \t\n]/),eg=Qh(/ {0,3}(?:[*+-]|\d{1,9}[.)])[ \t]+[^ \t\n]/),tg={blockquote:W(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace(`paragraph`,eg).getRegex(),code:Ih,def:qh,fences:Lh,heading:zh,hr:Rh,html:Zh,lheading:Hh,list:Jh,newline:Fh,paragraph:$h,table:Mh,text:Gh},ng=W(`^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)`).replace(`hr`,Rh).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`blockquote`,` {0,3}>`).replace(`code`,`(?: {4}| {0,3} )[^\\n]`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace(`list`,` {0,3}(?:[*+-]|1[.)])[ \\t]`).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,Yh).getRegex(),rg={...tg,lheading:Uh,table:ng,paragraph:W(Wh).replace(`hr`,Rh).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`|lheading`,``).replace(`table`,ng).replace(`blockquote`,` {0,3}>`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace(`list`,` {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]`).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,Yh).getRegex()},ig={...tg,html:W(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace(`comment`,Xh).replace(/tag/g,`(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b`).getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:Mh,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:W(Wh).replace(`hr`,Rh).replace(`heading`,` *#{1,6} *[^
1132
- ]`).replace(`lheading`,Hh).replace(`|table`,``).replace(`blockquote`,` {0,3}>`).replace(`|fences`,``).replace(`|list`,``).replace(`|html`,``).replace(`|tag`,``).getRegex()},ag=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,og=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,sg=/^( {2,}|\\)\n(?!\s*$)/,cg=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,lg=/[\p{P}\p{S}]/u,ug=/[\s\p{P}\p{S}]/u,dg=/[^\s\p{P}\p{S}]/u,fg=W(/^((?![*_])punctSpace)/,`u`).replace(/punctSpace/g,ug).getRegex(),pg=/(?!~)[\p{P}\p{S}]/u,mg=/(?!~)[\s\p{P}\p{S}]/u,hg=/(?:[^\s\p{P}\p{S}]|~)/u,gg=W(/link|precode-code|html/,`g`).replace(`link`,/\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace(`precode-`,Ph?"(?<!`)()":"(^^|[^`])").replace(`code`,/(?<b>`+)[^`]+\k<b>(?!`)/).replace(`html`,/<(?! )[^<>]*?>/).getRegex(),_g=/^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/,vg=W(_g,`u`).replace(/punct/g,lg).getRegex(),yg=W(_g,`u`).replace(/punct/g,pg).getRegex(),bg=`^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)`,xg=W(bg,`gu`).replace(/notPunctSpace/g,dg).replace(/punctSpace/g,ug).replace(/punct/g,lg).getRegex(),Sg=W(bg,`gu`).replace(/notPunctSpace/g,hg).replace(/punctSpace/g,mg).replace(/punct/g,pg).getRegex(),Cg=W(`^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)`,`gu`).replace(/notPunctSpace/g,dg).replace(/punctSpace/g,ug).replace(/punct/g,lg).getRegex(),wg=W(/^~~?(?:((?!~)punct)|[^\s~])/,`u`).replace(/punct/g,lg).getRegex(),Tg=W(`^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)`,`gu`).replace(/notPunctSpace/g,dg).replace(/punctSpace/g,ug).replace(/punct/g,lg).getRegex(),Eg=W(/\\(punct)/,`gu`).replace(/punct/g,lg).getRegex(),Dg=W(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace(`scheme`,/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace(`email`,/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),Og=W(Xh).replace(`(?:-->|$)`,`-->`).getRegex(),kg=W(`^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>`).replace(`comment`,Og).replace(`attribute`,/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),Ag=/(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/,jg=W(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace(`label`,Ag).replace(`href`,/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]+|(?=\))/).replace(`title`,/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),Mg=W(/^!?\[(label)\]\[(ref)\]/).replace(`label`,Ag).replace(`ref`,Kh).getRegex(),Ng=W(/^!?\[(ref)\](?:\[\])?/).replace(`ref`,Kh).getRegex(),Pg=W(`reflink|nolink(?!\\()`,`g`).replace(`reflink`,Mg).replace(`nolink`,Ng).getRegex(),Fg=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,Ig={_backpedal:Mh,anyPunctuation:Eg,autolink:Dg,blockSkip:gg,br:sg,code:og,del:Mh,delLDelim:Mh,delRDelim:Mh,emStrongLDelim:vg,emStrongRDelimAst:xg,emStrongRDelimUnd:Cg,escape:ag,link:jg,nolink:Ng,punctuation:fg,reflink:Mg,reflinkSearch:Pg,tag:kg,text:cg,url:Mh},Lg={...Ig,link:W(/^!?\[(label)\]\((.*?)\)/).replace(`label`,Ag).getRegex(),reflink:W(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace(`label`,Ag).getRegex()},Rg={...Ig,emStrongRDelimAst:Sg,emStrongLDelim:yg,delLDelim:wg,delRDelim:Tg,url:W(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace(`protocol`,Fg).replace(`email`,/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/,text:W(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace(`protocol`,Fg).getRegex()},zg={...Rg,br:W(sg).replace(`{2,}`,`*`).getRegex(),text:W(Rg.text).replace(`\\b_`,`\\b_| {2,}\\n`).replace(/\{2,\}/g,`*`).getRegex()},Bg={normal:tg,gfm:rg,pedantic:ig},Vg={normal:Ig,gfm:Rg,breaks:zg,pedantic:Lg},Hg={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`},Ug=e=>Hg[e];function Wg(e,t){if(t){if(G.escapeTest.test(e))return e.replace(G.escapeReplace,Ug)}else if(G.escapeTestNoEncode.test(e))return e.replace(G.escapeReplaceNoEncode,Ug);return e}function Gg(e){try{e=encodeURI(e).replace(G.percentDecode,`%`)}catch{return null}return e}function Kg(e,t){let n=e.replace(G.findPipe,(e,t,n)=>{let r=!1,i=t;for(;--i>=0&&n[i]===`\\`;)r=!r;return r?`|`:` |`}).split(G.splitPipe),r=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),t)if(n.length>t)n.splice(t);else for(;n.length<t;)n.push(``);for(;r<n.length;r++)n[r]=n[r].trim().replace(G.slashPipe,`|`);return n}function qg(e,t,n){let r=e.length;if(r===0)return``;let i=0;for(;i<r;){let a=e.charAt(r-i-1);if(a===t&&!n)i++;else if(a!==t&&n)i++;else break}return e.slice(0,r-i)}function Jg(e){let t=e.split(`
1133
- `),n=t.length-1;for(;n>=0&&G.blankLine.test(t[n]);)n--;return t.length-n<=2?e:t.slice(0,n+1).join(`
1134
- `)}function Yg(e,t){if(e.indexOf(t[1])===-1)return-1;let n=0;for(let r=0;r<e.length;r++)if(e[r]===`\\`)r++;else if(e[r]===t[0])n++;else if(e[r]===t[1]&&(n--,n<0))return r;return n>0?-2:-1}function Xg(e,t=0){let n=t,r=``;for(let t of e)if(t===` `){let e=4-n%4;r+=` `.repeat(e),n+=e}else r+=t,n++;return r}function Zg(e,t,n,r,i){let a=t.href,o=t.title||null,s=e[1].replace(i.other.outputLinkReplace,`$1`);r.state.inLink=!0;let c={type:e[0].charAt(0)===`!`?`image`:`link`,raw:n,href:a,title:o,text:s,tokens:r.inlineTokens(s)};return r.state.inLink=!1,c}function Qg(e,t,n){let r=e.match(n.other.indentCodeCompensation);if(r===null)return t;let i=r[1];return t.split(`
1135
- `).map(e=>{let t=e.match(n.other.beginningSpace);if(t===null)return e;let[r]=t;return r.length>=i.length?e.slice(i.length):e}).join(`
1136
- `)}var $g=class{options;rules;lexer;constructor(e){this.options=e||Ah}space(e){let t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:`space`,raw:t[0]}}code(e){let t=this.rules.block.code.exec(e);if(t){let e=this.options.pedantic?t[0]:Jg(t[0]);return{type:`code`,raw:e,codeBlockStyle:`indented`,text:e.replace(this.rules.other.codeRemoveIndent,``)}}}fences(e){let t=this.rules.block.fences.exec(e);if(t){let e=t[0],n=Qg(e,t[3]||``,this.rules);return{type:`code`,raw:e,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,`$1`):t[2],text:n}}}heading(e){let t=this.rules.block.heading.exec(e);if(t){let e=t[2].trim();if(this.rules.other.endingHash.test(e)){let t=qg(e,`#`);(this.options.pedantic||!t||this.rules.other.endingSpaceChar.test(t))&&(e=t.trim())}return{type:`heading`,raw:qg(t[0],`
1137
- `),depth:t[1].length,text:e,tokens:this.lexer.inline(e)}}}hr(e){let t=this.rules.block.hr.exec(e);if(t)return{type:`hr`,raw:qg(t[0],`
1138
- `)}}blockquote(e){let t=this.rules.block.blockquote.exec(e);if(t){let e=qg(t[0],`
1139
- `).split(`
1140
- `),n=``,r=``,i=[];for(;e.length>0;){let t=!1,a=[],o;for(o=0;o<e.length;o++)if(this.rules.other.blockquoteStart.test(e[o]))a.push(e[o]),t=!0;else if(!t)a.push(e[o]);else break;e=e.slice(o);let s=a.join(`
1141
- `),c=s.replace(this.rules.other.blockquoteSetextReplace,`
1142
- $1`).replace(this.rules.other.blockquoteSetextReplace2,``);n=n?`${n}
1143
- ${s}`:s,r=r?`${r}
1144
- ${c}`:c;let l=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(c,i,!0),this.lexer.state.top=l,e.length===0)break;let u=i.at(-1);if(u?.type===`code`)break;if(u?.type===`blockquote`){let t=u,a=t.raw+`
1145
- `+e.join(`
1146
- `),o=this.blockquote(a);i[i.length-1]=o,n=n.substring(0,n.length-t.raw.length)+o.raw,r=r.substring(0,r.length-t.text.length)+o.text;break}else if(u?.type===`list`){let t=u,a=t.raw+`
1147
- `+e.join(`
1148
- `),o=this.list(a);i[i.length-1]=o,n=n.substring(0,n.length-u.raw.length)+o.raw,r=r.substring(0,r.length-t.raw.length)+o.raw,e=a.substring(i.at(-1).raw.length).split(`
1149
- `);continue}}return{type:`blockquote`,raw:n,tokens:i,text:r}}}list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim(),r=n.length>1,i={type:`list`,raw:``,ordered:r,start:r?+n.slice(0,-1):``,loose:!1,items:[]};n=r?`\\d{1,9}\\${n.slice(-1)}`:`\\${n}`,this.options.pedantic&&(n=r?n:`[*+-]`);let a=this.rules.other.listItemRegex(n),o=!1;for(;e;){let n=!1,r=``,s=``;if(!(t=a.exec(e))||this.rules.block.hr.test(e))break;r=t[0],e=e.substring(r.length);let c=Xg(t[2].split(`
1150
- `,1)[0],t[1].length),l=e.split(`
1151
- `,1)[0],u=!c.trim(),d=0;if(this.options.pedantic?(d=2,s=c.trimStart()):u?d=t[1].length+1:(d=c.search(this.rules.other.nonSpaceChar),d=d>4?1:d,s=c.slice(d),d+=t[1].length),u&&this.rules.other.blankLine.test(l)&&(r+=l+`
1152
- `,e=e.substring(l.length+1),n=!0),!n){let t=this.rules.other.nextBulletRegex(d),n=this.rules.other.hrRegex(d),i=this.rules.other.fencesBeginRegex(d),a=this.rules.other.headingBeginRegex(d),o=this.rules.other.htmlBeginRegex(d),f=this.rules.other.blockquoteBeginRegex(d);for(;e;){let p=e.split(`
1153
- `,1)[0],m;if(l=p,this.options.pedantic?(l=l.replace(this.rules.other.listReplaceNesting,` `),m=l):m=l.replace(this.rules.other.tabCharGlobal,` `),i.test(l)||a.test(l)||o.test(l)||f.test(l)||t.test(l)||n.test(l))break;if(m.search(this.rules.other.nonSpaceChar)>=d||!l.trim())s+=`
1154
- `+m.slice(d);else{if(u||c.replace(this.rules.other.tabCharGlobal,` `).search(this.rules.other.nonSpaceChar)>=4||i.test(c)||a.test(c)||n.test(c))break;s+=`
1155
- `+l}u=!l.trim(),r+=p+`
1156
- `,e=e.substring(p.length+1),c=m.slice(d)}}i.loose||(o?i.loose=!0:this.rules.other.doubleBlankLine.test(r)&&(o=!0)),i.items.push({type:`list_item`,raw:r,task:!!this.options.gfm&&this.rules.other.listIsTask.test(s),loose:!1,text:s,tokens:[]}),i.raw+=r}let s=i.items.at(-1);if(s)s.raw=s.raw.trimEnd(),s.text=s.text.trimEnd();else return;i.raw=i.raw.trimEnd();for(let e of i.items){this.lexer.state.top=!1,e.tokens=this.lexer.blockTokens(e.text,[]);let t=e.tokens[0];if(e.task&&(t?.type===`text`||t?.type===`paragraph`)){e.text=e.text.replace(this.rules.other.listReplaceTask,``),t.raw=t.raw.replace(this.rules.other.listReplaceTask,``),t.text=t.text.replace(this.rules.other.listReplaceTask,``);for(let e=this.lexer.inlineQueue.length-1;e>=0;e--)if(this.rules.other.listIsTask.test(this.lexer.inlineQueue[e].src)){this.lexer.inlineQueue[e].src=this.lexer.inlineQueue[e].src.replace(this.rules.other.listReplaceTask,``);break}let n=this.rules.other.listTaskCheckbox.exec(e.raw);if(n){let t={type:`checkbox`,raw:n[0]+` `,checked:n[0]!==`[ ]`};e.checked=t.checked,i.loose?e.tokens[0]&&[`paragraph`,`text`].includes(e.tokens[0].type)&&`tokens`in e.tokens[0]&&e.tokens[0].tokens?(e.tokens[0].raw=t.raw+e.tokens[0].raw,e.tokens[0].text=t.raw+e.tokens[0].text,e.tokens[0].tokens.unshift(t)):e.tokens.unshift({type:`paragraph`,raw:t.raw,text:t.raw,tokens:[t]}):e.tokens.unshift(t)}}else e.task&&=!1;if(!i.loose){let t=e.tokens.filter(e=>e.type===`space`);i.loose=t.length>0&&t.some(e=>this.rules.other.anyLine.test(e.raw))}}if(i.loose)for(let e of i.items){e.loose=!0;for(let t of e.tokens)t.type===`text`&&(t.type=`paragraph`)}return i}}html(e){let t=this.rules.block.html.exec(e);if(t){let e=Jg(t[0]);return{type:`html`,block:!0,raw:e,pre:t[1]===`pre`||t[1]===`script`||t[1]===`style`,text:e}}}def(e){let t=this.rules.block.def.exec(e);if(t){let e=t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal,` `),n=t[2]?t[2].replace(this.rules.other.hrefBrackets,`$1`).replace(this.rules.inline.anyPunctuation,`$1`):``,r=t[3]?t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,`$1`):t[3];return{type:`def`,tag:e,raw:qg(t[0],`
1157
- `),href:n,title:r}}}table(e){let t=this.rules.block.table.exec(e);if(!t||!this.rules.other.tableDelimiter.test(t[2]))return;let n=Kg(t[1]),r=t[2].replace(this.rules.other.tableAlignChars,``).split(`|`),i=t[3]?.trim()?t[3].replace(this.rules.other.tableRowBlankLine,``).split(`
1158
- `):[],a={type:`table`,raw:qg(t[0],`
1159
- `),header:[],align:[],rows:[]};if(n.length===r.length){for(let e of r)this.rules.other.tableAlignRight.test(e)?a.align.push(`right`):this.rules.other.tableAlignCenter.test(e)?a.align.push(`center`):this.rules.other.tableAlignLeft.test(e)?a.align.push(`left`):a.align.push(null);for(let e=0;e<n.length;e++)a.header.push({text:n[e],tokens:this.lexer.inline(n[e]),header:!0,align:a.align[e]});for(let e of i)a.rows.push(Kg(e,a.header.length).map((e,t)=>({text:e,tokens:this.lexer.inline(e),header:!1,align:a.align[t]})));return a}}lheading(e){let t=this.rules.block.lheading.exec(e);if(t){let e=t[1].trim();return{type:`heading`,raw:qg(t[0],`
1160
- `),depth:t[2].charAt(0)===`=`?1:2,text:e,tokens:this.lexer.inline(e)}}}paragraph(e){let t=this.rules.block.paragraph.exec(e);if(t){let e=t[1].charAt(t[1].length-1)===`
1161
- `?t[1].slice(0,-1):t[1];return{type:`paragraph`,raw:t[0],text:e,tokens:this.lexer.inline(e)}}}text(e){let t=this.rules.block.text.exec(e);if(t)return{type:`text`,raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){let t=this.rules.inline.escape.exec(e);if(t)return{type:`escape`,raw:t[0],text:t[1]}}tag(e){let t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&this.rules.other.startATag.test(t[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:`html`,raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){let t=this.rules.inline.link.exec(e);if(t){let e=t[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(e)){if(!this.rules.other.endAngleBracket.test(e))return;let t=qg(e.slice(0,-1),`\\`);if((e.length-t.length)%2==0)return}else{let e=Yg(t[2],`()`);if(e===-2)return;if(e>-1){let n=(t[0].indexOf(`!`)===0?5:4)+t[1].length+e;t[2]=t[2].substring(0,e),t[0]=t[0].substring(0,n).trim(),t[3]=``}}let n=t[2],r=``;if(this.options.pedantic){let e=this.rules.other.pedanticHrefTitle.exec(n);e&&(n=e[1],r=e[3])}else r=t[3]?t[3].slice(1,-1):``;return n=n.trim(),this.rules.other.startAngleBracket.test(n)&&(n=this.options.pedantic&&!this.rules.other.endAngleBracket.test(e)?n.slice(1):n.slice(1,-1)),Zg(t,{href:n&&n.replace(this.rules.inline.anyPunctuation,`$1`),title:r&&r.replace(this.rules.inline.anyPunctuation,`$1`)},t[0],this.lexer,this.rules)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){let e=t[(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal,` `).toLowerCase()];if(!e){let e=n[0].charAt(0);return{type:`text`,raw:e,text:e}}return Zg(n,e,n[0],this.lexer,this.rules)}}emStrong(e,t,n=``){let r=this.rules.inline.emStrongLDelim.exec(e);if(!(!r||!r[1]&&!r[2]&&!r[3]&&!r[4]||r[4]&&n.match(this.rules.other.unicodeAlphaNumeric))&&(!(r[1]||r[3])||!n||this.rules.inline.punctuation.exec(n))){let n=[...r[0]].length-1,i,a,o=n,s=0,c=r[0][0]===`*`?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(c.lastIndex=0,t=t.slice(-1*e.length+n);(r=c.exec(t))!==null;){if(i=r[1]||r[2]||r[3]||r[4]||r[5]||r[6],!i)continue;if(a=[...i].length,r[3]||r[4]){o+=a;continue}else if((r[5]||r[6])&&n%3&&!((n+a)%3)){s+=a;continue}if(o-=a,o>0)continue;a=Math.min(a,a+o+s);let t=[...r[0]][0].length,c=e.slice(0,n+r.index+t+a);if(Math.min(n,a)%2){let e=c.slice(1,-1);return{type:`em`,raw:c,text:e,tokens:this.lexer.inlineTokens(e)}}let l=c.slice(2,-2);return{type:`strong`,raw:c,text:l,tokens:this.lexer.inlineTokens(l)}}}}codespan(e){let t=this.rules.inline.code.exec(e);if(t){let e=t[2].replace(this.rules.other.newLineCharGlobal,` `),n=this.rules.other.nonSpaceChar.test(e),r=this.rules.other.startingSpaceChar.test(e)&&this.rules.other.endingSpaceChar.test(e);return n&&r&&(e=e.substring(1,e.length-1)),{type:`codespan`,raw:t[0],text:e}}}br(e){let t=this.rules.inline.br.exec(e);if(t)return{type:`br`,raw:t[0]}}del(e,t,n=``){let r=this.rules.inline.delLDelim.exec(e);if(r&&(!r[1]||!n||this.rules.inline.punctuation.exec(n))){let n=[...r[0]].length-1,i,a,o=n,s=this.rules.inline.delRDelim;for(s.lastIndex=0,t=t.slice(-1*e.length+n);(r=s.exec(t))!==null;){if(i=r[1]||r[2]||r[3]||r[4]||r[5]||r[6],!i||(a=[...i].length,a!==n))continue;if(r[3]||r[4]){o+=a;continue}if(o-=a,o>0)continue;a=Math.min(a,a+o);let t=[...r[0]][0].length,s=e.slice(0,n+r.index+t+a),c=s.slice(n,-n);return{type:`del`,raw:s,text:c,tokens:this.lexer.inlineTokens(c)}}}}autolink(e){let t=this.rules.inline.autolink.exec(e);if(t){let e,n;return t[2]===`@`?(e=t[1],n=`mailto:`+e):(e=t[1],n=e),{type:`link`,raw:t[0],text:e,href:n,tokens:[{type:`text`,raw:e,text:e}]}}}url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if(t[2]===`@`)e=t[0],n=`mailto:`+e;else{let r;do r=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])?.[0]??``;while(r!==t[0]);e=t[0],n=t[1]===`www.`?`http://`+t[0]:t[0]}return{type:`link`,raw:t[0],text:e,href:n,tokens:[{type:`text`,raw:e,text:e}]}}}inlineText(e){let t=this.rules.inline.text.exec(e);if(t){let e=this.lexer.state.inRawBlock;return{type:`text`,raw:t[0],text:t[0],escaped:e}}}},e_=class e{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||Ah,this.options.tokenizer=this.options.tokenizer||new $g,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let t={other:G,block:Bg.normal,inline:Vg.normal};this.options.pedantic?(t.block=Bg.pedantic,t.inline=Vg.pedantic):this.options.gfm&&(t.block=Bg.gfm,this.options.breaks?t.inline=Vg.breaks:t.inline=Vg.gfm),this.tokenizer.rules=t}static get rules(){return{block:Bg,inline:Vg}}static lex(t,n){return new e(n).lex(t)}static lexInline(t,n){return new e(n).inlineTokens(t)}lex(e){e=e.replace(G.carriageReturn,`
1162
- `),this.blockTokens(e,this.tokens);for(let e=0;e<this.inlineQueue.length;e++){let t=this.inlineQueue[e];this.inlineTokens(t.src,t.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,t=[],n=!1){this.tokenizer.lexer=this,this.options.pedantic&&(e=e.replace(G.tabCharGlobal,` `).replace(G.spaceLine,``));let r=1/0;for(;e;){if(e.length<r)r=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}let i;if(this.options.extensions?.block?.some(n=>(i=n.call({lexer:this},e,t))?(e=e.substring(i.raw.length),t.push(i),!0):!1))continue;if(i=this.tokenizer.space(e)){e=e.substring(i.raw.length);let n=t.at(-1);i.raw.length===1&&n!==void 0?n.raw+=`
1163
- `:t.push(i);continue}if(i=this.tokenizer.code(e)){e=e.substring(i.raw.length);let n=t.at(-1);n?.type===`paragraph`||n?.type===`text`?(n.raw+=(n.raw.endsWith(`
1164
- `)?``:`
1165
- `)+i.raw,n.text+=`
1166
- `+i.text,this.inlineQueue.at(-1).src=n.text):t.push(i);continue}if(i=this.tokenizer.fences(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.heading(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.hr(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.blockquote(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.list(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.html(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.def(e)){e=e.substring(i.raw.length);let n=t.at(-1);n?.type===`paragraph`||n?.type===`text`?(n.raw+=(n.raw.endsWith(`
1167
- `)?``:`
1168
- `)+i.raw,n.text+=`
1169
- `+i.raw,this.inlineQueue.at(-1).src=n.text):this.tokens.links[i.tag]||(this.tokens.links[i.tag]={href:i.href,title:i.title},t.push(i));continue}if(i=this.tokenizer.table(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.lheading(e)){e=e.substring(i.raw.length),t.push(i);continue}let a=e;if(this.options.extensions?.startBlock){let t=1/0,n=e.slice(1),r;this.options.extensions.startBlock.forEach(e=>{r=e.call({lexer:this},n),typeof r==`number`&&r>=0&&(t=Math.min(t,r))}),t<1/0&&t>=0&&(a=e.substring(0,t+1))}if(this.state.top&&(i=this.tokenizer.paragraph(a))){let r=t.at(-1);n&&r?.type===`paragraph`?(r.raw+=(r.raw.endsWith(`
1170
- `)?``:`
1171
- `)+i.raw,r.text+=`
1172
- `+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=r.text):t.push(i),n=a.length!==e.length,e=e.substring(i.raw.length);continue}if(i=this.tokenizer.text(e)){e=e.substring(i.raw.length);let n=t.at(-1);n?.type===`text`?(n.raw+=(n.raw.endsWith(`
1173
- `)?``:`
1174
- `)+i.raw,n.text+=`
1175
- `+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=n.text):t.push(i);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){this.tokenizer.lexer=this;let n=e,r=null;if(this.tokens.links){let e=Object.keys(this.tokens.links);if(e.length>0)for(;(r=this.tokenizer.rules.inline.reflinkSearch.exec(n))!==null;)e.includes(r[0].slice(r[0].lastIndexOf(`[`)+1,-1))&&(n=n.slice(0,r.index)+`[`+`a`.repeat(r[0].length-2)+`]`+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(r=this.tokenizer.rules.inline.anyPunctuation.exec(n))!==null;)n=n.slice(0,r.index)+`++`+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);let i;for(;(r=this.tokenizer.rules.inline.blockSkip.exec(n))!==null;)i=r[2]?r[2].length:0,n=n.slice(0,r.index+i)+`[`+`a`.repeat(r[0].length-i-2)+`]`+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);n=this.options.hooks?.emStrongMask?.call({lexer:this},n)??n;let a=!1,o=``,s=1/0;for(;e;){if(e.length<s)s=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}a||(o=``),a=!1;let r;if(this.options.extensions?.inline?.some(n=>(r=n.call({lexer:this},e,t))?(e=e.substring(r.raw.length),t.push(r),!0):!1))continue;if(r=this.tokenizer.escape(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.tag(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.link(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(r.raw.length);let n=t.at(-1);r.type===`text`&&n?.type===`text`?(n.raw+=r.raw,n.text+=r.text):t.push(r);continue}if(r=this.tokenizer.emStrong(e,n,o)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.codespan(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.br(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.del(e,n,o)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.autolink(e)){e=e.substring(r.raw.length),t.push(r);continue}if(!this.state.inLink&&(r=this.tokenizer.url(e))){e=e.substring(r.raw.length),t.push(r);continue}let i=e;if(this.options.extensions?.startInline){let t=1/0,n=e.slice(1),r;this.options.extensions.startInline.forEach(e=>{r=e.call({lexer:this},n),typeof r==`number`&&r>=0&&(t=Math.min(t,r))}),t<1/0&&t>=0&&(i=e.substring(0,t+1))}if(r=this.tokenizer.inlineText(i)){e=e.substring(r.raw.length),r.raw.slice(-1)!==`_`&&(o=r.raw.slice(-1)),a=!0;let n=t.at(-1);n?.type===`text`?(n.raw+=r.raw,n.text+=r.text):t.push(r);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return t}infiniteLoopError(e){let t=`Infinite loop on byte: `+e;if(this.options.silent)console.error(t);else throw Error(t)}},t_=class{options;parser;constructor(e){this.options=e||Ah}space(e){return``}code({text:e,lang:t,escaped:n}){let r=(t||``).match(G.notSpaceStart)?.[0],i=e.replace(G.endingNewline,``)+`
1176
- `;return r?`<pre><code class="language-`+Wg(r)+`">`+(n?i:Wg(i,!0))+`</code></pre>
1177
- `:`<pre><code>`+(n?i:Wg(i,!0))+`</code></pre>
1178
- `}blockquote({tokens:e}){return`<blockquote>
1179
- ${this.parser.parse(e)}</blockquote>
1180
- `}html({text:e}){return e}def(e){return``}heading({tokens:e,depth:t}){return`<h${t}>${this.parser.parseInline(e)}</h${t}>
1181
- `}hr(e){return`<hr>
1182
- `}list(e){let t=e.ordered,n=e.start,r=``;for(let t=0;t<e.items.length;t++){let n=e.items[t];r+=this.listitem(n)}let i=t?`ol`:`ul`,a=t&&n!==1?` start="`+n+`"`:``;return`<`+i+a+`>
1183
- `+r+`</`+i+`>
1184
- `}listitem(e){return`<li>${this.parser.parse(e.tokens)}</li>
1185
- `}checkbox({checked:e}){return`<input `+(e?`checked="" `:``)+`disabled="" type="checkbox"> `}paragraph({tokens:e}){return`<p>${this.parser.parseInline(e)}</p>
1186
- `}table(e){let t=``,n=``;for(let t=0;t<e.header.length;t++)n+=this.tablecell(e.header[t]);t+=this.tablerow({text:n});let r=``;for(let t=0;t<e.rows.length;t++){let i=e.rows[t];n=``;for(let e=0;e<i.length;e++)n+=this.tablecell(i[e]);r+=this.tablerow({text:n})}return r&&=`<tbody>${r}</tbody>`,`<table>
1187
- <thead>
1188
- `+t+`</thead>
1189
- `+r+`</table>
1190
- `}tablerow({text:e}){return`<tr>
1191
- ${e}</tr>
1192
- `}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?`th`:`td`;return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`</${n}>
1193
- `}strong({tokens:e}){return`<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return`<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return`<code>${Wg(e,!0)}</code>`}br(e){return`<br>`}del({tokens:e}){return`<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=Gg(e);if(i===null)return r;e=i;let a=`<a href="`+e+`"`;return t&&(a+=` title="`+Wg(t)+`"`),a+=`>`+r+`</a>`,a}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=Gg(e);if(i===null)return Wg(n);e=i;let a=`<img src="${e}" alt="${Wg(n)}"`;return t&&(a+=` title="${Wg(t)}"`),a+=`>`,a}text(e){return`tokens`in e&&e.tokens?this.parser.parseInline(e.tokens):`escaped`in e&&e.escaped?e.text:Wg(e.text)}},n_=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return``+e}image({text:e}){return``+e}br(){return``}checkbox({raw:e}){return e}},r_=class e{options;renderer;textRenderer;constructor(e){this.options=e||Ah,this.options.renderer=this.options.renderer||new t_,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new n_}static parse(t,n){return new e(n).parse(t)}static parseInline(t,n){return new e(n).parseInline(t)}parse(e){this.renderer.parser=this;let t=``;for(let n=0;n<e.length;n++){let r=e[n];if(this.options.extensions?.renderers?.[r.type]){let e=r,n=this.options.extensions.renderers[e.type].call({parser:this},e);if(n!==!1||![`space`,`hr`,`heading`,`code`,`table`,`blockquote`,`list`,`html`,`def`,`paragraph`,`text`].includes(e.type)){t+=n||``;continue}}let i=r;switch(i.type){case`space`:t+=this.renderer.space(i);break;case`hr`:t+=this.renderer.hr(i);break;case`heading`:t+=this.renderer.heading(i);break;case`code`:t+=this.renderer.code(i);break;case`table`:t+=this.renderer.table(i);break;case`blockquote`:t+=this.renderer.blockquote(i);break;case`list`:t+=this.renderer.list(i);break;case`checkbox`:t+=this.renderer.checkbox(i);break;case`html`:t+=this.renderer.html(i);break;case`def`:t+=this.renderer.def(i);break;case`paragraph`:t+=this.renderer.paragraph(i);break;case`text`:t+=this.renderer.text(i);break;default:{let e=`Token with "`+i.type+`" type was not found.`;if(this.options.silent)return console.error(e),``;throw Error(e)}}}return t}parseInline(e,t=this.renderer){this.renderer.parser=this;let n=``;for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let e=this.options.extensions.renderers[i.type].call({parser:this},i);if(e!==!1||![`escape`,`html`,`link`,`image`,`strong`,`em`,`codespan`,`br`,`del`,`text`].includes(i.type)){n+=e||``;continue}}let a=i;switch(a.type){case`escape`:n+=t.text(a);break;case`html`:n+=t.html(a);break;case`link`:n+=t.link(a);break;case`image`:n+=t.image(a);break;case`checkbox`:n+=t.checkbox(a);break;case`strong`:n+=t.strong(a);break;case`em`:n+=t.em(a);break;case`codespan`:n+=t.codespan(a);break;case`br`:n+=t.br(a);break;case`del`:n+=t.del(a);break;case`text`:n+=t.text(a);break;default:{let e=`Token with "`+a.type+`" type was not found.`;if(this.options.silent)return console.error(e),``;throw Error(e)}}}return n}},i_=class{options;block;constructor(e){this.options=e||Ah}static passThroughHooks=new Set([`preprocess`,`postprocess`,`processAllTokens`,`emStrongMask`]);static passThroughHooksRespectAsync=new Set([`preprocess`,`postprocess`,`processAllTokens`]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(e=this.block){return e?e_.lex:e_.lexInline}provideParser(e=this.block){return e?r_.parse:r_.parseInline}},a_=new class{defaults=kh();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=r_;Renderer=t_;TextRenderer=n_;Lexer=e_;Tokenizer=$g;Hooks=i_;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(let r of e)switch(n=n.concat(t.call(this,r)),r.type){case`table`:{let e=r;for(let r of e.header)n=n.concat(this.walkTokens(r.tokens,t));for(let r of e.rows)for(let e of r)n=n.concat(this.walkTokens(e.tokens,t));break}case`list`:{let e=r;n=n.concat(this.walkTokens(e.items,t));break}default:{let e=r;this.defaults.extensions?.childTokens?.[e.type]?this.defaults.extensions.childTokens[e.type].forEach(r=>{let i=e[r].flat(1/0);n=n.concat(this.walkTokens(i,t))}):e.tokens&&(n=n.concat(this.walkTokens(e.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(e=>{let n={...e};if(n.async=this.defaults.async||n.async||!1,e.extensions&&(e.extensions.forEach(e=>{if(!e.name)throw Error(`extension name required`);if(`renderer`in e){let n=t.renderers[e.name];n?t.renderers[e.name]=function(...t){let r=e.renderer.apply(this,t);return r===!1&&(r=n.apply(this,t)),r}:t.renderers[e.name]=e.renderer}if(`tokenizer`in e){if(!e.level||e.level!==`block`&&e.level!==`inline`)throw Error(`extension level must be 'block' or 'inline'`);let n=t[e.level];n?n.unshift(e.tokenizer):t[e.level]=[e.tokenizer],e.start&&(e.level===`block`?t.startBlock?t.startBlock.push(e.start):t.startBlock=[e.start]:e.level===`inline`&&(t.startInline?t.startInline.push(e.start):t.startInline=[e.start]))}`childTokens`in e&&e.childTokens&&(t.childTokens[e.name]=e.childTokens)}),n.extensions=t),e.renderer){let t=this.defaults.renderer||new t_(this.defaults);for(let n in e.renderer){if(!(n in t))throw Error(`renderer '${n}' does not exist`);if([`options`,`parser`].includes(n))continue;let r=n,i=e.renderer[r],a=t[r];t[r]=(...e)=>{let n=i.apply(t,e);return n===!1&&(n=a.apply(t,e)),n||``}}n.renderer=t}if(e.tokenizer){let t=this.defaults.tokenizer||new $g(this.defaults);for(let n in e.tokenizer){if(!(n in t))throw Error(`tokenizer '${n}' does not exist`);if([`options`,`rules`,`lexer`].includes(n))continue;let r=n,i=e.tokenizer[r],a=t[r];t[r]=(...e)=>{let n=i.apply(t,e);return n===!1&&(n=a.apply(t,e)),n}}n.tokenizer=t}if(e.hooks){let t=this.defaults.hooks||new i_;for(let n in e.hooks){if(!(n in t))throw Error(`hook '${n}' does not exist`);if([`options`,`block`].includes(n))continue;let r=n,i=e.hooks[r],a=t[r];i_.passThroughHooks.has(n)?t[r]=e=>{if(this.defaults.async&&i_.passThroughHooksRespectAsync.has(n))return(async()=>{let n=await i.call(t,e);return a.call(t,n)})();let r=i.call(t,e);return a.call(t,r)}:t[r]=(...e)=>{if(this.defaults.async)return(async()=>{let n=await i.apply(t,e);return n===!1&&(n=await a.apply(t,e)),n})();let n=i.apply(t,e);return n===!1&&(n=a.apply(t,e)),n}}n.hooks=t}if(e.walkTokens){let t=this.defaults.walkTokens,r=e.walkTokens;n.walkTokens=function(e){let n=[];return n.push(r.call(this,e)),t&&(n=n.concat(t.call(this,e))),n}}this.defaults={...this.defaults,...n}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return e_.lex(e,t??this.defaults)}parser(e,t){return r_.parse(e,t??this.defaults)}parseMarkdown(e){return(t,n)=>{let r={...n},i={...this.defaults,...r},a=this.onError(!!i.silent,!!i.async);if(this.defaults.async===!0&&r.async===!1)return a(Error(`marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.`));if(typeof t>`u`||t===null)return a(Error(`marked(): input parameter is undefined or null`));if(typeof t!=`string`)return a(Error(`marked(): input parameter is of type `+Object.prototype.toString.call(t)+`, string expected`));if(i.hooks&&(i.hooks.options=i,i.hooks.block=e),i.async)return(async()=>{let n=i.hooks?await i.hooks.preprocess(t):t,r=await(i.hooks?await i.hooks.provideLexer(e):e?e_.lex:e_.lexInline)(n,i),a=i.hooks?await i.hooks.processAllTokens(r):r;i.walkTokens&&await Promise.all(this.walkTokens(a,i.walkTokens));let o=await(i.hooks?await i.hooks.provideParser(e):e?r_.parse:r_.parseInline)(a,i);return i.hooks?await i.hooks.postprocess(o):o})().catch(a);try{i.hooks&&(t=i.hooks.preprocess(t));let n=(i.hooks?i.hooks.provideLexer(e):e?e_.lex:e_.lexInline)(t,i);i.hooks&&(n=i.hooks.processAllTokens(n)),i.walkTokens&&this.walkTokens(n,i.walkTokens);let r=(i.hooks?i.hooks.provideParser(e):e?r_.parse:r_.parseInline)(n,i);return i.hooks&&(r=i.hooks.postprocess(r)),r}catch(e){return a(e)}}}onError(e,t){return n=>{if(n.message+=`
1194
- Please report this to https://github.com/markedjs/marked.`,e){let e=`<p>An error occurred:</p><pre>`+Wg(n.message+``,!0)+`</pre>`;return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}};function K(e,t){return a_.parse(e,t)}K.options=K.setOptions=function(e){return a_.setOptions(e),K.defaults=a_.defaults,jh(K.defaults),K},K.getDefaults=kh,K.defaults=Ah,K.use=function(...e){return a_.use(...e),K.defaults=a_.defaults,jh(K.defaults),K},K.walkTokens=function(e,t){return a_.walkTokens(e,t)},K.parseInline=a_.parseInline,K.Parser=r_,K.parser=r_.parse,K.Renderer=t_,K.TextRenderer=n_,K.Lexer=e_,K.lexer=e_.lex,K.Tokenizer=$g,K.Hooks=i_,K.parse=K,K.options,K.setOptions,K.use,K.walkTokens,K.parseInline,r_.parse,e_.lex;var o_=new K.Renderer;o_.html=({text:e})=>u_(e);var s_=300,c_=new Map;function l_(e){let t=c_.get(e);if(t!==void 0)return t;let n=d_(K.parse(e,{async:!1,breaks:!0,gfm:!0,renderer:o_}));if(c_.set(e,n),c_.size>s_){let e=c_.keys().next().value;e!==void 0&&c_.delete(e)}return n}function u_(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`)}function d_(e){let t=document.createElement(`template`);return t.innerHTML=e,t.content.querySelectorAll(`script, style, iframe, object, embed`).forEach(e=>{e.remove()}),t.content.querySelectorAll(`*`).forEach(e=>{for(let t of[...e.attributes]){let n=t.name.toLowerCase();n.startsWith(`on`)&&e.removeAttribute(t.name),(n===`href`||n===`src`)&&!f_(t.value)&&e.removeAttribute(t.name)}e.tagName===`A`&&(e.setAttribute(`target`,`_blank`),e.setAttribute(`rel`,`noreferrer noopener`))}),t.innerHTML}function f_(e){if(e.startsWith(`#`)||e.startsWith(`/`))return!0;try{return[`http:`,`https:`,`mailto:`].includes(new URL(e).protocol)}catch{return!1}}var p_=class extends v{constructor(...e){super(...e),this.text=``,this.onFormattedClick=e=>{if(!(e.target instanceof Element))return;let t=e.target.closest(`.code-copy-button`);if(!(t instanceof HTMLButtonElement))return;let n=t.closest(`.code-block-wrapper`);if(!(n instanceof HTMLElement))return;let r=n.querySelector(`pre code`);r instanceof HTMLElement&&this.copyCode(r.textContent,t)}}render(){return g`<div class="formatted" dir="auto" @click=${this.onFormattedClick}>${Oh(l_(this.text))}</div>`}updated(){this.enhanceCodeBlocks()}enhanceCodeBlocks(){this.renderRoot.querySelectorAll(`pre`).forEach(e=>{if(!(e instanceof HTMLPreElement)||e.parentElement?.classList.contains(`code-block-wrapper`)===!0||!(e.querySelector(`code`)instanceof HTMLElement))return;let t=document.createElement(`div`);t.className=`code-block-wrapper`;let n=document.createElement(`button`);n.type=`button`,n.className=`code-copy-button`,n.title=`Copy code block`,n.setAttribute(`aria-label`,`Copy code block`);let r=document.createElement(`span`);r.setAttribute(`aria-hidden`,`true`),r.textContent=`⧉`,n.append(r),e.before(t),t.append(e,n)})}async copyCode(e,t){let n=await Um(e);this.setCopyButtonState(t,n?`copied`:`failed`),window.setTimeout(()=>{this.setCopyButtonState(t,`idle`)},1200)}setCopyButtonState(e,t){let n=e.querySelector(`span`);n!==null&&(n.textContent=t===`copied`?`✓`:`⧉`);let r=t===`copied`?`Copied code block`:t===`failed`?`Failed to copy code block`:`Copy code block`;e.title=r,e.setAttribute(`aria-label`,r)}static{this.styles=$u}};R([b()],p_.prototype,`text`,void 0),p_=R([y(`formatted-text`)],p_);var m_=180,h_=class extends v{constructor(...e){super(...e),this.showFullDiff=!1,this.copied=!1,this.diffOpen=!0}render(){let e=this.execution;if(e===void 0)return null;let t=__(e.args),n=y_(e.details),r=e.preview,i=n??r?.diff,a=i===void 0?void 0:b_(i),o=n!==void 0&&r?.diff!==void 0&&n!==r.diff,s=e.status===`error`?e.resultText:r?.error,c=i===void 0?e.resultText:void 0,l=g_(e,t);return g`
1195
- <section class=${`tool-card ${e.status}`}>
1196
- <div class="tool-header">
1197
- <div class="tool-title">
1198
- <span class="status-icon" aria-hidden="true">${w_(e.status)}</span>
1199
- <strong>${e.toolName}</strong>
1200
- ${this.renderHeaderTarget(l)}
1201
- </div>
1202
- <div class="tool-meta">
1203
- ${v_(e)===void 0?null:g`<span>${v_(e)}</span>`}
1204
- ${a===void 0?null:g`<span class="diff-stats"><b class="added">+${a.added}</b><span>/</span><b class="removed">-${a.removed}</b></span>`}
1205
- <span class="status-label">${T_(e.status)}</span>
1206
- </div>
1207
- </div>
1208
-
1209
- ${o?g`<p class="notice">Applied diff differs from the preview.</p>`:null}
1210
- ${s===void 0||s===``?null:g`<pre class="error-text">${s}</pre>`}
1211
- ${i===void 0?this.renderTextBody(c,e.status===`error`,l):this.renderDiffBody(i,n===void 0?`Preview diff`:`Applied diff`,l)}
1212
- </section>
1213
- `}renderHeaderTarget(e){return e===void 0?null:g`<span class=${e.label===`File`?`path`:`summary`} title=${e.text} aria-label=${`${e.label}: ${e.text}`}>${e.text}</span>`}renderExpandedTarget(e){return e===void 0?null:g`
1214
- <div class="detail-target">
1215
- <span class="detail-label">${e.label}</span>
1216
- <pre class="detail-target-value">${e.text}</pre>
1217
- </div>
1218
- `}renderTextBody(e,t,n){return(e===void 0||e===``)&&n===void 0?null:g`
1219
- <details class="text-body" ?open=${t}>
1220
- <summary>Details</summary>
1221
- ${this.renderExpandedTarget(n)}
1222
- ${e===void 0||e===``?null:g`
1223
- <div class="detail-result">
1224
- <span class="detail-label">Result</span>
1225
- <pre>${e}</pre>
1226
- </div>
1227
- `}
1228
- </details>
1229
- `}renderDiffBody(e,t,n){let r=e.split(`
1230
- `),i=!this.showFullDiff&&r.length>m_,a=i?r.slice(0,m_):r;return g`
1231
- <details class="diff-details" ?open=${this.diffOpen} @toggle=${e=>{this.onDiffToggle(e)}}>
1232
- <summary>
1233
- <span>${t}</span>
1234
- <small>${String(r.length)} ${r.length===1?`line`:`lines`}</small>
1235
- </summary>
1236
- ${this.renderExpandedTarget(n)}
1237
- <div class="diff-toolbar">
1238
- <span>${i?`Showing ${String(a.length)} of ${String(r.length)} lines`:`Full diff`}</span>
1239
- <button type="button" @click=${()=>{this.copyDiff(e)}}>${this.copied?`Copied`:`Copy diff`}</button>
1240
- </div>
1241
- <pre class="diff" aria-label=${t}><code class="diff-content">${a.map(e=>g`<span class=${x_(e)}>${e}</span>`)}</code></pre>
1242
- ${i?g`
1243
- <button class="show-more" type="button" @click=${()=>{this.showFullDiff=!0}}>
1244
- Show all ${String(r.length)} diff lines
1245
- </button>
1246
- `:null}
1247
- </details>
1248
- `}onDiffToggle(e){let t=e.currentTarget;t instanceof HTMLDetailsElement&&(this.diffOpen=t.open)}async copyDiff(e){if(!await Um(e)){this.copied=!1;return}this.copied=!0,window.setTimeout(()=>{this.copied=!1},1200)}static{this.styles=h`
1249
- :host { display: block; width: 100%; max-width: 100%; min-width: 0; color: var(--pi-text); }
1250
- .tool-card { display: grid; gap: 8px; width: 100%; max-width: 100%; min-width: 0; box-sizing: border-box; overflow: hidden; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); padding: 9px; color: var(--pi-text); }
1251
- .tool-card.running, .tool-card.pending { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); }
1252
- .tool-card.success { border-color: var(--pi-success-border); background: var(--pi-success-bg); }
1253
- .tool-card.error { border-color: var(--pi-danger); background: color-mix(in srgb, var(--pi-danger) 10%, var(--pi-bg)); }
1254
- .tool-header { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; min-width: 0; }
1255
- .tool-title { flex: 1 1 auto; display: inline-flex; align-items: baseline; gap: 7px; min-width: 0; }
1256
- .status-icon { flex: 0 0 auto; color: var(--pi-muted); }
1257
- strong { flex: 0 0 auto; color: var(--pi-text); }
1258
- .path, .summary { display: block; flex: 1 1 auto; min-width: 0; max-width: 100%; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: thin; white-space: pre; color: var(--pi-accent); font: 13px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; direction: ltr; text-align: left; unicode-bidi: isolate; }
1259
- .summary { color: var(--pi-muted); font-family: inherit; }
1260
- .tool-meta { flex: 0 0 auto; display: inline-flex; align-items: baseline; gap: 8px; color: var(--pi-muted); font-size: 12px; }
1261
- .diff-stats { display: inline-flex; gap: 3px; }
1262
- .added, .diff .added { color: var(--pi-success); }
1263
- .removed, .diff .removed { color: var(--pi-danger); }
1264
- .status-label { text-transform: uppercase; letter-spacing: .04em; color: var(--pi-muted); }
1265
- .notice { margin: 0; color: var(--pi-warning); }
1266
- .muted { margin: 0; color: var(--pi-muted); }
1267
- .error-text { margin: 0; border: 1px solid var(--pi-danger); border-radius: 7px; background: color-mix(in srgb, var(--pi-danger) 10%, var(--pi-bg)); color: var(--pi-danger); padding: 8px; white-space: pre-wrap; overflow-wrap: anywhere; font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
1268
- .text-body { border-top: 1px solid var(--pi-border-muted); padding-top: 6px; }
1269
- .detail-target, .detail-result { display: grid; gap: 4px; margin-top: 8px; min-width: 0; }
1270
- .detail-label { color: var(--pi-muted); font-size: 12px; text-transform: uppercase; letter-spacing: .04em; }
1271
- .text-body pre { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--pi-text); }
1272
- .detail-result pre { box-sizing: border-box; max-width: 100%; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: thin; border: 1px solid var(--pi-border-muted); border-radius: 7px; background: var(--pi-bg); padding: 8px; white-space: pre; overflow-wrap: normal; direction: ltr; text-align: left; unicode-bidi: isolate; }
1273
- .detail-target-value { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--pi-accent); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; direction: ltr; text-align: left; unicode-bidi: isolate; }
1274
- .diff-details { min-width: 0; max-width: 100%; border-top: 1px solid var(--pi-border-muted); padding-top: 6px; }
1275
- .diff-details > summary { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; min-width: 0; color: var(--pi-muted); cursor: pointer; }
1276
- .diff-details > summary span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1277
- .diff-details > summary small { flex: 0 0 auto; color: var(--pi-dim); }
1278
- .diff-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; margin-top: 8px; color: var(--pi-muted); font-size: 12px; }
1279
- .diff-toolbar span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1280
- button { border: 1px solid var(--pi-border); border-radius: 6px; background: var(--pi-surface); color: var(--pi-text); padding: 3px 7px; font: 12px system-ui, sans-serif; cursor: pointer; }
1281
- button:hover, button:focus { border-color: var(--pi-accent); }
1282
- .diff { box-sizing: border-box; width: 100%; max-width: 100%; min-width: 0; margin: 0; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; border: 1px solid var(--pi-border-muted); border-radius: 7px; background: var(--pi-bg); padding: 8px 0; color: var(--pi-muted); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; line-height: 1.45; }
1283
- .diff-content { display: block; width: max-content; min-width: 100%; }
1284
- .diff span { display: block; min-height: 1.45em; padding: 0 8px; white-space: pre; }
1285
- .diff .context { color: var(--pi-muted); }
1286
- .diff .hunk { color: var(--pi-accent); }
1287
- .diff .file { color: var(--pi-dim); }
1288
- .diff .meta { color: var(--pi-dim); }
1289
- .diff .added { background: color-mix(in srgb, var(--pi-success) 12%, transparent); }
1290
- .diff .removed { background: color-mix(in srgb, var(--pi-danger) 12%, transparent); }
1291
- .show-more { justify-self: start; }
1292
- `}};R([b({attribute:!1})],h_.prototype,`execution`,void 0),R([x()],h_.prototype,`showFullDiff`,void 0),R([x()],h_.prototype,`copied`,void 0),R([x()],h_.prototype,`diffOpen`,void 0),h_=R([y(`tool-execution-view`)],h_);function g_(e,t){if(t!==void 0&&t!==``)return{label:`File`,text:t};let n=O_(e.args,`command`);if(n!==void 0&&n!==``)return{label:`Command`,text:n};if(e.summary!==``)return{label:`Input`,text:e.summary}}function __(e){return O_(e,`path`)??O_(e,`file_path`)}function v_(e){if(e.toolName!==`edit`)return;let t=D_(e.args,`edits`);if(Array.isArray(t))return`${String(t.length)} edit${t.length===1?``:`s`}`;if(typeof D_(e.args,`oldText`)==`string`&&typeof D_(e.args,`newText`)==`string`)return`1 edit`}function y_(e){return O_(e,`diff`)}function b_(e){let t=0,n=0;for(let r of e.split(`
1293
- `))S_(r)?t++:C_(r)&&n++;return{added:t,removed:n}}function x_(e){return S_(e)?`added`:C_(e)?`removed`:e.startsWith(`@@`)?`hunk`:e.startsWith(`+++`)||e.startsWith(`---`)?`file`:e.startsWith(`diff `)||e.startsWith(`index `)?`meta`:`context`}function S_(e){return e.startsWith(`+`)&&!e.startsWith(`+++`)}function C_(e){return e.startsWith(`-`)&&!e.startsWith(`---`)}function w_(e){return e===`success`?`✓`:e===`error`?`✖`:e===`running`?`●`:`○`}function T_(e){return e===`success`?`done`:e===`error`?`failed`:e===`running`?`running`:`pending`}function E_(e){return typeof e==`object`&&!!e}function D_(e,t){return E_(e)?e[t]:void 0}function O_(e,t){let n=D_(e,t);return typeof n==`string`?n:void 0}var k_=new Intl.DateTimeFormat(void 0,{dateStyle:`medium`,timeStyle:`medium`});function A_(e){return e===`error`?`⛔`:e===`info`?`ℹ️`:`⚠️`}function j_(e){return M_(e,0,100)}function M_(e,t,n){return Number.isFinite(e)?Math.min(n,Math.max(t,e)):t}function N_(e,t){return[e.length===0?void 0:{source:`client`,heading:`Queued until session starts`,detail:`Will send once the backend session is ready`,messages:e},t.length===0?void 0:{source:`server`,heading:`Queued messages`,detail:`${String(t.length)} pending`,messages:t}].filter(e=>e!==void 0)}function P_(e){return{src:`data:${e.mimeType};base64,${e.data}`,alt:`attached image`}}function F_(e){return e===void 0||e===``?`tool output`:`${e} output`}function I_(e){return`m:${String(e)}`}function L_(e){return`g:${String(e)}`}function R_(e){return`e:${String(e)}`}function z_(e){return`g:${String(e)}`}function B_(e){return e?`msg event-group live`:`msg event-group`}function V_(e){return e?`live events`:`events`}function H_(e,t,n){return e.source===`server`&&t&&n}function U_(e){return(e?.warnings??[]).map(e=>({severity:e.severity,severityClass:`session-warning ${e.severity}`,message:e.message,...e.source===void 0?{}:{source:e.source},...e.path===void 0?{}:{path:e.path},...e.dismiss===void 0?{}:{dismissId:e.dismiss.id}}))}function W_(e){let t=e.meta?.timestamp,n=[t===void 0?void 0:G_(t),K_(e)].filter(e=>e!==void 0&&e!==``);return n.length===0?`No Pi message metadata available`:n.join(` · `)}function G_(e){let t=new Date(e);if(Number.isFinite(t.getTime()))return k_.format(t)}function K_(e){let t=e.meta?.model;if(t===void 0)return;let n=t.responseId??t.id;return n===void 0||n===``?t.provider:t.provider!==void 0&&t.provider!==``?`${t.provider}/${n}`:n}var q=class extends v{constructor(...e){super(...e),this.messages=[],this.sessionId=``,this.messageStart=0,this.messageEnd=0,this.messageTotal=0,this.hasMore=!1,this.loadingMore=!1,this.isSendingPrompt=!1,this.isCompacting=!1,this.pendingMessageCount=0,this.clientQueuedMessages=[],this.canClearServerQueue=!1,this.pinnedToBottom=!0,this.zoomedImage=void 0,this.disclosures=new Mm,this.scrollController=new mh,this.suppressScrollSave=!1,this.suppressLoadMoreRequests=!1,this.groupedMessagesStart=0,this.groupedMessagesCache=[],this.messageMetaCache=new WeakMap,this.messageCopyTextCache=new WeakMap,this.lastScrollTop=0,this.lastClientHeight=0,this.prependRestoreToken=0,this.loadMoreRequested=!1,this.onViewportResize=()=>{this.pinnedToBottom?this.scrollToBottom():this.lastClientHeight=this.chat?.clientHeight??0},this.onImageLoad=()=>{this.pinnedToBottom&&this.scrollToBottom()},this.openImageZoom=(e,t)=>{this.zoomedImage={src:e,alt:t}},this.closeImageZoom=()=>{this.zoomedImage!==void 0&&(this.zoomedImage=void 0)},this.onImageZoomDialogClick=e=>{e.target===this.imageZoomDialog&&this.closeImageZoom()},this.onPageHide=()=>{this.saveScrollPosition()},this.handleClearServerQueue=()=>{this.onClearServerQueue?.()}}connectedCallback(){super.connectedCallback(),window.addEventListener(`resize`,this.onViewportResize),window.addEventListener(`pagehide`,this.onPageHide),window.visualViewport?.addEventListener(`resize`,this.onViewportResize)}firstUpdated(){this.lastClientHeight=this.chat?.clientHeight??0}disconnectedCallback(){this.saveScrollPosition(),this.scrollController.dispose(),this.prependRestoreToken+=1,this.restoreScrollFrame!==void 0&&cancelAnimationFrame(this.restoreScrollFrame),this.loadMoreCheckFrame!==void 0&&cancelAnimationFrame(this.loadMoreCheckFrame),this.scrollToBottomFrame!==void 0&&cancelAnimationFrame(this.scrollToBottomFrame),this.conversationRailFrame!==void 0&&cancelAnimationFrame(this.conversationRailFrame),window.removeEventListener(`resize`,this.onViewportResize),window.removeEventListener(`pagehide`,this.onPageHide),window.visualViewport?.removeEventListener(`resize`,this.onViewportResize),super.disconnectedCallback()}savePreviousSessionScrollPosition(e){typeof e!=`string`||e===``||e===this.sessionId||this.saveScrollPosition(e)}prepareSessionUiState(){this.disclosures.syncSession(this.sessionId),this.scrollController.clearScheduledSave(),this.suppressScrollSave=!1,this.suppressLoadMoreRequests=!1,this.pendingScrollRestoreSessionId=void 0,this.pendingScrollRestorePosition=void 0,this.prependRestoreToken+=1,this.restoreScrollFrame!==void 0&&(cancelAnimationFrame(this.restoreScrollFrame),this.restoreScrollFrame=void 0)}willUpdate(e){e.has(`sessionId`)&&(this.savePreviousSessionScrollPosition(e.get(`sessionId`)),this.prepareSessionUiState()),e.has(`messages`)&&(this.pinnedToBottom=this.pinnedToBottom&&(this.didChatHeightChange()||this.isNearBottom()))}update(e){let t=this.isPrependingMessages(e)?this.capturePrependScrollAnchor():void 0;super.update(e),t!==void 0&&this.restorePrependScrollAnchor(t)}updated(e){e.has(`loadingMore`)&&!this.loadingMore&&(this.loadMoreRequested=!1),e.has(`hasMore`)&&!this.hasMore&&(this.loadMoreRequested=!1),e.has(`sessionId`)&&this.restoreScrollPosition(),!e.has(`sessionId`)&&e.has(`messages`)&&this.pinnedToBottom&&this.scrollToBottom(),(e.has(`messages`)||e.has(`messageStart`)||e.has(`messageTotal`)||e.has(`hasMore`)||e.has(`loadingMore`))&&this.scheduleConversationRailUpdate(),(e.has(`messages`)||e.has(`messageStart`)||e.has(`hasMore`)||e.has(`loadingMore`))&&this.continuePendingScrollRestore(),(e.has(`messages`)||e.has(`hasMore`)||e.has(`loadingMore`))&&this.requestLoadMoreIfNeeded(),e.has(`zoomedImage`)&&this.syncImageZoomDialog()}syncImageZoomDialog(){let e=this.imageZoomDialog;e!==void 0&&(this.zoomedImage!==void 0&&!e.open?e.showModal():this.zoomedImage===void 0&&e.open&&e.close())}render(){let e=this.groupedMessages();return g`
1294
- ${this.renderWarnings()}
1295
- <div class="chat-wrap">
1296
- ${this.renderConversationRail()}
1297
- <div class="chat" @scroll=${()=>{this.onScroll()}} @wheel=${e=>{this.onWheel(e)}} @touchstart=${e=>{this.onTouchStart(e)}} @touchmove=${e=>{this.onTouchMove(e)}}>
1298
- ${this.renderHistoryBoundary()}
1299
- ${km(e,e=>e.kind===`group`?this.groupRenderKey(e.startIndex):this.messageAnchorKey(e.index),(t,n)=>t.kind===`group`?this.renderMessageGroup(t.messages,t.startIndex,t.endIndex,this.isLiveTailGroup(e,n)):t.kind===`tool-image`?this.renderToolImageOutput(t.message,t.index,t.toolName):this.renderMessage(t.message,t.index))}
1300
- ${this.renderQueuedMessages()}
1301
- ${this.renderSessionActivity()}
1302
- </div>
1303
- ${this.renderActivityDock()}
1304
- </div>
1305
- ${this.renderImageZoom()}
1306
- `}renderWarnings(){let e=U_(this.status);return e.length===0?null:g`
1307
- <aside class="session-warnings" role="alert" aria-live="polite">
1308
- ${e.map(e=>{let t=e.dismissId;return g`
1309
- <div class=${e.severityClass}>
1310
- <div class="session-warning-head">
1311
- <span class="session-warning-icon" aria-hidden="true">${A_(e.severity)}</span>
1312
- ${e.source===void 0?null:g`<span class="session-warning-source">${e.source}</span>`}
1313
- </div>
1314
- <div class="session-warning-body">
1315
- <p class="session-warning-message">${e.message}</p>
1316
- ${e.path===void 0?null:g`<p class="session-warning-path">${e.path}</p>`}
1317
- </div>
1318
- ${t===void 0?null:g`
1319
- <button
1320
- type="button"
1321
- class="session-warning-dismiss"
1322
- title="Don't show this warning again"
1323
- aria-label="Dismiss warning"
1324
- @click=${()=>{this.onDismissWarning?.(t)}}
1325
- >×</button>
1326
- `}
1327
- </div>
1328
- `})}
1329
- </aside>
1330
- `}renderImageZoom(){return g`
1331
- <dialog class="image-zoom" @click=${this.onImageZoomDialogClick} @close=${this.closeImageZoom} @cancel=${this.closeImageZoom}>
1332
- ${this.zoomedImage===void 0?null:g`
1333
- <button type="button" class="image-zoom-close" aria-label="Close image" @click=${this.closeImageZoom}>×</button>
1334
- <img class="image-zoom-full" src=${this.zoomedImage.src} alt=${this.zoomedImage.alt} />
1335
- `}
1336
- </dialog>
1337
- `}groupedMessages(){return this.groupedMessagesInput===this.messages&&this.groupedMessagesStart===this.messageStart?this.groupedMessagesCache:(this.groupedMessagesInput=this.messages,this.groupedMessagesStart=this.messageStart,this.groupedMessagesCache=Rm(this.messages,this.messageStart),this.groupedMessagesCache)}isLiveTailGroup(e,t){return t===e.length-1&&this.isSessionLive()}isSessionLive(){return this.isSendingPrompt||this.status?.isStreaming===!0||this.status?.isCompacting===!0||this.status?.isBashRunning===!0||this.activity?.phase===`active`}renderActivityDock(){if(this.isSendingPrompt)return g`
1338
- <div class="activity-dock active" aria-live="polite">
1339
- <span class="dot"></span>
1340
- <span class="activity-text">Sending your message…</span>
1341
- </div>
1342
- `;let e=this.activityState();return e===void 0?null:g`
1343
- <div class=${e!==`idle`||this.activity?.phase===`active`?`activity-dock active`:`activity-dock`} aria-live="polite">
1344
- <span class="dot"></span>
1345
- <span class="activity-text">${this.activityText(e)}</span>
1346
- </div>
1347
- `}renderQueuedMessages(){let e=this.status?.queuedMessages??[];return g`${N_(this.clientQueuedMessages,e).map(e=>this.renderQueuedMessageList(e))}`}renderQueuedMessageList(e){let t=H_(e,this.canClearServerQueue,this.onClearServerQueue!==void 0);return g`
1348
- <aside class="queued-messages" aria-live="polite">
1349
- <div class="queued-header">
1350
- <div class="queued-heading">
1351
- <strong>${e.heading}</strong>
1352
- <small>${e.detail}</small>
1353
- </div>
1354
- ${t?g`
1355
- <button type="button" class="queued-clear-button" title="Clear queued messages without stopping active work" @click=${this.handleClearServerQueue}>Clear queue</button>
1356
- `:null}
1357
- </div>
1358
- ${e.messages.map((e,t)=>g`
1359
- <div class="queued-message">
1360
- <span class="queued-kind">${e.kind===`steer`?`Steer`:`Follow-up`} ${String(t+1)}</span>
1361
- <formatted-text .text=${e.text}></formatted-text>
1362
- </div>
1363
- `)}
1364
- </aside>
1365
- `}renderSessionActivity(){return this.isCompacting?g`
1366
- <aside class="session-activity compacting" aria-live="polite">
1367
- <strong>Compacting history…</strong>
1368
- <span>The agent is summarizing earlier context. New prompts will be queued until compaction finishes.</span>
1369
- ${this.pendingMessageCount>0?g`<small>${this.pendingMessageCount} queued ${this.pendingMessageCount===1?`message`:`messages`}</small>`:null}
1370
- </aside>
1371
- `:null}activityState(){let e=this.status;return e===void 0?this.activity?.label:e.isCompacting?`compacting`:e.isBashRunning?`bash`:e.isStreaming?`running`:e.pendingMessageCount>0?`queued`:`idle`}activityText(e){let t=this.activity;return t===void 0||e!==`idle`&&t.phase===`idle`?e:t.detail!==void 0&&t.detail!==``?`${t.label}: ${t.detail}`:t.label}renderConversationRail(){if(!this.messages.length||this.messageTotal<=0)return null;let e=this.conversationDisplayTotal();return g`<conversation-meter .positionPercent=${this.conversationPositionPercent(e)} .loadedPercent=${this.hasMore?j_(this.messages.length/e*100):100}></conversation-meter>`}conversationDisplayTotal(){return!this.hasMore&&this.messageStart===0?Math.max(1,this.messages.length):Math.max(1,this.messageTotal,this.messageStart+this.messages.length)}conversationPositionPercent(e=this.conversationDisplayTotal()){if(e<=1)return 100;let t=this.pinnedToBottom?this.messageStart+this.messages.length-1:this.messageStart;return j_(M_(this.currentConversationIndex??t,0,e-1)/(e-1)*100)}renderHistoryBoundary(){let e=this.historyRangeLabel();return this.loadingMore?g`<div class="history-boundary"><span>Loading earlier messages…</span>${e}</div>`:this.hasMore?g`
1372
- <div class="history-boundary">
1373
- <button type="button" class="history-load-button" ?disabled=${this.loadMoreRequested} @click=${()=>{this.requestLoadMore()}}>Load earlier messages</button>
1374
- <span>Scroll up to load earlier messages</span>
1375
- ${e}
1376
- </div>
1377
- `:this.messages.length?g`<div class="history-boundary"><span>Beginning of session</span>${e}</div>`:null}historyRangeLabel(){if(!this.messages.length||this.messageTotal<=0)return null;let e=this.messageStart+1,t=this.loadedRawMessageEnd();return g`<small>Showing messages ${e}–${t} of ${Math.max(this.messageTotal,t)}</small>`}loadedRawMessageEnd(){return Math.max(this.messageEnd,this.messageStart+this.messages.length)}renderMessage(e,t){let n=this.isToolExecutionOnlyMessage(e);return g`
1378
- ${this.renderScrollMarker(this.messageScrollMarkerId(t))}
1379
- <article class=${n?`msg tool-execution-shell`:`msg ${e.role}`} data-index=${t} data-scroll-anchor-id=${this.messageAnchorKey(t)}>
1380
- ${n?null:this.renderMessageHeader(e,String(t))}
1381
- ${e.parts.map(t=>this.renderPart(t,e))}
1382
- </article>
1383
- `}renderToolImageOutput(e,t,n){let r=F_(n);return g`
1384
- ${this.renderScrollMarker(this.messageScrollMarkerId(t))}
1385
- <article class="msg tool-image-output" data-index=${t} data-scroll-anchor-id=${this.messageAnchorKey(t)}>
1386
- ${this.renderMessageHeader(e,String(t),r)}
1387
- ${e.parts.map(t=>this.renderPart(t,e))}
1388
- </article>
1389
- `}isToolExecutionOnlyMessage(e){return e.role===`tool`&&e.parts.length>0&&e.parts.every(e=>e.type===`toolExecution`)}renderMessageGroup(e,t,n,r){let i=this.groupDisclosureKey(t,n,r),a=this.disclosures.isOpen(i,r);return g`
1390
- ${this.renderScrollMarker(this.groupScrollMarkerId(n))}
1391
- <details class=${B_(r)} data-index=${t} data-scroll-anchor-id=${this.groupAnchorKey(t)} ?open=${a} @toggle=${e=>{this.onGroupToggle(i,e,r)}}>
1392
- <summary>
1393
- <b class="label">${V_(r)}</b>
1394
- <span>${zm(e)}</span>
1395
- </summary>
1396
- ${a?this.renderMessageGroupBody(e,t):null}
1397
- </details>
1398
- `}renderMessageGroupBody(e,t){return g`
1399
- <div class="group-body">
1400
- ${e.map((e,n)=>{let r=this.isToolExecutionOnlyMessage(e);return g`
1401
- <section class=${r?`group-msg tool-execution-shell`:`group-msg ${e.role}`} data-index=${t+n} data-scroll-anchor-id=${this.eventAnchorKey(t+n)}>
1402
- ${r?null:this.renderMessageHeader(e,`${String(t)}:${String(n)}`)}
1403
- ${e.parts.map(t=>this.renderPart(t,e))}
1404
- </section>
1405
- `})}
1406
- </div>
1407
- `}renderScrollMarker(e){return g`<span class="scroll-marker" data-marker-id=${e} aria-hidden="true"></span>`}renderMessageHeader(e,t,n=e.role){let r=this.messageMetaLabel(e),i=this.expandedMetaKey===t;return g`
1408
- <div class="msg-header">
1409
- <b class="label">${n}</b>
1410
- <div class="msg-header-trailing">
1411
- ${this.renderMessageActions(e,t)}
1412
- <span class=${i?`msg-meta expanded`:`msg-meta`} role="button" tabindex="0" title=${r} aria-label=${r} aria-expanded=${String(i)} @click=${()=>{this.expandedMetaKey=i?void 0:t}} @keydown=${e=>{this.onMetaKeydown(e,t,i)}}>${r}</span>
1413
- </div>
1414
- </div>
1415
- `}renderMessageActions(e,t){if(!this.isCopyableMessage(e))return null;let n=this.copiedMessageKey===t;return g`
1416
- <div class="msg-actions" aria-label="Message actions">
1417
- <button type="button" class="msg-action" title=${n?`Copied`:`Copy message`} aria-label=${`${n?`Copied`:`Copy`} ${e.role} message`} @click=${n=>{this.copyMessage(e,t,n)}}>
1418
- <span aria-hidden="true">${n?`✓`:`⧉`}</span>
1419
- </button>
1420
- </div>
1421
- `}onMetaKeydown(e,t,n){e.key!==`Enter`&&e.key!==` `||(e.preventDefault(),this.expandedMetaKey=n?void 0:t)}isCopyableMessage(e){return(e.role===`user`||e.role===`assistant`)&&this.messageCopyText(e)!==``}messageCopyText(e){let t=this.messageCopyTextCache.get(e);if(t!==void 0)return t;let n=e.parts.filter(e=>e.type===`text`).map(e=>e.text.trim()).filter(e=>e!==``).join(`
1422
-
1423
- `);return this.messageCopyTextCache.set(e,n),n}async copyMessage(e,t,n){n.stopPropagation(),await Um(this.messageCopyText(e))&&(this.copiedMessageKey=t,window.setTimeout(()=>{this.copiedMessageKey===t&&(this.copiedMessageKey=void 0)},1200))}messageMetaLabel(e){let t=this.messageMetaCache.get(e);if(t!==void 0)return t;let n=W_(e);return this.messageMetaCache.set(e,n),n}renderPart(e,t){if(e.type===`text`&&t?.role===`bash`)return g`<pre class="part shell-output">${e.text}</pre>`;if(e.type===`text`)return g`<formatted-text class="part" .text=${e.text}></formatted-text>`;if(e.type===`thinking`)return g`<details class="part"><summary>thinking</summary><formatted-text .text=${e.text}></formatted-text></details>`;if(e.type===`skillInvocation`)return g`
1424
- <details class="part skill-invocation">
1425
- <summary><b>[skill]</b> ${e.name}</summary>
1426
- <small>${e.location}</small>
1427
- <formatted-text .text=${e.content}></formatted-text>
1428
- </details>
1429
- `;if(e.type===`skillRead`)return g`
1430
- <div class="part skill-read">
1431
- <strong>Loaded ${e.name}</strong>
1432
- <small>read ${e.path}</small>
1433
- </div>
1434
- `;if(e.type===`image`){let{src:t,alt:n}=P_(e);return g`<img class="part chat-image" src=${t} alt=${n} loading="lazy" role="button" tabindex="0" title="Click to enlarge" @load=${this.onImageLoad} @click=${()=>{this.openImageZoom(t,n)}} @keydown=${e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),this.openImageZoom(t,n))}} />`}return e.type===`toolCall`?g`<div class="part tool-line">▶ ${e.toolName}<span class="summary">${e.summary}</span></div>`:e.type===`toolExecution`?g`<tool-execution-view class="part" .execution=${e}></tool-execution-view>`:e.type===`toolResult`?g`
1435
- <details class="part" ?open=${e.isError}>
1436
- <summary>${e.isError?`✖`:`✓`} ${e.toolName} result</summary>
1437
- <formatted-text .text=${e.text}></formatted-text>
1438
- </details>
1439
- `:null}onGroupToggle(e,t,n){let r=t.currentTarget;r instanceof HTMLDetailsElement&&this.disclosures.applyToggle(e,r.open,n)&&this.requestUpdate()}onScroll(){this.requestLoadMoreIfNeeded(),this.updatePinnedToBottomFromScroll(),this.scheduleConversationRailUpdate(),this.suppressScrollSave||this.scheduleScrollPositionSave()}onWheel(e){e.deltaY<0&&this.canScrollUp()&&(this.pinnedToBottom=!1)}onTouchStart(e){this.touchStartY=e.touches[0]?.clientY}onTouchMove(e){let t=e.touches[0]?.clientY;this.touchStartY!==void 0&&t!==void 0&&t>this.touchStartY&&this.canScrollUp()&&(this.pinnedToBottom=!1)}updatePinnedToBottomFromScroll(){let e=this.chat;if(!e)return;let t=this.didChatHeightChange(),n=this.pinnedToBottom,r=e.scrollTop<this.lastScrollTop;if(t&&n){this.lastClientHeight=e.clientHeight,this.scrollToBottom();return}this.isAtBottom()?this.pinnedToBottom=!0:r?this.pinnedToBottom=!1:this.pinnedToBottom=this.isNearBottom(),this.lastScrollTop=e.scrollTop,this.lastClientHeight=e.clientHeight}didChatHeightChange(){let e=this.chat;return e!==void 0&&this.lastClientHeight!==0&&e.clientHeight!==this.lastClientHeight}isPrependingMessages(e){let t=e.get(`messageStart`);return typeof t==`number`&&this.messageStart<t}requestLoadMoreIfNeeded(){this.loadMoreCheckFrame===void 0&&(this.loadMoreCheckFrame=requestAnimationFrame(()=>{if(this.loadMoreCheckFrame=void 0,this.suppressLoadMoreRequests)return;let e=this.chat;e&&ah({hasMore:this.hasMore,loadingMore:this.loadingMore||this.loadMoreRequested,canRequest:this.onLoadMore!==void 0,scrollTop:e.scrollTop,scrollHeight:e.scrollHeight,clientHeight:e.clientHeight})&&this.requestLoadMore()}))}requestLoadMore(){this.loadMoreRequested||!this.hasMore||this.loadingMore||this.onLoadMore===void 0||(this.loadMoreRequested=!0,this.onLoadMore())}isNearBottom(){let e=this.chat;return!e||yh(e)}isAtBottom(){let e=this.chat;return!e||vh(e)<2}canScrollUp(){let e=this.chat;return e!==void 0&&e.scrollTop>0}scrollToBottom(){this.scrollToBottomFrame===void 0&&(this.scrollToBottomFrame=requestAnimationFrame(()=>{this.scrollToBottomFrame=void 0;let e=this.chat;e&&this.withSuppressedScrollSave(()=>{e.scrollTop=e.scrollHeight,this.lastScrollTop=e.scrollTop,this.lastClientHeight=e.clientHeight})}))}restoreScrollPosition(){let e=this.sessionId;this.restoreScrollFrame!==void 0&&cancelAnimationFrame(this.restoreScrollFrame),this.restoreScrollFrame=requestAnimationFrame(()=>{this.restoreScrollFrame=void 0,this.sessionId===e&&this.withSuppressedScrollSave(()=>{let t=this.scrollController.restorePosition(e,this.chat,this.scrollAnchorElements(),{fallbackToBottom:this.shouldFallbackToBottomForMissingAnchor()});this.handleScrollRestoreResult(e,t)})})}continuePendingScrollRestore(){let e=this.pendingScrollRestoreSessionId,t=this.pendingScrollRestorePosition;e===void 0||t===void 0||e!==this.sessionId||this.restoreScrollFrame!==void 0||(this.restoreScrollFrame=requestAnimationFrame(()=>{this.restoreScrollFrame=void 0,this.sessionId===e&&this.withSuppressedScrollSave(()=>{let n=this.scrollController.restoreExplicitPosition(t,this.chat,this.scrollAnchorElements(),{fallbackToBottom:this.shouldFallbackToBottomForMissingAnchor()});this.handleScrollRestoreResult(e,n)})}))}handleScrollRestoreResult(e,t){if(this.syncScrollMetrics(),t.status!==`missing`){this.updatePinnedToBottomAfterRestore(t.status),(t.status===`restored`||t.status===`bottom`)&&this.cancelPrependRestore(),this.pendingScrollRestoreSessionId=void 0,this.pendingScrollRestorePosition=void 0;return}this.pinnedToBottom=!1,this.pendingScrollRestoreSessionId=e,this.pendingScrollRestorePosition=t.position;let n=this.chat;n===void 0||!this.hasMore||this.loadingMore||(n.scrollTop=0,this.syncScrollMetrics(),this.requestLoadMore())}shouldFallbackToBottomForMissingAnchor(){return!this.hasMore}updatePinnedToBottomAfterRestore(e){e===`bottom`?this.pinnedToBottom=!0:e===`restored`&&(this.pinnedToBottom=this.isNearBottom())}syncScrollMetrics(){let e=this.chat;e!==void 0&&(this.lastScrollTop=e.scrollTop,this.lastClientHeight=e.clientHeight)}cancelPrependRestore(){this.prependRestoreToken+=1,this.suppressLoadMoreRequests=!1}capturePrependScrollAnchor(){let e=this.chat;if(e)return Zm(e,this.scrollMarkers())}restorePrependScrollAnchor(e){if(!this.chat||!e)return;this.suppressLoadMoreRequests=!0,this.suppressScrollSave=!0;let t=this.prependRestoreToken+1;this.prependRestoreToken=t;let n=0,r=()=>{let i=this.chat;if(!(!i||t!==this.prependRestoreToken)){if(Qm(i,e,e.markerId===void 0?void 0:this.scrollMarkerAt(e.markerId)),this.lastScrollTop=i.scrollTop,n+=1,n<30){requestAnimationFrame(r);return}requestAnimationFrame(()=>{t===this.prependRestoreToken&&(this.suppressScrollSave=!1,this.suppressLoadMoreRequests=!1)})}};r()}saveScrollPosition(e=this.sessionId){e&&this.scrollController.savePosition(e,this.chat,this.scrollAnchorElements())}scheduleScrollPositionSave(){let e=this.sessionId;this.scrollController.scheduleSave(e,e=>{this.sessionId===e&&this.saveScrollPosition(e)})}scheduleConversationRailUpdate(){this.conversationRailFrame===void 0&&(this.conversationRailFrame=requestAnimationFrame(()=>{this.conversationRailFrame=void 0,this.updateConversationRailPosition()}))}updateConversationRailPosition(){if(!this.messages.length||this.messageTotal<=0){this.currentConversationIndex=void 0;return}let e=this.conversationDisplayTotal(),t=this.firstVisibleArticle(),n=Number(t?.dataset.index);if(Number.isFinite(n)){this.currentConversationIndex=M_(n,0,Math.max(0,e-1));return}this.currentConversationIndex=M_(this.pinnedToBottom?this.messageStart+this.messages.length-1:this.messageStart,0,Math.max(0,e-1))}scrollMarkers(){return Array.from(this.renderRoot.querySelectorAll(`.scroll-marker`))}scrollMarkerAt(e){return this.scrollMarkers().find(t=>t.dataset.markerId===e)}firstVisibleArticle(){let e=this.chat;if(e!==void 0)return Sh(e,Array.from(this.renderRoot.querySelectorAll(`article.msg`)))??Sh(e,this.articles())}articles(){return Array.from(this.renderRoot.querySelectorAll(`article.msg, details.msg`))}scrollAnchorElements(){return Array.from(this.renderRoot.querySelectorAll(`[data-scroll-anchor-id]`))}withSuppressedScrollSave(e){this.suppressScrollSave=!0,e(),requestAnimationFrame(()=>{requestAnimationFrame(()=>{this.suppressScrollSave=!1})})}groupDisclosureKey(e,t,n){return n?`${this.sessionId}:live:${String(e)}`:`${this.sessionId}:${String(t)}`}messageAnchorKey(e){return I_(e)}groupRenderKey(e){return L_(e)}groupAnchorKey(e){return L_(e)}eventAnchorKey(e){return R_(e)}messageScrollMarkerId(e){return I_(e)}groupScrollMarkerId(e){return z_(e)}static{this.styles=Qu}};R([b({attribute:!1})],q.prototype,`messages`,void 0),R([b()],q.prototype,`sessionId`,void 0),R([b({type:Number})],q.prototype,`messageStart`,void 0),R([b({type:Number})],q.prototype,`messageEnd`,void 0),R([b({type:Number})],q.prototype,`messageTotal`,void 0),R([b({type:Boolean})],q.prototype,`hasMore`,void 0),R([b({type:Boolean})],q.prototype,`loadingMore`,void 0),R([b({type:Boolean})],q.prototype,`isSendingPrompt`,void 0),R([b({type:Boolean})],q.prototype,`isCompacting`,void 0),R([b({type:Number})],q.prototype,`pendingMessageCount`,void 0),R([b({attribute:!1})],q.prototype,`clientQueuedMessages`,void 0),R([b({attribute:!1})],q.prototype,`status`,void 0),R([b({attribute:!1})],q.prototype,`activity`,void 0),R([b({type:Boolean})],q.prototype,`canClearServerQueue`,void 0),R([b({attribute:!1})],q.prototype,`onClearServerQueue`,void 0),R([b({attribute:!1})],q.prototype,`onDismissWarning`,void 0),R([b({attribute:!1})],q.prototype,`onLoadMore`,void 0),R([S(`.chat`)],q.prototype,`chat`,void 0),R([S(`dialog.image-zoom`)],q.prototype,`imageZoomDialog`,void 0),R([x()],q.prototype,`pinnedToBottom`,void 0),R([x()],q.prototype,`zoomedImage`,void 0),R([x()],q.prototype,`expandedMetaKey`,void 0),R([x()],q.prototype,`copiedMessageKey`,void 0),R([x()],q.prototype,`currentConversationIndex`,void 0),R([x()],q.prototype,`loadMoreRequested`,void 0),q=R([y(`chat-view`)],q);var q_=new Set([`image/jpeg`,`image/png`,`image/gif`,`image/webp`]);function J_(e){return typeof e==`string`&&q_.has(e)}function Y_(e){switch(e){case`image/jpeg`:return`jpg`;case`image/png`:return`png`;case`image/gif`:return`gif`;case`image/webp`:return`webp`;default:return`bin`}}var X_=`application/octet-stream`,Z_=`Failed to read an attachment.`;async function Q_(e,t){let n=[],r;for(let i of e)try{let e=await t(i);n.push(nv(i,e))}catch{r=Z_}return{attachments:n,...r===void 0?{}:{error:r}}}function $_(e){return e.kind===`image`&&J_(e.mimeType)}function ev(e){return e.every(e=>$_(e))}function tv(e,t){return ev(t)?e:`folder`}function nv(e,t){return J_(e.type)?{kind:`image`,name:iv(e),mimeType:e.type,data:t,size:e.size}:{kind:`file`,name:iv(e),mimeType:rv(e),data:t,size:e.size}}function rv(e){let t=e.type.trim();return t===``?X_:t}function iv(e){return e.name===``?J_(e.type)?`pasted-image.${Y_(e.type)}`:`pasted-file.bin`:e.name}var av=`pi-web:attachment-delivery`;function ov(){try{return typeof localStorage>`u`?void 0:localStorage}catch{return}}function sv(e=ov()){try{return e?.getItem(av)===`folder`?`folder`:`inline`}catch{return`inline`}}function cv(e,t=ov()){try{t?.setItem(av,e)}catch{}}var lv=`(pointer: coarse), (max-width: 760px)`,uv=`pi-web.promptEnterPreference`;function dv(){return typeof window<`u`&&`matchMedia`in window?window.matchMedia(lv):void 0}function fv(e){return e===`send`||e===`newline`?e:`auto`}function pv(e=vv()){if(e===void 0)return`auto`;try{return fv(e.getItem(uv))}catch{return`auto`}}function mv(e,t=vv()){if(t!==void 0)try{t.setItem(uv,e)}catch{}}function hv(e=dv(),t=pv()){return t===`send`||t!==`newline`&&e?.matches!==!0}function gv(e,t,n=dv()){return e?n?.matches!==!0||t:!1}function _v(e,t=dv(),n=pv()){let r=hv(t,n);return e?!r:r}function vv(){if(!(typeof window>`u`))try{return window.localStorage}catch{return}}function yv(){return Je`
1440
- <svg class="prompt-action-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
1441
- <path d="M20 11.5 12.5 19a4 4 0 0 1-5.66-5.66l7.07-7.07a2.5 2.5 0 0 1 3.54 3.54l-7.07 7.07a1 1 0 0 1-1.42-1.42l6.37-6.36"></path>
1442
- </svg>
1443
- `}function bv(){return Je`
1444
- <svg class="prompt-action-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
1445
- <path d="M21 3 13.5 21l-2-8.5L3 10.5Z"></path>
1446
- <path d="M21 3 11.5 12.5"></path>
1447
- </svg>
1448
- `}function xv(){return Je`
1449
- <svg class="prompt-action-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
1450
- <path d="M4 7h11"></path>
1451
- <path d="M4 12h7"></path>
1452
- <path d="M4 17h7"></path>
1453
- <path d="m15 14 5 3-5 3z"></path>
1454
- </svg>
1455
- `}function Sv(){return bv()}function Cv(){return Je`
1456
- <svg class="prompt-action-icon prompt-action-icon-filled" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
1457
- <rect x="6.5" y="6.5" width="11" height="11" rx="2"></rect>
1458
- </svg>
1459
- `}function wv(e){let t=Math.max(e.total,1),n=t>1?1.2:0,r=(18-n*(t-1))/t;return Je`
1460
- <svg class="prompt-thinking-gauge" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
1461
- ${Array.from({length:t},(i,a)=>{let o=3+a*(r+n),s=4+(a+1)/t*12,c=20-s;return Je`<rect class=${a<e.filled?`gauge-bar gauge-bar-active`:`gauge-bar`} x=${o} y=${c} width=${r} height=${s} rx="1"></rect>`})}
1462
- </svg>
1463
- `}var Tv=[`off`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`];function Ev(e){return e===void 0||e===``?`off`:e}function Dv(e,t){let n=t.length>=2?t:Tv,r=n.length-1,i=Ev(e),a=n.indexOf(i);return{total:r,filled:a<=0?0:Math.min(a,r)}}var Ov=_m(class extends vm{constructor(e){super(e),this.wasSelected=!1,this.isElementPart=e.type===gm.ELEMENT}update(e,[t,n]){if(!this.isElementPart)throw Error(`scrollWhenSelected must be used on an element`);if(t&&(!this.wasSelected||n!==this.previousKey)){let t=`element`in e?e.element:void 0;requestAnimationFrame(()=>{t instanceof HTMLElement&&t.scrollIntoView({block:`nearest`})})}this.wasSelected=t,this.previousKey=n}render(e,t){}}),kv=class extends v{constructor(...e){super(...e),this.items=[],this.selectedIndex=0}render(){return this.items.length?g`
1464
- <div class="menu">
1465
- ${this.items.map((e,t)=>g`
1466
- <button class=${t===this.selectedIndex?`selected`:``} ${Ov(t===this.selectedIndex,e)} @mousedown=${t=>{t.preventDefault(),this.onPick?.(e)}}>
1467
- <strong>${e.insertText}</strong>
1468
- <span>${e.detail}</span>
1469
- ${e.description!==void 0&&e.description!==``?g`<small>${e.description}</small>`:null}
1470
- </button>
1471
- `)}
1472
- </div>
1473
- `:null}static{this.styles=td}};R([b({attribute:!1})],kv.prototype,`items`,void 0),R([b({type:Number})],kv.prototype,`selectedIndex`,void 0),R([b({attribute:!1})],kv.prototype,`onPick`,void 0),kv=R([y(`autocomplete-menu`)],kv);var J=class extends v{constructor(...e){super(...e),this.disabled=!1,this.machineId=`local`,this.workspaceScopedFileSuggestions=!1,this.canSteer=!1,this.isCompacting=!1,this.canStop=!1,this.sending=!1,this.availableThinkingLevels=[],this.draft=``,this.currentInputMode={kind:`normal`},this.completions=[],this.selectedIndex=0,this.attachments=[],this.attachmentDelivery=sv(),this.attachmentError=void 0,this.attachmentSeq=0,this.requestVersion=0,this.editableCompartment=new s,this.readOnlyCompartment=new s,this.mobilePromptEnterMedia=dv(),this.explicitShiftKeyActive=!1}willUpdate(e){if(!e.has(`sessionId`)&&!e.has(`machineId`))return;let t=e.has(`sessionId`)?e.get(`sessionId`):this.sessionId,n=jv(e.has(`machineId`)?e.get(`machineId`):this.machineId,t);n!==void 0&&Go(n,this.draft);let r=jv(this.machineId,this.sessionId);this.draft=r===void 0?``:Wo(r),this.currentInputMode=$s(this.draft),this.completions=[],this.selectedIndex=0}shouldUpdate(e){return e.has(`status`)&&e.size===1?!Av(e.get(`status`),this.status):!0}firstUpdated(){this.createEditor()}updated(e){e.has(`disabled`)&&this.updateEditorDisabledState(),(e.has(`sessionId`)||e.has(`machineId`))&&this.syncEditorDoc()}disconnectedCallback(){this.editor?.destroy(),this.editor=void 0,super.disconnectedCallback()}render(){let e=this.currentInputMode.kind===`shell`?this.currentInputMode:void 0,t=e!==void 0,n=this.canSteer||this.isCompacting,r=this.disabled||this.sending;return g`
1474
- <footer class=${t?`shell-mode`:``} @paste=${e=>{this.handlePaste(e)}} @dragover=${e=>{this.handleDragOver(e)}} @drop=${e=>{this.handleDrop(e)}}>
1475
- <div class="editor-wrap">
1476
- <div class=${`markdown-editor${this.disabled?` markdown-editor-disabled`:``}`} aria-label="Message pi" aria-disabled=${this.disabled?`true`:`false`}></div>
1477
- <input class="attachment-input" type="file" multiple hidden @change=${e=>{this.handleFileInput(e)}} />
1478
- <button class="editor-attach icon-button" ?disabled=${r} title="Attach files" aria-label="Attach files" @click=${()=>{this.attachmentInput?.click()}}>${yv()}</button>
1479
- ${t?g`<div class="mode-hint">Shell command${e.excludeFromContext?` · excluded from context`:``}</div>`:null}
1480
- ${this.isCompacting&&!t?g`<div class="mode-hint">Compacting history · message will be queued</div>`:null}
1481
- ${this.renderAttachments()}
1482
- <autocomplete-menu .items=${this.completions} .selectedIndex=${this.selectedIndex} .onPick=${e=>{this.pick(e)}}></autocomplete-menu>
1483
- </div>
1484
- <div class="actions">
1485
- ${this.renderCompactStatus()}
1486
- <button class="icon-button send-button" ?disabled=${r} title=${n?`Queue until the current activity finishes`:`Send message`} aria-label=${n?`Queue message`:`Send message`} @click=${()=>{this.send(`followUp`)}}>${n?xv():bv()}</button>
1487
- ${this.canSteer&&!this.isCompacting?g`<button class="icon-button steer-button" ?disabled=${r} title="Steer the current response before the next model call" aria-label="Steer current response" @click=${()=>{this.send(`steer`)}}>${Sv()}</button>`:null}
1488
- <button class="icon-button stop-button" ?disabled=${this.disabled||!this.canStop} title=${this.canStop?`Stop current work and clear queued messages`:`Nothing running`} aria-label="Stop current work" @click=${()=>this.onStop?.()}>${Cv()}</button>
1489
- </div>
1490
- </footer>
1491
- `}focusInput(){this.editor?.focus()}get view(){return this.editor}renderCompactStatus(){let e=this.status;if(e===void 0)return null;let t=e.model?.id??`no model`;return g`
1492
- <div class="compact-status" aria-label="Session status">
1493
- <button class="select-model" title="Select model" @click=${()=>this.onSelectModel?.()}>${e.model?.provider!==void 0&&e.model.provider!==``?`${e.model.provider}/`:``}${t}</button>
1494
- <button class="select-thinking icon-button" title=${`Thinking level: ${Ev(e.thinkingLevel)}`} aria-label=${`Thinking level: ${Ev(e.thinkingLevel)}`} @click=${()=>this.onSelectThinking?.()}>${wv(Dv(e.thinkingLevel,this.availableThinkingLevels))}</button>
1495
- </div>
1496
- `}renderAttachments(){if(this.attachments.length===0&&this.attachmentError===void 0)return null;let e=ev(this.attachments),t=this.effectiveAttachmentDelivery();return g`
1497
- <div class="attachments" aria-label="Pending attachments">
1498
- ${this.attachments.map(e=>g`
1499
- <div class=${`attachment-chip ${$_(e)?`attachment-chip-image`:`attachment-chip-file`}`} title=${e.name}>
1500
- ${this.renderAttachmentPreview(e)}
1501
- <button type="button" class="attachment-remove" title="Remove attachment" aria-label=${`Remove ${e.name}`} @click=${()=>{this.removeAttachment(e.id)}}>×</button>
1502
- </div>
1503
- `)}
1504
- ${this.attachments.length>0?g`
1505
- <label class="attachment-delivery" title=${e?`How attachments are delivered to the agent`:`General files are saved and mentioned from the workspace`}>
1506
- <select .value=${t} @change=${e=>{this.changeDelivery(e)}}>
1507
- <option value="inline" ?disabled=${!e}>Attach to message${e?``:` (images only)`}</option>
1508
- <option value="folder">Save to .pi-web/attachments</option>
1509
- </select>
1510
- </label>
1511
- `:null}
1512
- ${this.attachmentError===void 0?null:g`<div class="attachment-error">${this.attachmentError}</div>`}
1513
- </div>
1514
- `}renderAttachmentPreview(e){return $_(e)?g`<img src=${`data:${e.mimeType};base64,${e.data}`} alt=${e.name} />`:g`
1515
- <div class="attachment-file-preview" aria-hidden="true">${Lv(e.name)}</div>
1516
- <span class="attachment-file-name">${e.name}</span>
1517
- `}changeDelivery(e){if(!(e.target instanceof HTMLSelectElement))return;let t=e.target.value===`folder`?`folder`:`inline`;if(t===`inline`&&!ev(this.attachments)){e.target.value=`folder`;return}this.attachmentDelivery=t,cv(this.attachmentDelivery)}removeAttachment(e){this.attachments=this.attachments.filter(t=>t.id!==e)}async handlePaste(e){let t=Pv(e.clipboardData);t.length!==0&&(e.preventDefault(),await this.addAttachmentFiles(t))}handleDragOver(e){e.dataTransfer!==null&&Fv(e.dataTransfer)&&e.preventDefault()}async handleDrop(e){let t=Pv(e.dataTransfer);t.length!==0&&(e.preventDefault(),await this.addAttachmentFiles(t))}async handleFileInput(e){if(!(e.target instanceof HTMLInputElement)||e.target.files===null)return;let t=Array.from(e.target.files);e.target.value=``,await this.addAttachmentFiles(t)}async addAttachmentFiles(e){this.attachmentError=void 0;let{attachments:t,error:n}=await Q_(e,Rv);t.length>0&&(this.attachments=[...this.attachments,...t.map(e=>({id:`attachment-${String(++this.attachmentSeq)}`,...e}))]),n!==void 0&&(this.attachmentError=n)}currentAttachments(){return this.attachments.map(e=>Iv(e))}effectiveAttachmentDelivery(){return tv(this.attachmentDelivery,this.attachments)}createEditor(){!this.editorHost||this.editor!==void 0||(this.editor=new p({parent:this.editorHost,state:e.create({doc:this.draft,extensions:[m(),ne(),t(),u.of(` `),r(a,{fallback:!0}),p.lineWrapping,p.contentAttributes.of(e=>Vv(e.state.sliceDoc(0,e.state.selection.main.head))),p.domEventHandlers({keyup:e=>this.handleEditorKeyUp(e),blur:()=>this.resetEditorModifierState()}),o(`Message pi... Use / for commands, @ for tracked files, @ space for all files`),this.editableCompartment.of(p.editable.of(!this.disabled)),this.readOnlyCompartment.of(e.readOnly.of(this.disabled)),p.updateListener.of(e=>{e.docChanged&&this.updateDraft(e.state.doc.toString())}),n.of([{any:(e,t)=>this.handleEditorKeyDown(t,e)},{key:`ArrowDown`,run:()=>this.moveCompletion(1)},{key:`ArrowUp`,run:()=>this.moveCompletion(-1)},{key:`Escape`,run:()=>this.closeCompletions()},{key:`Tab`,run:e=>this.handleEditorTab(e)},{key:`Shift-Tab`,run:e=>l.shift?.(e)??!1},{key:`Backspace`,run:e=>ee(e)},...c,...d])]})}))}syncEditorDoc(){let e=this.editor;if(!e)return;let t=e.state.doc.toString();t!==this.draft&&e.dispatch({changes:{from:0,to:t.length,insert:this.draft},selection:i.cursor(this.draft.length)})}updateEditorDisabledState(){this.editor?.dispatch({effects:[this.editableCompartment.reconfigure(p.editable.of(!this.disabled)),this.readOnlyCompartment.reconfigure(e.readOnly.of(this.disabled))]})}updateDraft(e){this.draft=e;let t=jv(this.machineId,this.sessionId);t!==void 0&&Go(t,this.draft);let n=$s(this.draft);tc(n,this.currentInputMode)||(this.currentInputMode=n),this.refreshCompletions()}async refreshCompletions(){let e=this.currentTrigger(),t=++this.requestVersion;if(this.selectedIndex=0,e===void 0){this.completions=[];return}if(e.kind===`command`&&this.sessionId!==void 0&&this.sessionId!==``&&this.cwd!==void 0&&this.cwd!==``){let n=await F.commands({id:this.sessionId,cwd:this.cwd},this.machineId).catch(Mv);if(t!==this.requestVersion)return;this.completions=n.filter(t=>t.name.toLowerCase().includes(e.query.toLowerCase())).slice(0,12).map(t=>({kind:`command`,replaceFrom:e.from,replaceTo:e.to,insertText:`/${t.name}`,detail:t.source,...t.description===void 0?{}:{description:t.description}}))}else if(e.kind===`file`&&this.cwd!==void 0&&this.cwd!==``){let n=await F.files(this.cwd,e.query,{scope:e.fileScope,machineId:this.machineId,projectId:this.projectId,workspaceId:this.workspaceId,workspaceScoped:this.workspaceScopedFileSuggestions}).catch(Nv);if(t!==this.requestVersion)return;this.completions=n.slice(0,12).map(t=>{let n=Js(t.path,e.quoted===!0,t.path.endsWith(`/`)?e.allPrefix:void 0);return{kind:`file`,replaceFrom:e.from,replaceTo:e.to,insertText:n,detail:t.kind,...t.path.endsWith(`/`)&&n.endsWith(`"`)?{cursorOffset:n.length-1}:{}}})}}currentTrigger(){return qs(this.draft,this.editor?.state.selection.main.head??this.draft.length)}moveCompletion(e){return this.completions.length?(this.selectedIndex=(this.selectedIndex+e+this.completions.length)%this.completions.length,!0):!1}closeCompletions(){return this.completions.length?(this.completions=[],!0):!1}handleEditorKeyDown(e,t){if(e.key===`Shift`)return this.explicitShiftKeyActive=!0,!1;if(e.key!==`Enter`)return this.explicitShiftKeyActive=!1,!1;if(e.defaultPrevented||e.isComposing||t.composing)return!1;let n=gv(e.shiftKey,this.explicitShiftKeyActive,this.mobilePromptEnterMedia);return this.explicitShiftKeyActive=!1,this.handleEditorEnter(t,n)}handleEditorKeyUp(e){return e.key===`Shift`&&(this.explicitShiftKeyActive=!1),!1}resetEditorModifierState(){return this.explicitShiftKeyActive=!1,!1}handleEditorEnter(e,t){if(!t&&this.completions.length){let e=this.completions[this.selectedIndex];return e!==void 0&&this.pick(e),!0}return _v(t,this.mobilePromptEnterMedia,pv())?(this.send(this.canSteer||this.isCompacting?`followUp`:void 0),!0):te(e)||f(e)}handleEditorTab(e){if(this.completions.length){let e=this.completions[this.selectedIndex];return e!==void 0&&this.pick(e),!0}return this.currentTrigger()?.kind===`file`?(this.refreshCompletions(),!0):l.run?.(e)??!1}pick(e){let t=this.editor;if(!t)return;let n=e.kind===`file`&&(e.insertText.endsWith(`/`)||e.cursorOffset!==void 0)?``:` `,r=e.replaceFrom+(e.cursorOffset??e.insertText.length)+n.length,a=e.insertText.endsWith(`"`)&&this.draft.slice(e.replaceTo).startsWith(`"`)?e.replaceTo+1:e.replaceTo;t.dispatch({changes:{from:e.replaceFrom,to:a,insert:`${e.insertText}${n}`},selection:i.cursor(r),scrollIntoView:!0}),this.completions=[]}send(e){if(this.disabled||this.sending)return;let t=this.draft.trim(),n=this.attachments;if(t===``&&n.length===0)return;let r=this.canSteer||this.isCompacting?e:void 0,i=n.length>0?this.currentAttachments():void 0,a=this.effectiveAttachmentDelivery();this.resetComposer(),this.onSend?.(t,r,i,i===void 0?void 0:a)}resetComposer(){this.draft=``,this.currentInputMode={kind:`normal`};let e=jv(this.machineId,this.sessionId);e!==void 0&&Ko(e),this.completions=[],this.attachments=[],this.attachmentError=void 0,this.syncEditorDoc()}static{this.styles=id}};R([b({type:Boolean})],J.prototype,`disabled`,void 0),R([b()],J.prototype,`sessionId`,void 0),R([b()],J.prototype,`cwd`,void 0),R([b()],J.prototype,`machineId`,void 0),R([b()],J.prototype,`projectId`,void 0),R([b()],J.prototype,`workspaceId`,void 0),R([b({type:Boolean})],J.prototype,`workspaceScopedFileSuggestions`,void 0),R([b({type:Boolean})],J.prototype,`canSteer`,void 0),R([b({type:Boolean})],J.prototype,`isCompacting`,void 0),R([b({type:Boolean})],J.prototype,`canStop`,void 0),R([b({attribute:!1})],J.prototype,`status`,void 0),R([b({type:Boolean})],J.prototype,`sending`,void 0),R([b({attribute:!1})],J.prototype,`onSend`,void 0),R([b({attribute:!1})],J.prototype,`onStop`,void 0),R([b({attribute:!1})],J.prototype,`onSelectModel`,void 0),R([b({attribute:!1})],J.prototype,`onSelectThinking`,void 0),R([b({attribute:!1})],J.prototype,`availableThinkingLevels`,void 0),R([S(`.markdown-editor`)],J.prototype,`editorHost`,void 0),R([S(`.attachment-input`)],J.prototype,`attachmentInput`,void 0),R([x()],J.prototype,`currentInputMode`,void 0),R([x()],J.prototype,`completions`,void 0),R([x()],J.prototype,`selectedIndex`,void 0),R([x()],J.prototype,`attachments`,void 0),R([x()],J.prototype,`attachmentDelivery`,void 0),R([x()],J.prototype,`attachmentError`,void 0),J=R([y(`prompt-editor`)],J);function Av(e,t){return e===t?!0:e===void 0||t===void 0?!1:e.model?.id===t.model?.id&&e.model?.provider===t.model?.provider&&e.thinkingLevel===t.thinkingLevel}function jv(e,t){if(!(typeof e!=`string`||e===``)&&!(typeof t!=`string`||t===``))return da(e,t)}function Mv(){return[]}function Nv(){return[]}function Pv(e){return e===null?[]:Array.from(e.files)}function Fv(e){let t=Array.from(e.items);return t.length>0?t.some(e=>e.kind===`file`):Array.from(e.types).includes(`Files`)}function Iv(e){return e.kind===`image`?{kind:`image`,mimeType:e.mimeType,data:e.data,name:e.name}:{kind:`file`,mimeType:e.mimeType,data:e.data,name:e.name}}function Lv(e){let t=e.trim(),n=t.lastIndexOf(`.`);return n>=0&&n<t.length-1?t.slice(n+1,n+5).toUpperCase():`FILE`}function Rv(e){return new Promise((t,n)=>{let r=new FileReader;r.onerror=()=>{n(r.error??Error(`Failed to read file`))},r.onload=()=>{let e=r.result;if(typeof e!=`string`){n(Error(`Unexpected file reader result`));return}let i=e.indexOf(`,`);t(i===-1?e:e.slice(i+1))},r.readAsDataURL(e)})}var zv={spellcheck:`true`,autocorrect:`on`,autocapitalize:`sentences`,writingsuggestions:`true`,dir:`auto`},Bv={spellcheck:`false`,autocorrect:`off`,autocapitalize:`off`,writingsuggestions:`false`,dir:`auto`};function Vv(e){return $s(e).kind===`normal`?zv:Bv}function Hv(e){return Number.isFinite(e)?e<1e3?Math.round(e).toString():e<1e4?`${(e/1e3).toFixed(1)}k`:e<1e6?`${String(Math.round(e/1e3))}k`:e<1e7?`${(e/1e6).toFixed(1)}M`:`${String(Math.round(e/1e6))}M`:`0`}function Uv(e){return!Number.isFinite(e)||e===0?`$0`:e<.01?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`}var Wv=class extends v{render(){let e=this.status;if(e===void 0)return g`<div class="bar muted">No session status yet</div>`;let t=e.contextUsage,n=t?t.percent==null?`context ${Hv(t.contextWindow)}`:`${t.percent.toFixed(1)}%/${Hv(t.contextWindow)}`:`context unknown`,r=e.tokens;return g`
1518
- <div class="bar">
1519
- <span>↑${Hv(r.input)}</span>
1520
- <span>↓${Hv(r.output)}</span>
1521
- <span class="context">${n}</span>
1522
- <span>${Uv(e.cost)}</span>
1523
- ${e.pendingMessageCount>0?g`<span>${String(e.pendingMessageCount)} queued</span>`:null}
1524
- </div>
1525
- `}static{this.styles=ed}};R([b({attribute:!1})],Wv.prototype,`status`,void 0),Wv=R([y(`status-bar`)],Wv);var Gv=class extends v{constructor(...e){super(...e),this.title=`Select`,this.searchable=!1,this.options=[],this.selectedIndex=0,this.query=``}render(){let e=this.filteredOptions();return g`
1526
- <div class="backdrop" @mousedown=${()=>this.onCancel?.()}>
1527
- <section @mousedown=${e=>{e.stopPropagation()}}>
1528
- <header>
1529
- <strong>${this.title}</strong>
1530
- <button @click=${()=>this.onCancel?.()}>×</button>
1531
- </header>
1532
- ${this.searchable?g`<input placeholder="Search" .value=${this.query} @input=${e=>{this.handleSearchInput(e)}} @keydown=${e=>{this.handleKeyDown(e)}}>`:null}
1533
- <div class="options" @keydown=${e=>{this.handleKeyDown(e)}} tabindex="0">
1534
- ${e.map((e,t)=>g`
1535
- <button class=${t===this.selectedIndex?`selected`:``} ${Ov(t===this.selectedIndex,e.value)} @click=${()=>this.onPick?.(e.value)}>
1536
- <span>${e.label}</span>
1537
- ${e.description!==void 0&&e.description!==``?g`<small>${e.description}</small>`:null}
1538
- </button>
1539
- `)}
1540
- ${e.length===0?g`<div class="empty">No matching options</div>`:null}
1541
- </div>
1542
- </section>
1543
- </div>
1544
- `}firstUpdated(){this.selectInitialValue(),this.renderRoot.querySelector(this.searchable?`input`:`.options`)?.focus()}selectInitialValue(){if(this.selectedValue===void 0)return;let e=this.filteredOptions().findIndex(e=>e.value===this.selectedValue);e>=0&&(this.selectedIndex=e)}handleSearchInput(e){e.target instanceof HTMLInputElement&&(this.query=e.target.value,this.selectedIndex=0)}filteredOptions(){let e=this.query.trim().toLowerCase();return e===``?this.options:this.options.filter(t=>`${t.label} ${t.description??``} ${t.value}`.toLowerCase().includes(e))}handleKeyDown(e){let t=this.filteredOptions();if(e.key===`Escape`)e.preventDefault(),this.onCancel?.();else if(e.key===`ArrowDown`)e.preventDefault(),t.length>0&&(this.selectedIndex=(this.selectedIndex+1)%t.length);else if(e.key===`ArrowUp`)e.preventDefault(),t.length>0&&(this.selectedIndex=(this.selectedIndex-1+t.length)%t.length);else if(e.key===`Enter`){e.preventDefault();let n=t[this.selectedIndex];n&&this.onPick?.(n.value)}}static{this.styles=nd}};R([b()],Gv.prototype,`title`,void 0),R([b({type:Boolean})],Gv.prototype,`searchable`,void 0),R([b({attribute:!1})],Gv.prototype,`options`,void 0),R([b({attribute:!1})],Gv.prototype,`selectedValue`,void 0),R([b({attribute:!1})],Gv.prototype,`onPick`,void 0),R([b({attribute:!1})],Gv.prototype,`onCancel`,void 0),R([x()],Gv.prototype,`selectedIndex`,void 0),R([x()],Gv.prototype,`query`,void 0),Gv=R([y(`command-picker`)],Gv);var Kv=class extends v{constructor(...e){super(...e),this.actions=[],this.queryText=``,this.selectedIndex=0}render(){let e=this.filteredActions();return g`
1545
- <div class="backdrop" @mousedown=${()=>this.onCancel?.()}>
1546
- <section @mousedown=${e=>{e.stopPropagation()}} @keydown=${e=>{this.handleKeyDown(e)}}>
1547
- <header>
1548
- <input
1549
- .value=${this.queryText}
1550
- placeholder="Search actions..."
1551
- @input=${e=>{e.target instanceof HTMLInputElement&&(this.queryText=e.target.value,this.selectedIndex=0)}}
1552
- >
1553
- <button title="Close" @click=${()=>this.onCancel?.()}>×</button>
1554
- </header>
1555
- <div class="options">
1556
- ${e.length===0?g`<div class="empty">No actions found.</div>`:e.map((e,t)=>g`
1557
- <button class=${`${t===this.selectedIndex?`selected`:``} ${e.enabled===!1?`disabled`:``}`} ?disabled=${e.enabled===!1} title=${e.disabledReason??e.title} ${Ov(t===this.selectedIndex,e.id)} @click=${()=>{this.run(e)}}>
1558
- <span class="main">
1559
- <strong>${e.title}</strong>
1560
- ${e.description!==void 0&&e.description!==``?g`<small>${e.description}</small>`:null}
1561
- ${e.enabled===!1&&e.disabledReason!==void 0?g`<small class="disabled-reason">${e.disabledReason}</small>`:null}
1562
- </span>
1563
- ${e.shortcut===void 0?null:g`<kbd>${Nl(e.shortcut)}</kbd>`}
1564
- ${e.group!==void 0&&e.group!==``?g`<small class="group">${e.group}</small>`:null}
1565
- </button>
1566
- `)}
1567
- </div>
1568
- </section>
1569
- </div>
1570
- `}firstUpdated(){this.input?.focus()}updated(e){if(!e.has(`actions`)&&!e.has(`queryText`))return;let t=Math.max(0,this.filteredActions().length-1);this.selectedIndex>t&&(this.selectedIndex=t)}filteredActions(){return qv(this.actions,this.queryText)}handleKeyDown(e){let t=this.filteredActions();if(e.key===`Escape`)e.preventDefault(),this.onCancel?.();else if(e.key===`ArrowDown`)e.preventDefault(),t.length>0&&(this.selectedIndex=(this.selectedIndex+1)%t.length);else if(e.key===`ArrowUp`)e.preventDefault(),t.length>0&&(this.selectedIndex=(this.selectedIndex-1+t.length)%t.length);else if(e.key===`Enter`){e.preventDefault();let n=t[this.selectedIndex];n!==void 0&&this.run(n)}}run(e){e.enabled!==!1&&this.onRun?.(e)}static{this.styles=rd}};R([b({attribute:!1})],Kv.prototype,`actions`,void 0),R([b({attribute:!1})],Kv.prototype,`onRun`,void 0),R([b({attribute:!1})],Kv.prototype,`onCancel`,void 0),R([S(`input`)],Kv.prototype,`input`,void 0),R([x()],Kv.prototype,`queryText`,void 0),R([x()],Kv.prototype,`selectedIndex`,void 0),Kv=R([y(`action-palette`)],Kv);function qv(e,t){let n=t.trim().toLowerCase();return e.filter(e=>e.enabled!==!1||e.disabledReason!==void 0).filter(e=>n===``||[e.title,e.description??``,e.disabledReason??``,e.group??``,e.shortcut??``].join(` `).toLowerCase().includes(n))}var Jv=class extends v{render(){let e=this.state;return e===void 0?null:g`
1571
- <div class="backdrop" @mousedown=${()=>{this.cancel()}}>
1572
- <section @mousedown=${e=>{e.stopPropagation()}} @keydown=${e=>{this.handleKeyDown(e)}}>
1573
- <header>
1574
- <strong>${this.dialogTitle(e)}</strong>
1575
- <button title="Close" @click=${()=>{this.cancel()}}>×</button>
1576
- </header>
1577
- ${this.renderBody(e)}
1578
- </section>
1579
- </div>
1580
- `}updated(){this.focusInputIfNeeded()}dialogTitle(e){switch(e.step){case`method`:return`Configure provider authentication`;case`providers`:return e.authType===void 0?`Select provider authentication`:e.authType===`oauth`?`Select subscription provider`:`Select credential provider`;case`apiKey`:return`API key for ${e.provider.name}`;case`oauth`:return`Login to ${e.flow.providerName}`;case`logout`:return`Remove stored provider authentication`}}renderBody(e){switch(e.step){case`method`:return g`
1581
- <div class="options">
1582
- <button @click=${()=>{this.onChooseMethod?.(`oauth`)}}><span>Use a subscription</span><small>ChatGPT Plus/Pro, Claude Pro/Max, or GitHub Copilot</small></button>
1583
- <button @click=${()=>{this.onChooseMethod?.(`api_key`)}}><span>Use provider credentials</span><small>Configure an API key or provider-specific credentials in the active Pi-compatible profile's auth.json</small></button>
1584
- </div>
1585
- `;case`providers`:return g`<div class="options">${e.providers.length===0?g`<div class="empty">No providers available.</div>`:e.providers.map(e=>this.renderProviderButton(e))}</div>`;case`apiKey`:return g`
1586
- <div class="form">
1587
- <p>Enter the API key for <strong>${e.provider.name}</strong>. It will be stored in the active Pi-compatible profile's <code>auth.json</code>.</p>
1588
- <input type="password" autocomplete="off" placeholder="API key" .value=${e.value} @input=${e=>{e.target instanceof HTMLInputElement&&this.onApiKeyInput?.(e.target.value)}}>
1589
- ${e.error!==void 0&&e.error!==``?g`<div class="error-text">${e.error}</div>`:null}
1590
- <div class="actions"><button @click=${()=>{this.cancel()}}>Cancel</button><button class="primary" ?disabled=${e.saving===!0} @click=${()=>{this.onSaveApiKey?.()}}>${e.saving===!0?`Saving…`:`Save API key`}</button></div>
1591
- </div>
1592
- `;case`oauth`:return this.renderOAuth(e);case`logout`:return g`<div class="options">${e.providers.length===0?g`<div class="empty">No stored credentials. Environment variables and models.json settings are unchanged.</div>`:e.providers.map(e=>g`
1593
- <button @click=${()=>{this.onLogoutProvider?.(e.id)}}><span>${e.name}</span><small>${e.id} · ${Xv(e.authType)}</small></button>
1594
- `)}</div>`}}renderProviderButton(e){return g`
1595
- <button @click=${()=>{this.onSelectProvider?.(e.id,e.authType)}}>
1596
- <span>${e.name}${e.status.source===void 0?null:g` <em>${Qv(e)}</em>`}</span>
1597
- <small>${e.id} · ${Xv(e.authType)}</small>
1598
- </button>
1599
- `}renderOAuth(e){let t=e.flow,n=t.prompt,r=t.select,i=Yv(n?.promptType);return g`
1600
- <div class="form">
1601
- ${t.auth===void 0?g`<p>Starting login flow…</p>`:g`
1602
- <p>Open this authorization link:</p>
1603
- <p><a href=${t.auth.url} target="_blank" rel="noreferrer">${t.auth.url}</a></p>
1604
- ${t.auth.deviceCode===void 0?t.auth.instructions===void 0?null:g`<p class="warning">${t.auth.instructions}</p>`:g`
1605
- <p class="warning">Enter code: <code>${t.auth.deviceCode.userCode}</code></p>
1606
- `}
1607
- `}
1608
- ${t.progress.length>0?g`<ul class="progress">${t.progress.map(e=>g`<li>${e}</li>`)}</ul>`:null}
1609
- ${t.info?.map(e=>e.links===void 0||e.links.length===0?null:g`
1610
- <div class="info-links" aria-label="Related information">
1611
- ${e.links.map(t=>g`<a href=${t.url} target="_blank" rel="noreferrer" title=${e.message}>${t.label??t.url}</a>`)}
1612
- </div>
1613
- `)??null}
1614
- ${n===void 0?null:g`
1615
- <label>${n.message}</label>
1616
- <input type=${i} autocomplete=${i===`password`?`off`:`on`} .value=${e.inputValue??``} placeholder=${n.placeholder??``} @input=${e=>{e.target instanceof HTMLInputElement&&this.onOAuthInput?.(e.target.value)}}>
1617
- <div class="actions"><button @click=${()=>{this.onOAuthCancel?.()}}>Cancel</button><button class="primary" ?disabled=${e.responding===!0} @click=${()=>{this.onOAuthRespond?.()}}>Submit</button></div>
1618
- `}
1619
- ${r===void 0?null:g`
1620
- <p>${r.message}</p>
1621
- <div class="inline-options">${r.options.map(e=>g`
1622
- <button @click=${()=>{this.onOAuthRespond?.(e.value)}}>
1623
- <span>${e.label}</span>
1624
- ${e.description===void 0?null:g`<small>${e.description}</small>`}
1625
- </button>
1626
- `)}</div>
1627
- `}
1628
- ${e.error!==void 0&&e.error!==``?g`<div class="error-text">${e.error}</div>`:null}
1629
- ${t.status===`error`||t.status===`cancelled`?g`<div class="error-text">${t.error??t.status}</div><div class="actions"><button @click=${()=>{this.cancel()}}>Close</button></div>`:null}
1630
- ${n===void 0&&r===void 0&&t.status===`running`?g`<div class="actions"><button @click=${()=>{this.onOAuthCancel?.()}}>Cancel</button></div>`:null}
1631
- </div>
1632
- `}focusInputIfNeeded(){let e=Zv(this.state);if(e===void 0){this.lastFocusedInputKey=void 0;return}e!==this.lastFocusedInputKey&&(this.lastFocusedInputKey=e,this.input?.focus())}handleKeyDown(e){if(e.key===`Escape`){e.preventDefault(),this.cancel();return}if(e.key!==`Enter`)return;let t=this.state;t?.step===`apiKey`?(e.preventDefault(),this.onSaveApiKey?.()):t?.step===`oauth`&&t.flow.prompt!==void 0&&(e.preventDefault(),this.onOAuthRespond?.())}cancel(){this.state?.step===`oauth`?this.onOAuthCancel?.():this.onCancel?.()}static{this.styles=[nd,h`
1633
- .form { display: grid; gap: 12px; padding: 14px; overflow: auto; }
1634
- .form p { margin: 0; color: var(--pi-text-secondary); overflow-wrap: anywhere; }
1635
- .form a { color: var(--pi-accent); overflow-wrap: anywhere; }
1636
- .form code { border: 1px solid var(--pi-border); border-radius: 4px; background: var(--pi-surface); padding: 1px 4px; }
1637
- label { color: var(--pi-muted); }
1638
- .actions { display: flex; justify-content: flex-end; gap: 8px; }
1639
- .actions button, .inline-options button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; }
1640
- .actions button.primary { border-color: var(--pi-success-border); background: var(--pi-success-surface); color: var(--pi-success); }
1641
- .actions button:disabled { opacity: .6; cursor: wait; }
1642
- .warning { color: var(--pi-warning); }
1643
- .error-text { color: var(--pi-danger); }
1644
- .progress { margin: 0; padding-left: 18px; color: var(--pi-muted); }
1645
- .info-links { display: flex; flex-wrap: wrap; gap: 8px 12px; }
1646
- .inline-options { display: grid; gap: 8px; }
1647
- .inline-options button { display: grid; gap: 2px; text-align: left; }
1648
- .inline-options small { color: var(--pi-muted); }
1649
- em { color: var(--pi-success); font-style: normal; font-size: 12px; }
1650
- `]}};R([b({attribute:!1})],Jv.prototype,`state`,void 0),R([b({attribute:!1})],Jv.prototype,`onChooseMethod`,void 0),R([b({attribute:!1})],Jv.prototype,`onSelectProvider`,void 0),R([b({attribute:!1})],Jv.prototype,`onApiKeyInput`,void 0),R([b({attribute:!1})],Jv.prototype,`onSaveApiKey`,void 0),R([b({attribute:!1})],Jv.prototype,`onLogoutProvider`,void 0),R([b({attribute:!1})],Jv.prototype,`onOAuthInput`,void 0),R([b({attribute:!1})],Jv.prototype,`onOAuthRespond`,void 0),R([b({attribute:!1})],Jv.prototype,`onOAuthCancel`,void 0),R([b({attribute:!1})],Jv.prototype,`onCancel`,void 0),R([S(`input`)],Jv.prototype,`input`,void 0),Jv=R([y(`auth-dialog`)],Jv);function Yv(e){return e===`secret`?`password`:`text`}function Xv(e){return e===`oauth`?`subscription`:`credentials`}function Zv(e){if(e?.step===`apiKey`)return`api-key:${e.provider.authType}:${e.provider.id}`;if(e?.step===`oauth`&&e.flow.prompt!==void 0)return`oauth:${e.flow.flowId}:${e.flow.prompt.requestId}`}function Qv(e){if(e.status.source===void 0)return``;switch(e.status.source){case`stored`:return`✓ configured`;case`environment`:return`✓ env${e.status.label===void 0?``:`: ${e.status.label}`}`;case`runtime`:return`✓ runtime`;case`fallback`:return`✓ custom key`;case`models_json_key`:return`✓ models.json key`;case`models_json_command`:return`✓ models.json command`;default:return``}}var $v=class extends v{constructor(...e){super(...e),this.machineId=`local`,this.path=``,this.createMissing=!0,this.suggestions=[],this.selected=0,this.loading=!1,this.requestId=0}connectedCallback(){super.connectedCallback(),this.loadSuggestions()}firstUpdated(){this.pathInput?.focus()}async loadSuggestions(){let e=++this.requestId;this.loading=!0;try{let t=await F.projectDirectories(this.path,this.machineId);if(e!==this.requestId)return;this.suggestions=t,this.selected=Math.min(this.selected,Math.max(0,t.length-1))}catch{e===this.requestId&&(this.suggestions=[])}finally{e===this.requestId&&(this.loading=!1)}}setPath(e){this.path=e,this.selected=0,this.loadSuggestions()}pick(e){this.setPath(e.path)}submit(){this.path.trim()!==``&&this.onSubmit?.(this.path,this.createMissing)}onPathInput(e){e.target instanceof HTMLInputElement&&this.setPath(e.target.value)}onCreateMissingChange(e){e.target instanceof HTMLInputElement&&(this.createMissing=e.target.checked)}onKeyDown(e){if(e.key===`Escape`)e.preventDefault(),this.onCancel?.();else if(e.key===`Enter`)e.preventDefault(),this.submit();else if(e.key===`ArrowDown`)e.preventDefault(),this.selected=Math.min(this.selected+1,Math.max(0,this.suggestions.length-1));else if(e.key===`ArrowUp`)e.preventDefault(),this.selected=Math.max(0,this.selected-1);else if(e.key===`Tab`){let t=this.suggestions[this.selected];if(t===void 0)return;e.preventDefault(),this.pick(t)}}render(){return g`
1651
- <div class="backdrop" @click=${()=>this.onCancel?.()}>
1652
- <section @click=${e=>{e.stopPropagation()}}>
1653
- <header>
1654
- <strong>Add project</strong>
1655
- <button @click=${()=>{this.onCancel?.()}} aria-label="Close">×</button>
1656
- </header>
1657
- <div class="body">
1658
- <label>
1659
- Project folder
1660
- <input .value=${this.path} @input=${e=>{this.onPathInput(e)}} @keydown=${e=>{this.onKeyDown(e)}} placeholder="/path/to/project or ~/code/project" autofocus />
1661
- </label>
1662
- <div class="suggestions">
1663
- ${this.loading?g`<div class="hint">Loading folders…</div>`:null}
1664
- ${this.suggestions.map((e,t)=>g`
1665
- <button class=${t===this.selected?`selected`:``} @click=${()=>{this.pick(e)}}>
1666
- ${e.path}
1667
- </button>
1668
- `)}
1669
- ${!this.loading&&this.suggestions.length===0?g`<div class="hint">No matching folders. Enter a new path to create it.</div>`:null}
1670
- </div>
1671
- <label class="check">
1672
- <input type="checkbox" .checked=${this.createMissing} @change=${e=>{this.onCreateMissingChange(e)}} />
1673
- Create the folder if it does not exist
1674
- </label>
1675
- </div>
1676
- <footer>
1677
- <button @click=${()=>{this.onCancel?.()}}>Cancel</button>
1678
- <button class="primary" ?disabled=${this.path.trim()===``} @click=${()=>{this.submit()}}>Add project</button>
1679
- </footer>
1680
- </section>
1681
- </div>
1682
- `}static{this.styles=h`
1683
- :host { position: fixed; inset: 0; z-index: 30; color: var(--pi-text); font: 14px system-ui, sans-serif; }
1684
- .backdrop { display: grid; place-items: start center; width: 100%; height: 100%; padding-top: min(12vh, 90px); box-sizing: border-box; background: var(--pi-overlay); }
1685
- section { width: min(720px, calc(100vw - 40px)); max-height: min(700px, calc(100vh - 40px)); display: flex; flex-direction: column; border: 1px solid var(--pi-border); border-radius: 12px; background: var(--pi-bg); box-shadow: 0 20px 60px var(--pi-shadow-strong); overflow: hidden; }
1686
- header, footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px; border-bottom: 1px solid var(--pi-border); }
1687
- footer { border-top: 1px solid var(--pi-border); border-bottom: 0; justify-content: end; }
1688
- .body { display: grid; gap: 12px; padding: 12px; min-height: 0; }
1689
- label { display: grid; gap: 6px; color: var(--pi-muted); }
1690
- input[type="text"], input:not([type]) { box-sizing: border-box; width: 100%; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); color: var(--pi-text); padding: 9px; font: var(--pi-control-font-size, 16px) var(--pi-control-monospace-font-family, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); }
1691
- .check { display: flex; grid-template-columns: auto 1fr; align-items: center; color: var(--pi-text); }
1692
- .suggestions { min-height: 90px; max-height: 320px; overflow: auto; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); }
1693
- .suggestions button { display: block; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; border: 0; border-bottom: 1px solid var(--pi-border); border-radius: 0; background: transparent; color: var(--pi-text); padding: 8px 10px; text-align: left; font: 13px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
1694
- .suggestions button.selected, .suggestions button:hover { background: var(--pi-selection-bg); }
1695
- .hint { padding: 12px; color: var(--pi-muted); }
1696
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
1697
- header button { border: 0; background: transparent; color: var(--pi-muted); font-size: 22px; padding: 0 8px; }
1698
- .primary { border-color: var(--pi-success-border); background: var(--pi-success-border); }
1699
- button:disabled { opacity: .5; cursor: not-allowed; }
1700
- `}};R([b({attribute:!1})],$v.prototype,`onSubmit`,void 0),R([b({attribute:!1})],$v.prototype,`onCancel`,void 0),R([b()],$v.prototype,`machineId`,void 0),R([x()],$v.prototype,`path`,void 0),R([x()],$v.prototype,`createMissing`,void 0),R([x()],$v.prototype,`suggestions`,void 0),R([x()],$v.prototype,`selected`,void 0),R([x()],$v.prototype,`loading`,void 0),R([S(`input`)],$v.prototype,`pathInput`,void 0),$v=R([y(`project-dialog`)],$v);var ey=class extends v{constructor(...e){super(...e),this.error=``,this.url=``,this.name=``,this.token=``,this.submitting=!1,this.nameEdited=!1,this.previousSuggestedName=``}firstUpdated(){this.urlInput?.focus()}handleUrlInput(e){if(!(e.target instanceof HTMLInputElement))return;let t=e.target.value,n=ty(t);(!this.nameEdited||this.name.trim()===``||this.name===this.previousSuggestedName)&&(this.name=n),this.previousSuggestedName=n,this.url=t}handleNameInput(e){e.target instanceof HTMLInputElement&&(this.nameEdited=!0,this.name=e.target.value)}handleTokenInput(e){e.target instanceof HTMLInputElement&&(this.token=e.target.value)}handleKeyDown(e){if(e.key===`Escape`){e.preventDefault(),this.onCancel?.();return}e.key===`Enter`&&e.target instanceof HTMLInputElement&&e.target.name===`baseUrl`&&ny(this.url)===void 0&&(e.preventDefault(),this.updateComplete.then(()=>{this.nameInput?.focus(),this.nameInput?.select()}))}handleSubmit(e){e.preventDefault(),this.submit()}async submit(){let e=this.validInput();if(!(e===void 0||this.submitting)){this.submitting=!0;try{await this.onSubmit?.(e)}finally{this.isConnected&&(this.submitting=!1)}}}validInput(){let e=this.url.trim(),t=this.name.trim();if(e===``||t===``||ny(e)!==void 0)return;let n=this.token.trim();return{name:t,baseUrl:e,...n===``?{}:{token:n}}}render(){let e=this.url.trim()!==``,t=e?ny(this.url):void 0,n=this.validInput()!==void 0&&!this.submitting;return g`
1701
- <div class="backdrop" @click=${()=>this.onCancel?.()}>
1702
- <section @click=${e=>{e.stopPropagation()}}>
1703
- <form @submit=${e=>{this.handleSubmit(e)}} @keydown=${e=>{this.handleKeyDown(e)}}>
1704
- <header>
1705
- <strong>Add machine</strong>
1706
- <button type="button" @click=${()=>{this.onCancel?.()}} aria-label="Close">×</button>
1707
- </header>
1708
- <div class="body">
1709
- ${this.error===``?null:g`<div class="dialog-error" role="alert">${this.error}</div>`}
1710
- <label>
1711
- Remote PI WEB URL
1712
- <input name="baseUrl" type="url" .value=${this.url} @input=${e=>{this.handleUrlInput(e)}} placeholder="http://dev-box.local:8504" autocomplete="url" inputmode="url" autofocus />
1713
- </label>
1714
- <small class=${t===void 0?`hint`:`field-error`}>${t??`Enter the reachable base URL first, including http:// or https://.`}</small>
1715
- ${e?g`
1716
- <label>
1717
- Machine name
1718
- <input name="name" type="text" .value=${this.name} @input=${e=>{this.handleNameInput(e)}} placeholder=${this.previousSuggestedName||`Dev Box`} autocomplete="off" />
1719
- </label>
1720
- <small class="hint">Suggested from the URL. Edit it to use a friendlier sidebar label.</small>
1721
- <label>
1722
- Bearer token <span class="optional">optional</span>
1723
- <input name="token" type="password" .value=${this.token} @input=${e=>{this.handleTokenInput(e)}} placeholder="Leave blank if the remote machine does not require one" autocomplete="off" />
1724
- </label>
1725
- <small class="hint">Paste only the token value; PI WEB sends it as an Authorization: Bearer header.</small>
1726
- `:g`<p class="hint intro">After you enter a URL, PI WEB will suggest a machine name and let you add an optional bearer token.</p>`}
1727
- </div>
1728
- <footer>
1729
- <button type="button" @click=${()=>{this.onCancel?.()}}>Cancel</button>
1730
- <button class="primary" type="submit" ?disabled=${!n}>${this.submitting?`Adding…`:`Add machine`}</button>
1731
- </footer>
1732
- </form>
1733
- </section>
1734
- </div>
1735
- `}static{this.styles=h`
1736
- :host { position: fixed; inset: 0; z-index: 30; color: var(--pi-text); font: 14px system-ui, sans-serif; }
1737
- .backdrop { display: grid; place-items: start center; width: 100%; height: 100%; padding-top: min(12vh, 90px); box-sizing: border-box; background: var(--pi-overlay); }
1738
- section { width: min(560px, calc(100vw - 40px)); max-height: min(640px, calc(100vh - 40px)); border: 1px solid var(--pi-border); border-radius: 12px; background: var(--pi-bg); box-shadow: 0 20px 60px var(--pi-shadow-strong); overflow: hidden; }
1739
- form { display: flex; flex-direction: column; max-height: inherit; min-height: 0; }
1740
- header, footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px; border-bottom: 1px solid var(--pi-border); }
1741
- footer { border-top: 1px solid var(--pi-border); border-bottom: 0; justify-content: end; }
1742
- .body { display: grid; gap: 8px; padding: 12px; min-height: 0; overflow: auto; }
1743
- label { display: grid; gap: 6px; color: var(--pi-muted); }
1744
- input { box-sizing: border-box; width: 100%; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); color: var(--pi-text); padding: 9px; font: var(--pi-control-font-size, 16px) var(--pi-control-monospace-font-family, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); }
1745
- input:focus-visible { outline: 2px solid var(--pi-accent); outline-offset: 1px; }
1746
- .hint { color: var(--pi-muted); }
1747
- .intro { margin: 4px 0 0; line-height: 1.4; }
1748
- .optional { color: var(--pi-muted); font-weight: 400; }
1749
- .field-error { color: var(--pi-danger); }
1750
- .dialog-error { border: 1px solid var(--pi-danger); border-radius: 8px; background: color-mix(in srgb, var(--pi-danger) 10%, transparent); color: var(--pi-danger); padding: 9px; line-height: 1.35; }
1751
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
1752
- header button { border: 0; background: transparent; color: var(--pi-muted); font-size: 22px; padding: 0 8px; }
1753
- .primary { border-color: var(--pi-success-border); background: var(--pi-success-border); }
1754
- button:disabled { opacity: .5; cursor: not-allowed; }
1755
- `}};R([b({attribute:!1})],ey.prototype,`onSubmit`,void 0),R([b({attribute:!1})],ey.prototype,`onCancel`,void 0),R([b()],ey.prototype,`error`,void 0),R([x()],ey.prototype,`url`,void 0),R([x()],ey.prototype,`name`,void 0),R([x()],ey.prototype,`token`,void 0),R([x()],ey.prototype,`submitting`,void 0),R([S(`input[name='baseUrl']`)],ey.prototype,`urlInput`,void 0),R([S(`input[name='name']`)],ey.prototype,`nameInput`,void 0),ey=R([y(`machine-dialog`)],ey);function ty(e){let t=e.trim();if(t===``)return``;let n=ry(t)??ry(`http://${t.replace(/^\/+/u,``)}`);return n!==void 0&&n.hostname!==``?n.hostname.replace(/^\[(.*)\]$/u,`$1`):iy(t)}function ny(e){let t=e.trim();if(t===``)return`Remote PI WEB URL is required.`;let n;try{n=new URL(t)}catch{return`Enter a valid URL including http:// or https://.`}if(n.protocol!==`http:`&&n.protocol!==`https:`)return`Use an http:// or https:// URL.`;if(n.username!==``||n.password!==``)return`Do not include credentials in the machine URL.`;if(n.search!==``||n.hash!==``)return`Do not include a query string or fragment.`}function ry(e){try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`?t:void 0}catch{return}}function iy(e){let t=e.replace(/^[a-z][a-z\d+.-]*:\/\//iu,``),n=t.slice(t.lastIndexOf(`@`)+1).split(/[/?#]/u)[0]??``;return n.startsWith(`[`)&&n.includes(`]`)?n.slice(1,n.indexOf(`]`)):n.replace(/:\d+$/u,``)}var ay={availability:`error`,error:`error`,success:`success`,security:`warning`,warning:`warning`,info:`info`};function oy(e){return e.tone??ay[e.type]}var sy=class extends v{constructor(...e){super(...e),this.heading=``,this.description=``,this.actionLabel=``,this.actionTitle=``,this.actionDisabled=!1,this.notices=[]}render(){return g`
1756
- <section class="panel" aria-label=${this.heading||`Settings panel`}>
1757
- <header class="section-heading">
1758
- <div class="heading-copy">
1759
- ${this.heading===``?_:g`<h2>${this.heading}</h2>`}
1760
- <div class="description"><slot name="description">${this.description}</slot></div>
1761
- </div>
1762
- <div class="heading-actions"><slot name="actions">${this.renderDefaultAction()}</slot></div>
1763
- </header>
1764
- ${this.renderNoticeStack()}
1765
- <div class="content"><slot></slot></div>
1766
- </section>
1767
- `}renderDefaultAction(){return this.actionLabel===``?_:g`
1768
- <button
1769
- class="secondary"
1770
- title=${this.actionTitle||this.actionLabel}
1771
- ?disabled=${this.actionDisabled}
1772
- @click=${()=>{this.onAction?.()}}
1773
- >${this.actionLabel}</button>
1774
- `}renderNoticeStack(){return this.notices.length===0?_:g`
1775
- <div class="notice-stack" aria-label="Settings notices">
1776
- ${this.notices.map(e=>this.renderNotice(e))}
1777
- </div>
1778
- `}renderNotice(e){let t=oy(e),n=e.role??cy(t),r=e.title;return g`
1779
- <article class=${`notice ${t}`} role=${n}>
1780
- ${r===void 0||r===``?_:g`<strong class="notice-title">${r}</strong>`}
1781
- <div class="notice-content">${e.content}</div>
1782
- </article>
1783
- `}static{this.styles=h`
1784
- :host { display: block; }
1785
- .panel { display: block; }
1786
- .section-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
1787
- .heading-copy { display: grid; gap: 6px; min-width: 0; }
1788
- .heading-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
1789
- h2 { margin: 0; font-size: 17px; line-height: 1.25; }
1790
- .description { color: var(--pi-muted); line-height: 1.45; }
1791
- .description ::slotted(*) { margin: 0; }
1792
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; font: inherit; cursor: pointer; }
1793
- button:disabled { opacity: .55; cursor: not-allowed; }
1794
- .secondary { flex: 0 0 auto; }
1795
- .notice-stack { display: grid; gap: 12px; margin-bottom: 14px; }
1796
- .notice { border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; line-height: 1.45; }
1797
- .notice.error { border-color: var(--pi-danger); color: var(--pi-danger); background: color-mix(in srgb, var(--pi-danger) 10%, var(--pi-surface)); }
1798
- .notice.success { border-color: var(--pi-success-border); color: var(--pi-success); background: var(--pi-success-surface); }
1799
- .notice.warning { border-color: var(--pi-warning-border); color: var(--pi-text); background: var(--pi-warning-surface); }
1800
- .notice.info { color: var(--pi-muted); }
1801
- .notice-title { display: block; margin-bottom: 4px; color: inherit; }
1802
- .notice-content { min-width: 0; }
1803
- code { border: 1px solid var(--pi-border-muted); border-radius: 5px; background: var(--pi-bg); padding: 1px 4px; color: var(--pi-text); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; overflow-wrap: anywhere; }
1804
- .content { display: grid; gap: 14px; min-width: 0; }
1805
- .content ::slotted(*) { min-width: 0; }
1806
-
1807
- @media (max-width: 760px) {
1808
- .section-heading { display: grid; gap: 12px; }
1809
- .heading-actions { justify-self: start; }
1810
- }
1811
- `}};R([b()],sy.prototype,`heading`,void 0),R([b({attribute:!1})],sy.prototype,`description`,void 0),R([b()],sy.prototype,`actionLabel`,void 0),R([b()],sy.prototype,`actionTitle`,void 0),R([b({type:Boolean})],sy.prototype,`actionDisabled`,void 0),R([b({attribute:!1})],sy.prototype,`notices`,void 0),R([b({attribute:!1})],sy.prototype,`onAction`,void 0),sy=R([y(`settings-panel-frame`)],sy);function cy(e){switch(e){case`error`:return`alert`;case`success`:return`status`;case`warning`:case`info`:return`note`}}function ly(){return{host:``,port:``,allowedHostsMode:`list`,allowedHostsText:``}}function uy(){return{allowedPathsText:``,uploadDefaultFolder:``}}function dy(){return{command:``,dir:``}}function fy(e){return{host:e.host??``,port:e.port===void 0?``:String(e.port),allowedHostsMode:e.allowedHosts===!0?`all`:`list`,allowedHostsText:Array.isArray(e.allowedHosts)?e.allowedHosts.join(`
1812
- `):``}}function py(e){return{allowedPathsText:e.pathAccess?.allowedPaths?.join(`
1813
- `)??``,uploadDefaultFolder:e.uploads?.defaultFolder??``}}function my(e){return{command:e.agent?.command??``,dir:e.agent?.dir??``}}function hy(e){let t=e.command.trim(),n=e.dir.trim();return{agent:{...t===``?{}:{command:t},...n===``?{}:{dir:n}}}}function gy(e,t){let n=hy(e).agent??{},r=t.agent??{};return n.command===r.command&&n.dir===r.dir}function _y(e,t={}){let n=yy(t),r=e.host.trim(),i=e.port.trim();if(r!==``&&(n.host=r),i!==``){let e=Number(i);if(!Number.isInteger(e)||e<1||e>65535)throw Error(`Port must be an integer from 1 to 65535.`);n.port=e}return n.allowedHosts=e.allowedHostsMode===`all`||by(e.allowedHostsText),n}function vy(e){let t=xy(e.allowedPathsText),n=Sy(e.uploadDefaultFolder);return{pathAccess:{allowedPaths:t},uploads:n===``?{}:{defaultFolder:n}}}function yy(e){return{...e.shortcuts===void 0?{}:{shortcuts:e.shortcuts},...e.plugins===void 0?{}:{plugins:e.plugins},...e.pathAccess===void 0?{}:{pathAccess:e.pathAccess},...e.uploads===void 0?{}:{uploads:e.uploads},...e.maxUploadBytes===void 0?{}:{maxUploadBytes:e.maxUploadBytes},...e.spawnSessions===void 0?{}:{spawnSessions:e.spawnSessions},...e.subsessions===void 0?{}:{subsessions:e.subsessions},...e.agent===void 0?{}:{agent:e.agent}}}function by(e){return e.split(/[\n,]/u).map(e=>e.trim()).filter(e=>e!==``)}function xy(e){let t=e.split(`
1814
- `).map(e=>e.trim()).filter(e=>e!==``),n=t.find(e=>!Cy(e));if(n!==void 0)throw Error(`Allowed external paths must be absolute paths or start with ~: ${n}`);return t}function Sy(e){let t=e.trim();if(t===``)return``;if(wy(t))throw Error(`Upload default folder must be workspace-relative.`);let n=t.split(/[\\/]+/u).filter(e=>e!==``&&e!==`.`);if(n.length===0)return``;if(n.some(e=>e===`..`))throw Error(`Upload default folder must not contain path traversal.`);return n.join(`/`)}function Cy(e){return e===`~`||e.startsWith(`~/`)||e.startsWith(`~\\`)||e.startsWith(`/`)||e.startsWith(`\\`)||/^[A-Za-z]:[\\/]/u.test(e)}function wy(e){let t=e.replace(/\\/g,`/`);return t.startsWith(`/`)||/^[A-Za-z]:\//u.test(t)}function Ty(e){return g`Gateway server fields edit this local gateway. File access and upload defaults edit ${e}.`}var Y=class extends v{constructor(...e){super(...e),this.loading=!1,this.machineLoading=!1,this.saving=!1,this.error=``,this.machineError=``,this.savedMessage=``,this.targetLabel=`selected machine`,this.gatewayDraft=ly(),this.machineDraft=uy(),this.gatewayLocalError=``,this.machineLocalError=``}willUpdate(e){e.has(`configResponse`)&&this.configResponse!==void 0&&(this.gatewayDraft=fy(this.configResponse.config),this.gatewayLocalError=``),e.has(`machineConfigResponse`)&&this.machineConfigResponse!==void 0&&(this.machineDraft=py(this.machineConfigResponse.config),this.machineLocalError=``)}render(){return g`
1815
- <settings-panel-frame
1816
- heading="General configuration"
1817
- .description=${Ty(this.targetLabel)}
1818
- actionLabel="Reload"
1819
- .actionDisabled=${this.loading||this.machineLoading}
1820
- .notices=${this.panelNotices()}
1821
- .onAction=${()=>{this.reloadAll()}}
1822
- >
1823
- <div class="settings-sections">
1824
- ${this.renderGatewayServerSettings()}
1825
- ${this.renderSelectedMachineAccessSettings()}
1826
- </div>
1827
- </settings-panel-frame>
1828
- `}renderGatewayServerSettings(){let e=this.configResponse;return g`
1829
- <section class="settings-card" aria-label="Gateway server settings">
1830
- <div class="card-heading">
1831
- <h3>Gateway server</h3>
1832
- <p>Host, port, and allowed hosts are saved in the gateway config. Address changes require the web service to restart before the running server binds to the new address.</p>
1833
- </div>
1834
- ${e===void 0&&this.loading?g`<div class="loading-card">Loading gateway configuration…</div>`:g`
1835
- <div class="config-path-card">
1836
- <span>Gateway config file</span>
1837
- <code>${e?.path??`Unknown`}</code>
1838
- <small>${e?.exists===!0?`Existing file`:`This file will be created on save`}</small>
1839
- </div>
1840
- <form class="config-form" @submit=${e=>{this.saveGatewayConfig(e)}}>
1841
- <label class="field">
1842
- <span class="field-heading">
1843
- <span>Host</span>
1844
- ${this.renderOverrideBadge(`host`)}
1845
- </span>
1846
- <input .value=${this.gatewayDraft.host} placeholder="127.0.0.1" autocomplete="off" spellcheck="false" @input=${e=>{this.updateGatewayDraft({host:Oy(e)})}}>
1847
- <small>Address the web server should bind to. Leave empty to use PI WEB's default.</small>
1848
- </label>
1849
-
1850
- <label class="field">
1851
- <span class="field-heading">
1852
- <span>Port</span>
1853
- ${this.renderOverrideBadge(`port`)}
1854
- </span>
1855
- <input .value=${this.gatewayDraft.port} inputmode="numeric" pattern="[0-9]*" placeholder="8504" autocomplete="off" @input=${e=>{this.updateGatewayDraft({port:Oy(e)})}}>
1856
- <small>TCP port from 1 to 65535. Leave empty to use PI WEB's default.</small>
1857
- </label>
1858
-
1859
- <div class="field">
1860
- <span class="field-heading">
1861
- <span>Allowed hosts</span>
1862
- ${this.renderOverrideBadge(`allowedHosts`)}
1863
- </span>
1864
- <select .value=${this.gatewayDraft.allowedHostsMode} @change=${e=>{this.updateGatewayDraft({allowedHostsMode:ky(e)===`all`?`all`:`list`})}}>
1865
- <option value="list">Only listed hosts</option>
1866
- <option value="all">Allow every host</option>
1867
- </select>
1868
- <textarea .value=${this.gatewayDraft.allowedHostsText} ?disabled=${this.gatewayDraft.allowedHostsMode===`all`} rows="4" placeholder="example.local&#10;192.168.1.20" spellcheck="false" @input=${e=>{this.updateGatewayDraft({allowedHostsText:Ay(e)})}}></textarea>
1869
- <small>Enter one host per line, or choose “Allow every host” to write <code>true</code>.</small>
1870
- </div>
1871
-
1872
- ${this.renderGatewayEffectiveConfig()}
1873
-
1874
- <footer class="form-actions">
1875
- <button class="primary" ?disabled=${this.loading||this.saving}>${this.saving?`Saving…`:`Save gateway server config`}</button>
1876
- </footer>
1877
- </form>
1878
- `}
1879
- </section>
1880
- `}renderSelectedMachineAccessSettings(){let e=this.machineConfigResponse;return g`
1881
- <section class="settings-card" aria-label="Selected machine file access and upload settings">
1882
- <div class="card-heading">
1883
- <h3>Selected machine file access and uploads</h3>
1884
- <p>External filesystem roots and upload defaults are saved on ${this.targetLabel}.</p>
1885
- </div>
1886
- ${this.renderMachineMessages()}
1887
- ${e===void 0?g`<div class="loading-card">${this.machineLoading?`Loading selected-machine file access config…`:`Selected-machine file access config is unavailable. Reload before saving file/upload settings.`}</div>`:g`
1888
- <div class="config-path-card">
1889
- <span>Selected machine config file</span>
1890
- <code>${e.path}</code>
1891
- <small>${e.exists?`Existing file`:`This file will be created on save`}</small>
1892
- </div>
1893
- <form class="config-form" @submit=${e=>{this.saveMachineAccessConfig(e)}}>
1894
- <label class="field">
1895
- <span class="field-heading">
1896
- <span>External filesystem roots</span>
1897
- </span>
1898
- <textarea .value=${this.machineDraft.allowedPathsText} rows="4" placeholder="~/SDKs&#10;/opt/reference" spellcheck="false" @input=${e=>{this.updateMachineDraft({allowedPathsText:Ay(e)})}}></textarea>
1899
- <small>Allowlist for absolute <code>@</code> completions and file explorer reads outside a workspace on ${this.targetLabel}. Enter one absolute path, Windows absolute path, or <code>~</code>-prefixed path per line. Leave empty to deny external paths by default.</small>
1900
- </label>
1901
-
1902
- <label class="field">
1903
- <span class="field-heading">
1904
- <span>Default upload folder</span>
1905
- </span>
1906
- <input .value=${this.machineDraft.uploadDefaultFolder} placeholder=${Ri} autocomplete="off" spellcheck="false" @input=${e=>{this.updateMachineDraft({uploadDefaultFolder:Oy(e)})}}>
1907
- <small>Workspace-relative folder for manual file uploads on ${this.targetLabel}. Leave empty to use PI WEB's default <code>${Ri}</code>.</small>
1908
- </label>
1909
-
1910
- ${this.renderMachineEffectiveConfig()}
1911
-
1912
- <footer class="form-actions">
1913
- <button class="primary" ?disabled=${this.machineLoading||this.saving}>${this.saving?`Saving…`:`Save file/upload config`}</button>
1914
- </footer>
1915
- </form>
1916
- `}
1917
- </section>
1918
- `}panelNotices(){let e=[],t=this.gatewayLocalError||this.error;return t!==``&&e.push({type:`error`,title:`Gateway server`,content:t}),this.savedMessage!==``&&e.push({type:`success`,content:this.savedMessage}),e}renderMachineMessages(){let e=this.machineLocalError||this.machineError;return e===``?null:g`<div class="message error-message">${e}</div>`}renderOverrideBadge(e){return this.configResponse?.envOverrides[e]===!0?g`<span class="override-badge">environment override</span>`:null}renderGatewayEffectiveConfig(){let e=this.configResponse?.effectiveConfig??{};return g`
1919
- <section class="effective-card" aria-label="Effective gateway configuration summary">
1920
- <h3>Effective gateway settings after environment overrides</h3>
1921
- <dl>
1922
- <div><dt>Host</dt><dd>${e.host??g`<span class="muted">127.0.0.1 default</span>`}</dd></div>
1923
- <div><dt>Port</dt><dd>${e.port??g`<span class="muted">8504 default</span>`}</dd></div>
1924
- <div><dt>Allowed hosts</dt><dd>${Ey(e.allowedHosts)}</dd></div>
1925
- </dl>
1926
- </section>
1927
- `}renderMachineEffectiveConfig(){let e=this.machineConfigResponse?.effectiveConfig??{};return g`
1928
- <section class="effective-card" aria-label="Effective selected machine file access and upload summary">
1929
- <h3>Effective selected-machine settings</h3>
1930
- <dl>
1931
- <div><dt>External roots</dt><dd>${Dy(e.pathAccess?.allowedPaths)}</dd></div>
1932
- <div><dt>Upload folder</dt><dd>${e.uploads?.defaultFolder??g`<span class="muted">${`.pi-web/uploads`} default</span>`}</dd></div>
1933
- </dl>
1934
- </section>
1935
- `}reloadAll(){this.onReload?.(),this.onReloadMachine?.()}async saveGatewayConfig(e){e.preventDefault(),this.gatewayLocalError=``;try{await this.onSave?.(_y(this.gatewayDraft,this.configResponse?.config??{}))}catch(e){this.gatewayLocalError=jy(e)}}async saveMachineAccessConfig(e){e.preventDefault(),this.machineLocalError=``;try{await this.onSaveMachineConfig?.(vy(this.machineDraft))}catch(e){this.machineLocalError=jy(e)}}updateGatewayDraft(e){this.gatewayDraft={...this.gatewayDraft,...e},this.gatewayLocalError=``}updateMachineDraft(e){this.machineDraft={...this.machineDraft,...e},this.machineLocalError=``}static{this.styles=h`
1936
- :host { display: block; }
1937
- .card-heading { display: grid; gap: 6px; min-width: 0; }
1938
- h3, p { margin: 0; }
1939
- h3 { font-size: 13px; line-height: 1.3; }
1940
- p { color: var(--pi-muted); line-height: 1.45; }
1941
- button, input, select, textarea { font: inherit; }
1942
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
1943
- button:disabled { opacity: .55; cursor: not-allowed; }
1944
- .settings-sections { display: grid; gap: 14px; }
1945
- .settings-card, .message, .loading-card, .config-path-card, .effective-card { border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; }
1946
- .settings-card { display: grid; gap: 14px; }
1947
- .message { margin-bottom: 12px; }
1948
- .settings-card .message { margin-bottom: 0; }
1949
- .error-message { border-color: var(--pi-danger); color: var(--pi-danger); background: color-mix(in srgb, var(--pi-danger) 10%, var(--pi-surface)); }
1950
- .loading-card { color: var(--pi-muted); }
1951
- .config-path-card { display: grid; gap: 5px; }
1952
- .config-path-card span, .field-heading, dt { color: var(--pi-muted); font-size: 12px; font-weight: 700; text-transform: uppercase; }
1953
- code { border: 1px solid var(--pi-border-muted); border-radius: 5px; background: var(--pi-bg); padding: 1px 4px; color: var(--pi-text); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; overflow-wrap: anywhere; }
1954
- .config-path-card small, .field small { color: var(--pi-muted); }
1955
- .config-form { display: grid; gap: 14px; }
1956
- .field { display: grid; gap: 7px; }
1957
- .field-heading { display: flex; align-items: center; gap: 8px; }
1958
- input, select, textarea { box-sizing: border-box; width: 100%; min-width: 0; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); color: var(--pi-text); padding: 9px 10px; outline: none; font: var(--pi-control-font-size, 16px) var(--pi-control-font-family, system-ui, sans-serif); }
1959
- input:focus, select:focus, textarea:focus { border-color: var(--pi-accent); box-shadow: 0 0 0 1px var(--pi-accent-border); }
1960
- textarea { resize: vertical; min-height: 94px; font-family: var(--pi-control-monospace-font-family, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); }
1961
- textarea:disabled { opacity: .55; }
1962
- .override-badge { border: 1px solid var(--pi-warning-border); border-radius: 999px; color: var(--pi-warning); background: var(--pi-warning-surface); padding: 2px 7px; font-size: 11px; font-weight: 600; text-transform: none; }
1963
- .effective-card { display: grid; gap: 10px; }
1964
- .effective-card dl { display: grid; gap: 8px; margin: 0; }
1965
- .effective-card dl > div { display: grid; grid-template-columns: 130px minmax(0, 1fr); gap: 12px; align-items: baseline; }
1966
- dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
1967
- .muted { color: var(--pi-muted); }
1968
- .form-actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 2px; }
1969
- .primary { border-color: var(--pi-accent); background: var(--pi-selection-bg); color: var(--pi-text-bright); }
1970
-
1971
- @media (max-width: 760px) {
1972
- .effective-card dl > div { grid-template-columns: minmax(0, 1fr); gap: 3px; }
1973
- }
1974
- `}};R([b({attribute:!1})],Y.prototype,`configResponse`,void 0),R([b({attribute:!1})],Y.prototype,`machineConfigResponse`,void 0),R([b({type:Boolean})],Y.prototype,`loading`,void 0),R([b({type:Boolean})],Y.prototype,`machineLoading`,void 0),R([b({type:Boolean})],Y.prototype,`saving`,void 0),R([b()],Y.prototype,`error`,void 0),R([b()],Y.prototype,`machineError`,void 0),R([b()],Y.prototype,`savedMessage`,void 0),R([b()],Y.prototype,`targetLabel`,void 0),R([b({attribute:!1})],Y.prototype,`onReload`,void 0),R([b({attribute:!1})],Y.prototype,`onReloadMachine`,void 0),R([b({attribute:!1})],Y.prototype,`onSave`,void 0),R([b({attribute:!1})],Y.prototype,`onSaveMachineConfig`,void 0),R([x()],Y.prototype,`gatewayDraft`,void 0),R([x()],Y.prototype,`machineDraft`,void 0),R([x()],Y.prototype,`gatewayLocalError`,void 0),R([x()],Y.prototype,`machineLocalError`,void 0),Y=R([y(`settings-general-panel`)],Y);function Ey(e){return e===!0?`Any host`:Array.isArray(e)?e.length===0?g`<span class="muted">None listed</span>`:e.join(`, `):g`<span class="muted">Unset</span>`}function Dy(e){return e===void 0||e.length===0?g`<span class="muted">External paths denied</span>`:e.join(`, `)}function Oy(e){return e.target instanceof HTMLInputElement?e.target.value:``}function ky(e){return e.target instanceof HTMLSelectElement?e.target.value:``}function Ay(e){return e.target instanceof HTMLTextAreaElement?e.target.value:``}function jy(e){return e instanceof Error?e.message:String(e)}function My(e){return{spawnSessions:e}}function Ny(e){return{subsessions:e}}function Py(e,t){let n=e?.effectiveConfig.agent;if(n?.command===void 0||n.dir===void 0||t===void 0)return`unavailable`;let r=[`PI_WEB_AGENT_SESSION_DIR`,...wt(n.command)?[`PI_CODING_AGENT_SESSION_DIR`]:[]];return n.command===t.command&&n.dir===t.dir&&Ly(t.sessionDirEnvKeys,r)?`active`:`restart-required`}function Fy(e,t){return e?.agentDirSource===`pi-web`?!0:e?.agentDirSource===`pi-compatibility`?wt(t.trim()||`pi`):e?.agentDir===!0}function Iy(e,t){let n={...e.envOverrides,spawnSessions:t.envOverrides.spawnSessions,subsessions:t.envOverrides.subsessions,agentCommand:t.envOverrides.agentCommand,agentDir:t.envOverrides.agentDir,agentSessionDir:t.envOverrides.agentSessionDir};return t.envOverrides.agentDirSource===void 0?delete n.agentDirSource:n.agentDirSource=t.envOverrides.agentDirSource,{...e,config:{...e.config,...t.config},effectiveConfig:{...e.effectiveConfig,...t.effectiveConfig},envOverrides:n}}function Ly(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}var Ry=class extends v{constructor(...e){super(...e),this.loading=!1,this.saving=!1,this.error=``,this.savedMessage=``,this.targetLabel=`local (local gateway)`,this.agentProfileSupport={state:`supported`},this.agentDraft=dy(),this.agentDraftDirty=!1,this.agentLocalError=``}willUpdate(e){if(e.has(`configResponse`)){if(this.configResponse===void 0){this.agentDraft=dy(),this.agentDraftDirty=!1,this.agentLocalError=``;return}(!this.agentDraftDirty||gy(this.agentDraft,this.configResponse.config))&&(this.agentDraft=my(this.configResponse.config),this.agentDraftDirty=!1,this.agentLocalError=``)}}render(){let e=this.configResponse,t=e?.envOverrides.spawnSessions===!0,n=e?.effectiveConfig.spawnSessions!==!1,r=e?.envOverrides.subsessions===!0,i=e?.effectiveConfig.subsessions===!0&&n,a=e?.envOverrides.agentCommand===!0,o=this.agentProfileSupport.state===`supported`,s=a?e.effectiveConfig.agent?.command??this.agentDraft.command:this.agentDraft.command,c=Fy(e?.envOverrides,s),l=e?.envOverrides.agentDir===!0,u=e?.effectiveConfig.agent,d=Py(e,this.activeAgentProfile);return g`
1975
- <settings-panel-frame
1976
- heading="Session daemon"
1977
- .description=${Hy(this.targetLabel)}
1978
- actionLabel="Reload"
1979
- .actionDisabled=${this.loading}
1980
- .notices=${this.panelNotices(e)}
1981
- .onAction=${this.onReload}
1982
- >
1983
- ${e===void 0?this.renderUnavailableConfigState():g`
1984
- <div class="config-path-card">
1985
- <span>Config file</span>
1986
- <code>${e.path}</code>
1987
- </div>
1988
- <form class="profile-form" aria-label="Pi-compatible agent profile" @submit=${e=>{this.saveAgentProfile(e)}}>
1989
- ${o?null:g`<div class="profile-support-message">${this.agentProfileSupport.message??`Pi-compatible agent profile editing is unavailable for this machine.`}</div>`}
1990
- <label class="field">
1991
- <span class="field-heading">
1992
- <span>Companion CLI command</span>
1993
- ${a?g`<span class="override-badge">environment override</span>`:null}
1994
- </span>
1995
- <input
1996
- class="text-input"
1997
- type="text"
1998
- autocomplete="off"
1999
- spellcheck="false"
2000
- .value=${this.agentDraft.command}
2001
- placeholder="pi"
2002
- ?disabled=${this.loading||this.saving||!o||a}
2003
- @input=${e=>{this.updateAgentDraft({command:By(e)})}}
2004
- >
2005
- <small>Set the Pi-compatible companion CLI used for doctor and update checks. The embedded session runtime remains PI WEB's bundled Pi SDK.</small>
2006
- </label>
2007
- <label class="field">
2008
- <span class="field-heading">
2009
- <span>Profile state directory</span>
2010
- ${l?g`<span class="override-badge">environment override</span>`:null}
2011
- </span>
2012
- <input
2013
- class="text-input"
2014
- type="text"
2015
- autocomplete="off"
2016
- spellcheck="false"
2017
- .value=${this.agentDraft.dir}
2018
- placeholder="~/.pi/agent or ~/agent-profiles/work"
2019
- ?disabled=${this.loading||this.saving||!o||c}
2020
- @input=${e=>{this.updateAgentDraft({dir:By(e)})}}
2021
- >
2022
- <small>Choose the Pi-compatible auth, models, settings, and sessions PI WEB reads. An alternate command and its required state directory are saved together.</small>
2023
- </label>
2024
- <footer class="form-actions">
2025
- <button class="primary" type="submit" ?disabled=${this.loading||this.saving||!o||a&&c}>${this.saving?`Saving…`:`Save agent profile`}</button>
2026
- </footer>
2027
- </form>
2028
- <div class="field">
2029
- <span class="field-heading">
2030
- <span>Allow agents to start sessions</span>
2031
- ${t?g`<span class="override-badge">environment override</span>`:null}
2032
- </span>
2033
- <label class="toggle">
2034
- <input
2035
- type="checkbox"
2036
- .checked=${n}
2037
- ?disabled=${this.loading||this.saving||t}
2038
- @change=${e=>{this.toggleSpawnSessions(e)}}
2039
- >
2040
- <span>Enable the <code>spawn_session</code> tool</span>
2041
- </label>
2042
- <small>When enabled, LLMs can start new sessions, constrained to a workspace (any worktree) of the same registered project so every spawned session stays visible here. On by default.</small>
2043
- </div>
2044
- <div class="field">
2045
- <span class="field-heading">
2046
- <span>Allow agents to start tracked subsessions</span>
2047
- <span class="beta-badge">beta</span>
2048
- ${r?g`<span class="override-badge">environment override</span>`:null}
2049
- </span>
2050
- <label class="toggle">
2051
- <input
2052
- type="checkbox"
2053
- .checked=${i}
2054
- ?disabled=${this.loading||this.saving||r||!n}
2055
- @change=${e=>{this.toggleSubsessions(e)}}
2056
- >
2057
- <span>Enable the <code>spawn_subsession</code> tools</span>
2058
- </label>
2059
- <small>Beta: agents can start child sessions they stay attached to (<code>spawn_subsession</code>, <code>list_subsessions</code>, <code>check_subsession</code>, <code>read_subsession</code>) and are notified when a child finishes. Requires "Allow agents to start sessions". Off by default.</small>
2060
- </div>
2061
- <section class="effective-card" aria-label="Desired and active session daemon configuration summary">
2062
- <h3>Desired after environment overrides</h3>
2063
- <dl>
2064
- <div><dt>Desired command</dt><dd>${u?.command??g`<span class="muted">Unavailable</span>`}</dd></div>
2065
- <div><dt>Desired state</dt><dd>${u?.dir??g`<span class="muted">Unavailable</span>`}</dd></div>
2066
- <div><dt>Active command</dt><dd>${this.activeAgentProfile?.command??g`<span class="muted">Unavailable</span>`}</dd></div>
2067
- <div><dt>Active state</dt><dd>${this.activeAgentProfile?.dir??g`<span class="muted">Unavailable</span>`}</dd></div>
2068
- <div><dt>Profile status</dt><dd>${zy(d)}</dd></div>
2069
- <div><dt>Spawn sessions</dt><dd>${n?`Enabled`:g`<span class="muted">Disabled</span>`}</dd></div>
2070
- <div><dt>Subsessions</dt><dd>${i?`Enabled`:g`<span class="muted">Disabled</span>`}</dd></div>
2071
- </dl>
2072
- </section>
2073
- `}
2074
- </settings-panel-frame>
2075
- `}panelNotices(e){return Uy(e,{error:this.agentLocalError||this.error,savedMessage:this.savedMessage,activeProfile:this.activeAgentProfile,targetLabel:this.targetLabel,profileEditingSupported:this.agentProfileSupport.state===`supported`})}renderUnavailableConfigState(){return g`<div class="loading-card">${this.loading?`Loading configuration…`:`Configuration is unavailable. Reload to try again.`}</div>`}async saveAgentProfile(e){e.preventDefault(),this.agentLocalError=``;try{await this.onSave?.(hy(this.agentDraft))}catch(e){this.agentLocalError=Vy(e)}}updateAgentDraft(e){this.agentDraft={...this.agentDraft,...e},this.agentDraftDirty=!0,this.agentLocalError=``}async toggleSpawnSessions(e){let t=e.target instanceof HTMLInputElement&&e.target.checked;await this.onSave?.(My(t))}async toggleSubsessions(e){let t=e.target instanceof HTMLInputElement&&e.target.checked;await this.onSave?.(Ny(t))}static{this.styles=h`
2076
- :host { display: block; }
2077
- h3 { margin: 0; font-size: 13px; line-height: 1.3; }
2078
- button, input { font: inherit; }
2079
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
2080
- button:disabled { opacity: .55; cursor: not-allowed; }
2081
- .loading-card, .config-path-card, .effective-card, .profile-support-message { border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; }
2082
- .loading-card { color: var(--pi-muted); }
2083
- .config-path-card { display: grid; gap: 5px; }
2084
- .profile-form { display: grid; gap: 14px; }
2085
- .profile-support-message { color: var(--pi-muted); line-height: 1.45; }
2086
- .form-actions { display: flex; justify-content: flex-end; }
2087
- .primary { border-color: var(--pi-accent); background: var(--pi-accent); color: var(--pi-accent-contrast); }
2088
- .config-path-card span, .field-heading, dt { color: var(--pi-muted); font-size: 12px; font-weight: 700; text-transform: uppercase; }
2089
- code { border: 1px solid var(--pi-border-muted); border-radius: 5px; background: var(--pi-bg); padding: 1px 4px; color: var(--pi-text); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; overflow-wrap: anywhere; }
2090
- .field { display: grid; gap: 7px; }
2091
- .field small { color: var(--pi-muted); line-height: 1.45; }
2092
- .field-heading { display: flex; align-items: center; gap: 8px; }
2093
- .toggle { display: flex; align-items: center; gap: 9px; cursor: pointer; }
2094
- .toggle input { width: 16px; height: 16px; }
2095
- .text-input {
2096
- width: 100%;
2097
- min-width: 0;
2098
- box-sizing: border-box;
2099
- border: 1px solid var(--pi-border);
2100
- border-radius: 8px;
2101
- background: var(--pi-bg);
2102
- color: var(--pi-text);
2103
- padding: 8px 9px;
2104
- outline: none;
2105
- font: var(--pi-control-font-size, 16px) var(--pi-control-monospace-font-family, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
2106
- }
2107
- .text-input:focus { border-color: var(--pi-accent); box-shadow: 0 0 0 1px var(--pi-accent-border); }
2108
- .text-input:disabled { opacity: .55; cursor: not-allowed; }
2109
- .toggle input:disabled { cursor: not-allowed; }
2110
- .override-badge { border: 1px solid var(--pi-warning-border); border-radius: 999px; color: var(--pi-warning); background: var(--pi-warning-surface); padding: 2px 7px; font-size: 11px; font-weight: 600; text-transform: none; }
2111
- .beta-badge { border: 1px solid var(--pi-border); border-radius: 999px; color: var(--pi-muted); background: var(--pi-bg); padding: 2px 7px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
2112
- .effective-card { display: grid; gap: 10px; }
2113
- .effective-card dl { display: grid; gap: 8px; margin: 0; }
2114
- .effective-card dl > div { display: grid; grid-template-columns: 130px minmax(0, 1fr); gap: 12px; align-items: baseline; }
2115
- dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
2116
- .muted { color: var(--pi-muted); }
2117
-
2118
- @media (max-width: 760px) {
2119
- .effective-card dl > div { grid-template-columns: minmax(0, 1fr); gap: 3px; }
2120
- }
2121
- `}};R([b({attribute:!1})],Ry.prototype,`configResponse`,void 0),R([b({type:Boolean})],Ry.prototype,`loading`,void 0),R([b({type:Boolean})],Ry.prototype,`saving`,void 0),R([b()],Ry.prototype,`error`,void 0),R([b()],Ry.prototype,`savedMessage`,void 0),R([b()],Ry.prototype,`targetLabel`,void 0),R([b({attribute:!1})],Ry.prototype,`activeAgentProfile`,void 0),R([b({attribute:!1})],Ry.prototype,`agentProfileSupport`,void 0),R([b({attribute:!1})],Ry.prototype,`onReload`,void 0),R([b({attribute:!1})],Ry.prototype,`onSave`,void 0),R([x()],Ry.prototype,`agentDraft`,void 0),R([x()],Ry.prototype,`agentDraftDirty`,void 0),R([x()],Ry.prototype,`agentLocalError`,void 0),Ry=R([y(`settings-sessiond-panel`)],Ry);function zy(e){return e===`active`?`Active`:e===`restart-required`?`Restart required`:g`<span class="muted">Unavailable</span>`}function By(e){return e.target instanceof HTMLInputElement?e.target.value:``}function Vy(e){return e instanceof Error?e.message:String(e)}function Hy(e){return`Select the Pi-compatible agent profile and companion CLI for ${e}. Changes are saved immediately but only take effect after the session daemon on that machine restarts.`}function Uy(e,t){let n=[];t.error!==``&&n.push({type:`error`,content:t.error}),t.savedMessage!==``&&n.push({type:`success`,content:t.savedMessage});let r=Py(e,t.activeProfile);return r===`restart-required`?n.push({type:`warning`,title:`Pi-compatible agent profile restart required on ${t.targetLabel}`,content:g`The desired profile differs from the active session-daemon profile. Run <code>pi-web restart</code> on that machine (or restart its session daemon service) to apply the command and state directory together.`}):e!==void 0&&r===`unavailable`&&t.profileEditingSupported&&n.push({type:`info`,title:`Active Pi-compatible agent profile unavailable on ${t.targetLabel}`,content:`PI WEB cannot compare the desired profile with the running session daemon. Reload after the daemon is available.`}),n}function Wy(e){return e===void 0?{id:`local`,name:`local`,kind:`local`}:{id:e.id,name:e.name,kind:e.kind}}function Gy(e){return e.kind===`local`?`${e.name} (local gateway)`:`${e.name} (remote machine)`}function Ky(e,t){return e.kind===`local`?{state:`supported`}:t?.ok===!0?Rt(t,w.piPackagesManage)?{state:`supported`}:{state:`unsupported`,message:Yy(e)}:{state:`unknown`}}function qy(e){return`${e.state}:${e.message??``}`}function Jy(e){return e?.state===`unsupported`}function Yy(e){return`Pi package management is not available on ${e.name}. Update and restart Pi-Web on that machine, then try again.`}function Xy(e){return e.kind===`local`}function Zy(e){return e.trim()}function Qy(e){if(Zy(e)===``)return`Enter a Pi package source accepted by Pi, such as npm:@scope/package, a git/URL source, or a local path.`}function $y(e){return e.scope===`project`?`Project scope`:`User scope`}function eb(e){return e.filtered?`Filtered by current Pi package settings`:`Available in this PI WEB process`}function tb(e){return e.installedPath??`Installed path not reported by Pi`}function nb(e){return e.scope===`user`}function rb(e){if(!nb(e))return`Project-scope Pi packages are listed for visibility, but PI WEB only updates user-scope Pi packages safely from this view.`}function ib(e){return e.length>0&&e.every(nb)}function ab(e){if(e.length===0)return`No Pi packages are configured yet.`;if(!ib(e))return`Update all is disabled while project-scope Pi packages are listed; update user-scope packages individually.`}function ob(e,t,n){return e?.kind===t?n===void 0||e.source===n:!1}function sb(e,t=Wy(void 0)){return`Pi package ${e===`install`?`installed`:e===`remove`?`removed`:`updated`}${t.kind===`local`?``:` on ${t.name}`}. Type /reload in ${t.kind===`local`?`each idle PI WEB session`:`each idle PI WEB session on ${t.name}`} to rediscover Pi runtime resources: extensions, skills, prompt templates, themes, and context/system prompt files. Reload the browser page separately for ${t.kind===`local`?`PI WEB browser plugin changes`:`PI WEB browser plugin changes served by ${t.name}`}.`}function cb(e,t){let n=e.trim();return t.kind===`remote`?lb(n)?Yy(t):n===`Remote machine timeout`?`Timed out while contacting ${t.name} for Pi package management. The package operation may still be running remotely; reload the package list before retrying.`:n===`Remote machine unavailable`?`Could not reach ${t.name} for Pi package management. Check the machine connection and try again.`:n:n}function lb(e){return e===`Not Found`||/route\s+(GET|POST):?\/api\/pi-packages\b.*not found/iu.test(e)||/cannot\s+(GET|POST)\s+.*\/api\/pi-packages\b/iu.test(e)}var ub=class extends v{constructor(...e){super(...e),this.loading=!1,this.error=``,this.operationMessage=``,this.installSource=``,this.validationMessage=``}render(){let e=this.packagesResponse?.packages??[],t=this.packageTarget,n=Gy(t),r=this.packageManagementUnavailable,i=this.packagesResponse!==void 0&&!r;return g`
2122
- <settings-panel-frame
2123
- heading="Pi packages"
2124
- .description=${db(n)}
2125
- actionLabel="Reload"
2126
- actionTitle=${r?this.packageManagementUnavailableMessage(n):`Reload Pi packages from ${n}`}
2127
- .actionDisabled=${this.loading||this.isOperating||r}
2128
- .notices=${this.panelNotices(n,i)}
2129
- .onAction=${this.onReload}
2130
- >
2131
- ${this.renderPanelContent(e,t,n)}
2132
- </settings-panel-frame>
2133
- `}panelNotices(e,t){let n=[];return this.packageManagementUnavailable?n.push({type:`availability`,content:this.packageManagementUnavailableMessage(e)}):this.error!==``&&n.push({type:`error`,content:this.error}),this.operationMessage!==``&&n.push({type:`success`,content:this.operationMessage}),t&&n.push({type:`security`,content:g`<strong>Trusted code warning:</strong> Pi packages and PI WEB plugins can run with your user permissions. Install packages and enable plugins only from sources you trust.`}),n}renderPanelContent(e,t,n){return this.packageManagementUnavailable?null:this.packagesResponse===void 0?g`<div class="loading-card">${this.loading?`Loading Pi packages from ${n}…`:`Pi package list unavailable for ${n}. Use Reload to try again.`}</div>`:g`
2134
- ${this.renderInstallForm(n)}
2135
- ${this.renderPackageList(e,t)}
2136
- `}renderInstallForm(e){return g`
2137
- <form class="install-card" @submit=${e=>{this.installPackage(e)}}>
2138
- <label for="package-source">Pi package source</label>
2139
- <div class="install-row">
2140
- <input id="package-source" .value=${this.installSource} ?disabled=${this.isOperating} placeholder="npm:@scope/package, git URL, or local path" @input=${e=>{this.updateInstallSource(e)}}>
2141
- <button type="submit" title="Install this Pi package" ?disabled=${this.isOperating}>${ob(this.operation,`install`)?`Installing…`:`Install`}</button>
2142
- </div>
2143
- ${this.validationMessage===``?null:g`<div class="field-error">${this.validationMessage}</div>`}
2144
- <small>Installs run on ${e} and use Pi's default package location, equivalent to <code>pi install &lt;source&gt;</code>. PI WEB does not ask you to choose an install location.</small>
2145
- </form>
2146
- `}renderPackageList(e,t){let n=Gy(t),r=this.packageManagementUnavailable?this.packageManagementUnavailableMessage(n):ab(e),i=r!==void 0&&e.length>0;return g`
2147
- <section class="package-section" aria-label="Configured Pi packages">
2148
- <div class="package-toolbar">
2149
- <div>
2150
- <h3>Configured Pi packages</h3>
2151
- <p>This list comes from Pi's package manager settings on ${n}.</p>
2152
- </div>
2153
- <button class="secondary" title=${r??`Update all user-scope Pi packages`} ?disabled=${this.isOperating||r!==void 0} @click=${()=>{this.updatePackage()}}>
2154
- ${ob(this.operation,`update-all`)?`Updating…`:`Update all`}
2155
- </button>
2156
- </div>
2157
- ${i?g`<div class="action-note">${r}</div>`:null}
2158
- ${this.loading&&e.length>0?g`<div class="action-note">Refreshing Pi packages from ${n}…</div>`:null}
2159
- ${this.renderPackageListContent(e,n)}
2160
- </section>
2161
- `}renderPackageListContent(e,t){return this.loading&&e.length===0?g`<div class="loading-card">Loading Pi packages from ${t}…</div>`:e.length===0?g`<div class="loading-card">No Pi packages configured in Pi settings on ${t} yet.</div>`:g`
2162
- <div class="package-list">
2163
- ${e.map(e=>this.renderPackage(e))}
2164
- </div>
2165
- `}renderPackage(e){let t=Gy(this.packageTarget),n=this.packageManagementUnavailable,r=n?this.packageManagementUnavailableMessage(t):rb(e),i=n?this.packageManagementUnavailableMessage(t):`Remove this Pi package`,a=ob(this.operation,`update`,e.source),o=ob(this.operation,`remove`,e.source);return g`
2166
- <article class=${`package-card${e.filtered?` filtered`:``}`}>
2167
- <div class="package-main">
2168
- <strong>${e.source}</strong>
2169
- <small>${$y(e)} · ${eb(e)}</small>
2170
- <small>Installed path: <code>${tb(e)}</code></small>
2171
- ${r===void 0?null:g`<small class="action-note">${r}</small>`}
2172
- </div>
2173
- <div class="package-actions">
2174
- <button class="secondary" title=${r??`Update this Pi package`} ?disabled=${this.isOperating||r!==void 0} @click=${()=>{this.updatePackage(e.source)}}>${a?`Updating…`:`Update`}</button>
2175
- <button class="danger" title=${i} ?disabled=${this.isOperating||n} @click=${()=>{this.removePackage(e)}}>${o?`Removing…`:`Remove`}</button>
2176
- </div>
2177
- </article>
2178
- `}updateInstallSource(e){this.installSource=e.target instanceof HTMLInputElement?e.target.value:``,this.validationMessage=``}async installPackage(e){e.preventDefault();let t=Qy(this.installSource);if(t!==void 0){this.validationMessage=t;return}let n=Zy(this.installSource);try{await this.onInstallPackage?.(n),this.installSource=``,this.validationMessage=``}catch{}}async removePackage(e){try{await this.onRemovePackage?.(e.source,e.scope)}catch{}}async updatePackage(e){try{await this.onUpdatePackage?.(e)}catch{}}get packageTarget(){return this.targetMachine??Wy(void 0)}get packageManagementUnavailable(){return Jy(this.managementSupport)}packageManagementUnavailableMessage(e){return this.managementSupport?.message??`Pi package management is not available on ${e}.`}get isOperating(){return this.operation!==void 0}static{this.styles=h`
2179
- :host { display: block; }
2180
- .package-toolbar { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
2181
- .package-toolbar > div, .package-main { display: grid; gap: 6px; min-width: 0; }
2182
- h3, p { margin: 0; }
2183
- h3 { font-size: 15px; line-height: 1.25; }
2184
- p, small { color: var(--pi-muted); line-height: 1.45; }
2185
- button, input { font: inherit; }
2186
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
2187
- button:disabled, input:disabled { opacity: .55; cursor: not-allowed; }
2188
- input { box-sizing: border-box; width: 100%; min-width: 0; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); color: var(--pi-text); padding: 8px 9px; }
2189
- label { font-weight: 700; }
2190
- .secondary { flex: 0 0 auto; }
2191
- .danger { border-color: color-mix(in srgb, var(--pi-danger) 55%, var(--pi-border)); color: var(--pi-danger); }
2192
- .loading-card, .install-card, .package-card { border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; }
2193
- .field-error { color: var(--pi-danger); font-size: 12px; }
2194
- .install-card { display: grid; gap: 8px; }
2195
- .install-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: center; }
2196
- .package-section { display: block; }
2197
- .loading-card, .action-note { color: var(--pi-muted); }
2198
- .action-note { margin-bottom: 10px; font-size: 12px; }
2199
- .package-list { display: grid; gap: 10px; }
2200
- .package-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; }
2201
- .package-card.filtered { opacity: .82; }
2202
- .package-main strong, .package-main small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2203
- .package-actions { display: flex; align-items: center; gap: 8px; }
2204
- code { border: 1px solid var(--pi-border-muted); border-radius: 5px; background: var(--pi-bg); padding: 1px 4px; color: var(--pi-text); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; overflow-wrap: anywhere; }
2205
-
2206
- @media (max-width: 760px) {
2207
- .package-toolbar { display: grid; gap: 12px; }
2208
- .package-toolbar .secondary { justify-self: start; }
2209
- .install-row, .package-card { grid-template-columns: minmax(0, 1fr); align-items: start; }
2210
- .package-actions { justify-self: start; flex-wrap: wrap; }
2211
- .package-main strong, .package-main small { white-space: normal; }
2212
- }
2213
- `}};R([b({attribute:!1})],ub.prototype,`packagesResponse`,void 0),R([b({type:Boolean})],ub.prototype,`loading`,void 0),R([b({attribute:!1})],ub.prototype,`operation`,void 0),R([b({attribute:!1})],ub.prototype,`targetMachine`,void 0),R([b({attribute:!1})],ub.prototype,`managementSupport`,void 0),R([b()],ub.prototype,`error`,void 0),R([b()],ub.prototype,`operationMessage`,void 0),R([b({attribute:!1})],ub.prototype,`onReload`,void 0),R([b({attribute:!1})],ub.prototype,`onInstallPackage`,void 0),R([b({attribute:!1})],ub.prototype,`onRemovePackage`,void 0),R([b({attribute:!1})],ub.prototype,`onUpdatePackage`,void 0),R([x()],ub.prototype,`installSource`,void 0),R([x()],ub.prototype,`validationMessage`,void 0),ub=R([y(`settings-packages-panel`)],ub);function db(e){return g`Managing Pi packages on <strong>${e}</strong>. Install, remove, and update packages managed by Pi on the selected machine. Pi packages can provide extensions, skills, prompt templates, themes, context/system prompt files, and PI WEB browser plugins.`}var fb=class extends v{constructor(...e){super(...e),this.loading=!1,this.saving=!1,this.error=``,this.savedMessage=``,this.targetLabel=`local (local gateway)`}render(){let e=this.pluginsResponse?.plugins??[],t=this.pluginsResponse!==void 0;return g`
2214
- <settings-panel-frame
2215
- heading="PI WEB plugins"
2216
- .description=${pb(this.targetLabel)}
2217
- actionLabel="Reload"
2218
- actionTitle=${`Reload PI WEB plugins from ${this.targetLabel}`}
2219
- .actionDisabled=${this.loading}
2220
- .notices=${this.panelNotices(e.length>0)}
2221
- .onAction=${this.onReload}
2222
- >
2223
- ${this.renderPanelContent(e,t)}
2224
- </settings-panel-frame>
2225
- `}panelNotices(e){let t=[];return this.error!==``&&t.push({type:`error`,content:this.error}),this.shouldShowConfigUnavailableNotice(e)&&t.push({type:`availability`,content:`Configuration is unavailable. Reload to try again before changing plugin enablement.`}),this.savedMessage!==``&&t.push({type:`success`,content:`${this.savedMessage} Reload the browser tab to apply plugin changes.`}),e&&t.push({type:`security`,content:g`<strong>Trusted code warning:</strong> PI WEB plugins and Pi packages can run with your user permissions. Enable plugins only from sources you trust.`}),t}shouldShowConfigUnavailableNotice(e){return e&&this.configResponse===void 0&&!this.loading&&this.error===``}renderPanelContent(e,t){return t?e.length===0?g`<div class="loading-card">No PI WEB browser plugins discovered on ${this.targetLabel}.</div>`:g`
2226
- <div class="plugin-note">Config key on ${this.targetLabel}: <code>plugins</code>. Plugins are enabled unless their entry sets <code>enabled</code> to <code>false</code>.</div>
2227
- <div class="plugin-list">
2228
- ${e.map(e=>this.renderPlugin(e))}
2229
- </div>
2230
- `:g`<div class="loading-card">${this.loading?`Loading PI WEB plugins…`:`PI WEB plugin list unavailable for ${this.targetLabel}. Use Reload to try again.`}</div>`}renderPlugin(e){let t=this.configResponse?.config.plugins?.[e.id],n=t?.enabled===!1?`Config disabled`:t?.enabled===!0?`Config enabled`:`Default enabled`;return g`
2231
- <article class=${`plugin-card${e.enabled?``:` disabled`}`}>
2232
- <div class="plugin-main">
2233
- <strong>${e.id}</strong>
2234
- <small>${e.source} · ${e.scope}${e.machineSpecific?` · machine-specific`:``}</small>
2235
- <small>${n}</small>
2236
- </div>
2237
- <label class="toggle">
2238
- <input type="checkbox" .checked=${e.enabled} ?disabled=${this.saving||this.configResponse===void 0} @change=${t=>{this.togglePlugin(e,t)}}>
2239
- <span>${e.enabled?`Enabled`:`Disabled`}</span>
2240
- </label>
2241
- </article>
2242
- `}async togglePlugin(e,t){let n=t.target instanceof HTMLInputElement?t.target.checked:e.enabled;await this.onTogglePlugin?.(e.id,n)}static{this.styles=h`
2243
- :host { display: block; }
2244
- input { font: inherit; }
2245
- input:disabled { opacity: .55; cursor: not-allowed; }
2246
- .loading-card, .plugin-note, .plugin-card { border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; }
2247
- .loading-card, .plugin-note { color: var(--pi-muted); }
2248
- code { border: 1px solid var(--pi-border-muted); border-radius: 5px; background: var(--pi-bg); padding: 1px 4px; color: var(--pi-text); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; overflow-wrap: anywhere; }
2249
- .plugin-list { display: grid; gap: 10px; }
2250
- .plugin-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; }
2251
- .plugin-card.disabled { opacity: .75; }
2252
- .plugin-main { min-width: 0; display: grid; gap: 3px; }
2253
- .plugin-main strong, .plugin-main small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2254
- .plugin-main small { color: var(--pi-muted); }
2255
- .toggle { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
2256
- .toggle input { width: 18px; height: 18px; accent-color: var(--pi-accent); }
2257
-
2258
- @media (max-width: 760px) {
2259
- .plugin-card { grid-template-columns: minmax(0, 1fr); align-items: start; }
2260
- .toggle { justify-self: start; }
2261
- }
2262
- `}};R([b({attribute:!1})],fb.prototype,`pluginsResponse`,void 0),R([b({attribute:!1})],fb.prototype,`configResponse`,void 0),R([b({type:Boolean})],fb.prototype,`loading`,void 0),R([b({type:Boolean})],fb.prototype,`saving`,void 0),R([b()],fb.prototype,`error`,void 0),R([b()],fb.prototype,`savedMessage`,void 0),R([b()],fb.prototype,`targetLabel`,void 0),R([b({attribute:!1})],fb.prototype,`onReload`,void 0),R([b({attribute:!1})],fb.prototype,`onTogglePlugin`,void 0),fb=R([y(`settings-plugins-panel`)],fb);function pb(e){return g`Enable or disable discovered PI WEB browser plugins on <strong>${e}</strong>. This is separate from installing Pi packages. Reload the browser tab to apply plugin runtime changes.`}var mb={capture:!0},hb=[{value:`auto`,label:`Auto/default`,description:`Desktop-like Enter sends; mobile, coarse pointer, or narrow screens insert a new line.`},{value:`send`,label:`Enter sends message`,description:`Enter sends the chat message; Shift+Enter adds a new line when supported.`},{value:`newline`,label:`Enter inserts new line`,description:`Enter adds a line break; Shift+Enter sends the chat message when supported.`}];function gb(){return g`Edit app shortcuts by action. Type a shortcut such as <code>mod+k</code> or <code>mod+g p</code>, record one from the keyboard, disable it with None, or reset it to the default. When shortcuts conflict, custom shortcuts win before defaults; ties are resolved by action id, and shorter shortcuts shadow longer sequences with the same prefix.`}var _b=class extends v{constructor(...e){super(...e),this.actions=[],this.loading=!1,this.saving=!1,this.error=``,this.savedMessage=``,this.drafts={},this.localError=``,this.promptEnterPreference=pv(),this.recordingListenerActive=!1,this.onRecordKeyDown=e=>{let t=this.recording;if(t===void 0)return;if(e.preventDefault(),e.stopPropagation(),e.key===`Escape`){this.stopRecording();return}let n=Pl(e);if(n===void 0){this.localError=`Press a letter, number, punctuation, function, or navigation key. Press Esc to cancel recording.`;return}if(t.tokens.length===0&&!Fl(n)){this.localError=`Start shortcuts with Ctrl/⌘ or Alt so normal typing is not captured.`;return}let r=[...t.tokens,n];this.localError=``,this.drafts={[t.actionId]:r.join(` `)},this.recording={actionId:t.actionId,tokens:r},this.armRecordingTimer()}}willUpdate(e){e.has(`configResponse`)&&this.configResponse!==void 0&&(this.drafts={},this.localError=``,this.stopRecording())}disconnectedCallback(){this.stopRecording(),super.disconnectedCallback()}render(){let e=xb(this.actions),t=this.shortcutResolutions();return g`
2263
- <settings-panel-frame
2264
- heading="Keyboard shortcuts"
2265
- .description=${gb()}
2266
- actionLabel="Reload"
2267
- .actionDisabled=${this.loading}
2268
- .notices=${this.panelNotices()}
2269
- .onAction=${this.onReload}
2270
- >
2271
- ${this.renderPromptEnterPreferenceCard()}
2272
- ${this.configResponse===void 0&&this.loading?g`<div class="loading-card">Loading shortcuts…</div>`:g`
2273
- <div class="config-path-card">
2274
- <span>Config file</span>
2275
- <code>${this.configResponse?.path??`Unknown`}</code>
2276
- <small>Shortcut overrides are saved under <code>shortcuts</code>. A value of <code>null</code> disables the action shortcut.</small>
2277
- </div>
2278
- ${e.length===0?g`<div class="loading-card">No actions registered.</div>`:e.map(e=>g`
2279
- <section class="shortcut-group">
2280
- <h3>${e.name}</h3>
2281
- <div class="shortcut-list">
2282
- ${e.actions.map(e=>this.renderShortcutRow(e,t.get(e.id)))}
2283
- </div>
2284
- </section>
2285
- `)}
2286
- `}
2287
- </settings-panel-frame>
2288
- `}panelNotices(){let e=[],t=this.localError||this.error;return t!==``&&e.push({type:`error`,content:t}),this.savedMessage!==``&&e.push({type:`success`,content:this.savedMessage}),e}renderPromptEnterPreferenceCard(){return g`
2289
- <section class="prompt-enter-card" aria-labelledby="prompt-enter-preference-title">
2290
- <div class="prompt-enter-copy">
2291
- <span class="card-eyebrow">Chat composer</span>
2292
- <h3 id="prompt-enter-preference-title">Enter key behavior</h3>
2293
- <p>Choose what Enter does in this browser. Shift+Enter does the opposite when supported; automatic touch-keyboard capitalization is ignored to avoid accidental sends.</p>
2294
- </div>
2295
- <div class="prompt-enter-options" role="radiogroup" aria-label="Enter and Shift Enter behavior in the chat composer">
2296
- ${hb.map(e=>g`
2297
- <label class="prompt-enter-option">
2298
- <input
2299
- type="radio"
2300
- name="prompt-enter-preference"
2301
- .value=${e.value}
2302
- .checked=${this.promptEnterPreference===e.value}
2303
- @change=${()=>{this.updatePromptEnterPreference(e.value)}}
2304
- >
2305
- <span>
2306
- <strong>${e.label}</strong>
2307
- <small>${e.description}</small>
2308
- </span>
2309
- </label>
2310
- `)}
2311
- </div>
2312
- </section>
2313
- `}updatePromptEnterPreference(e){this.promptEnterPreference=e,mv(e)}renderShortcutRow(e,t){let n=this.configResponse?.config.shortcuts,r=Cb(e.id,n),i=Eb(e,n),a=this.shortcutInputText(e),o=a.trim()===``?void 0:jl(a),s=o?.ok===!0?o.shortcut:Tb(e,n),c=r!==void 0,l=this.drafts[e.id]!==void 0,u=l&&a.trim()!==``?`custom`:i,d=this.recordingHint(e.id),f=bb(t);return g`
2314
- <article class=${vb(t)}>
2315
- <div class="shortcut-main">
2316
- <strong>${e.title}</strong>
2317
- ${e.description!==void 0&&e.description!==``?g`<small>${e.description}</small>`:null}
2318
- <small class="shortcut-id">${e.id}</small>
2319
- <small>${e.shortcut!==void 0&&e.shortcut!==``?g`Default: <kbd>${Nl(e.shortcut)}</kbd>`:`No default shortcut`}</small>
2320
- </div>
2321
- <div class="shortcut-editor">
2322
- <div class="shortcut-status">
2323
- ${s!==void 0&&s!==``?g`<kbd>${Nl(s)}</kbd>`:g`<span class="unassigned">${i===`disabled`?`Disabled`:`Unassigned`}</span>`}
2324
- <small class=${u}>${Db(u)}${l?` · Unsaved`:``}</small>
2325
- ${f===void 0?null:g`<small class=${yb(t)}>${f}</small>`}
2326
- </div>
2327
- <label class="shortcut-input-label">
2328
- <span>Shortcut</span>
2329
- <input
2330
- class="shortcut-input"
2331
- data-action-id=${e.id}
2332
- .value=${a}
2333
- placeholder=${e.shortcut??`mod+k`}
2334
- autocomplete="off"
2335
- autocapitalize="off"
2336
- spellcheck="false"
2337
- ?disabled=${this.saving}
2338
- @input=${t=>{this.updateDraft(e.id,Ob(t))}}
2339
- >
2340
- </label>
2341
- ${d===``?null:g`<small class="recording-hint">${d}</small>`}
2342
- <div class="shortcut-actions">
2343
- <button class="primary" ?disabled=${this.loading||this.saving||!l||a.trim()===``} @click=${()=>{this.saveShortcut(e)}}>Save</button>
2344
- <button ?disabled=${this.loading||this.saving} @click=${()=>{this.toggleRecording(e.id)}}>${this.recording?.actionId===e.id?`Cancel recording`:`Record`}</button>
2345
- <button ?disabled=${this.loading||this.saving||r===null} @click=${()=>{this.setShortcutNone(e.id)}}>None</button>
2346
- <button ?disabled=${this.loading||this.saving||!c} @click=${()=>{this.resetShortcut(e.id)}}>Reset</button>
2347
- </div>
2348
- </div>
2349
- </article>
2350
- `}shortcutInputText(e){let t=this.drafts[e.id];if(t!==void 0)return t;let n=Cb(e.id,this.configResponse?.config.shortcuts);return n===null?``:n??e.shortcut??``}recordingHint(e){let t=this.recording;return t?.actionId===e?t.tokens.length===0?`Recording: press Ctrl/⌘ or Alt with a key. Press Esc to cancel.`:`Recording: ${Nl(t.tokens.join(` `))}. Press another key to add a sequence, or wait to finish.`:``}updateDraft(e,t){this.drafts={[e]:t},this.localError=``}async saveShortcut(e){this.stopRecording();let t=jl(this.shortcutInputText(e).trim());if(!t.ok){this.localError=t.message;return}this.localError=``,await this.saveShortcutPreference(e.id,t.shortcut)}async setShortcutNone(e){this.stopRecording(),this.localError=``,await this.saveShortcutPreference(e,null)}async resetShortcut(e){this.stopRecording(),this.localError=``,await this.saveShortcutPreference(e,void 0)}async saveShortcutPreference(e,t){let n={...this.configResponse?.config??{}},r=n.shortcuts??{},i=t===void 0?wb(r,e):{...r,[e]:t};Object.keys(i).length===0?delete n.shortcuts:n.shortcuts=i,await this.onSave?.(n)}shortcutResolutions(){return new Map(Al(this.actions,this.previewShortcutConfig(),{enabledOnly:!0}).map(e=>[e.action.id,e]))}previewShortcutConfig(){let e={...this.configResponse?.config.shortcuts??{}};for(let[t,n]of Object.entries(this.drafts)){let r=n.trim();if(r===``)continue;let i=jl(r);i.ok&&(e[t]=i.shortcut)}return Object.keys(e).length===0?void 0:e}async toggleRecording(e){if(this.recording?.actionId===e){this.stopRecording();return}this.stopRecording(),this.localError=``,this.recording={actionId:e,tokens:[]},this.ensureRecordingListener(),await this.updateComplete,this.focusShortcutInput(e)}focusShortcutInput(e){for(let t of this.renderRoot.querySelectorAll(`.shortcut-input`))if(t.dataset.actionId===e){t.focus(),t.select();return}}armRecordingTimer(){this.clearRecordingTimer(),this.recordingTimer=window.setTimeout(()=>{this.recordingTimer=void 0,this.stopRecording()},Dl)}stopRecording(){this.clearRecordingTimer(),this.removeRecordingListener(),this.recording=void 0}clearRecordingTimer(){this.recordingTimer!==void 0&&(window.clearTimeout(this.recordingTimer),this.recordingTimer=void 0)}ensureRecordingListener(){this.recordingListenerActive||=(window.addEventListener(`keydown`,this.onRecordKeyDown,mb),!0)}removeRecordingListener(){this.recordingListenerActive&&=(window.removeEventListener(`keydown`,this.onRecordKeyDown,mb),!1)}static{this.styles=h`
2351
- :host { display: block; }
2352
- h3, p { margin: 0; }
2353
- h3 { font-size: 13px; line-height: 1.3; }
2354
- p { color: var(--pi-muted); line-height: 1.45; }
2355
- button, input { font: inherit; }
2356
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
2357
- button:disabled, input:disabled { opacity: .55; cursor: not-allowed; }
2358
- .primary { border-color: var(--pi-accent); background: var(--pi-selection-bg); color: var(--pi-text-bright); }
2359
- .loading-card, .config-path-card, .prompt-enter-card { border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; }
2360
- .loading-card, .config-path-card { color: var(--pi-muted); }
2361
- .config-path-card { display: grid; gap: 5px; }
2362
- .config-path-card span, .card-eyebrow { color: var(--pi-muted); font-size: 12px; font-weight: 700; text-transform: uppercase; }
2363
- .prompt-enter-card { display: grid; grid-template-columns: minmax(0, .85fr) minmax(260px, 1fr); gap: 12px; align-items: start; }
2364
- .prompt-enter-copy { display: grid; gap: 5px; min-width: 0; }
2365
- .prompt-enter-copy p, .prompt-enter-option small { font-size: 12px; }
2366
- .prompt-enter-options { display: grid; gap: 7px; }
2367
- .prompt-enter-option { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px; align-items: start; color: var(--pi-text); }
2368
- .prompt-enter-option input { box-sizing: border-box; width: 14px; min-width: 14px; height: 14px; margin: 3px 0 0; padding: 0; border: 0; background: transparent; accent-color: var(--pi-accent); font-family: inherit; }
2369
- .prompt-enter-option input:focus { border-color: transparent; box-shadow: none; outline: 2px solid var(--pi-accent-border); outline-offset: 2px; }
2370
- .prompt-enter-option span { display: grid; gap: 2px; }
2371
- .prompt-enter-option small { color: var(--pi-muted); line-height: 1.35; }
2372
- code { border: 1px solid var(--pi-border-muted); border-radius: 5px; background: var(--pi-bg); padding: 1px 4px; color: var(--pi-text); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; overflow-wrap: anywhere; }
2373
- .shortcut-group { margin: 0; }
2374
- .shortcut-group h3 { margin: 0 0 8px; color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
2375
- .shortcut-list { border: 1px solid var(--pi-border); border-radius: 10px; overflow: hidden; }
2376
- .shortcut-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(360px, 48%); gap: 14px; align-items: start; padding: 12px; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-surface); }
2377
- .shortcut-row.shadowed { background: color-mix(in srgb, var(--pi-warning) 5%, var(--pi-surface)); }
2378
- .shortcut-row.shadowing { background: color-mix(in srgb, var(--pi-accent) 5%, var(--pi-surface)); }
2379
- .shortcut-row:last-child { border-bottom: 0; }
2380
- .shortcut-main { min-width: 0; display: grid; gap: 4px; }
2381
- .shortcut-main strong, .shortcut-main small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2382
- .shortcut-main small { color: var(--pi-muted); }
2383
- .shortcut-id { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
2384
- .shortcut-editor { min-width: 0; display: grid; gap: 8px; }
2385
- .shortcut-status { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
2386
- .shortcut-status small { color: var(--pi-muted); font-size: 11px; }
2387
- .shortcut-status small.custom { color: var(--pi-accent); }
2388
- .shortcut-status small.disabled { color: var(--pi-warning); }
2389
- .shortcut-status small.conflict { border: 1px solid currentColor; border-radius: 999px; padding: 2px 7px; }
2390
- .shortcut-status small.conflict.shadowing { color: var(--pi-accent); }
2391
- .shortcut-status small.conflict.shadowed { color: var(--pi-warning); }
2392
- .shortcut-input-label { min-width: 0; display: grid; gap: 5px; }
2393
- .shortcut-input-label span { color: var(--pi-muted); font-size: 11px; font-weight: 700; text-transform: uppercase; }
2394
- input { box-sizing: border-box; width: 100%; min-width: 0; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); color: var(--pi-text); padding: 8px 9px; outline: none; font: var(--pi-control-font-size, 16px) var(--pi-control-monospace-font-family, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); }
2395
- input:focus { border-color: var(--pi-accent); box-shadow: 0 0 0 1px var(--pi-accent-border); }
2396
- .shortcut-actions { display: flex; justify-content: flex-end; gap: 7px; flex-wrap: wrap; }
2397
- kbd { border: 1px solid var(--pi-border); border-radius: 6px; background: var(--pi-bg); color: var(--pi-text-secondary); padding: 3px 7px; font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; white-space: nowrap; }
2398
- .unassigned { color: var(--pi-muted); font-size: 12px; }
2399
- .recording-hint { color: var(--pi-accent); font-size: 12px; }
2400
-
2401
- @media (max-width: 760px) {
2402
- .prompt-enter-card { grid-template-columns: minmax(0, 1fr); }
2403
- .shortcut-row { grid-template-columns: minmax(0, 1fr); align-items: start; }
2404
- .shortcut-status, .shortcut-actions { justify-content: flex-start; }
2405
- }
2406
- `}};R([b({attribute:!1})],_b.prototype,`actions`,void 0),R([b({attribute:!1})],_b.prototype,`configResponse`,void 0),R([b({type:Boolean})],_b.prototype,`loading`,void 0),R([b({type:Boolean})],_b.prototype,`saving`,void 0),R([b()],_b.prototype,`error`,void 0),R([b()],_b.prototype,`savedMessage`,void 0),R([b({attribute:!1})],_b.prototype,`onReload`,void 0),R([b({attribute:!1})],_b.prototype,`onSave`,void 0),R([x()],_b.prototype,`drafts`,void 0),R([x()],_b.prototype,`localError`,void 0),R([x()],_b.prototype,`promptEnterPreference`,void 0),R([x()],_b.prototype,`recording`,void 0),_b=R([y(`settings-shortcuts-panel`)],_b);function vb(e){return e?.active===!1?`shortcut-row shadowed`:e?.active===!0&&e.shadows.length>0?`shortcut-row shadowing`:`shortcut-row`}function yb(e){return e?.active===!1?`conflict shadowed`:`conflict shadowing`}function bb(e){if(e===void 0)return;if(!e.active)return`Shadowed by ${e.shadowedBy?.action.title??`another action`}`;let t=e.shadows.length;if(t===0)return;let n=e.shadows.slice(0,2).map(e=>e.action.title).join(`, `),r=t>2?`, +${String(t-2)} more`:``;return`Shadows ${String(t)} ${t===1?`action`:`actions`}: ${n}${r}`}function xb(e){let t=new Map;for(let n of[...e].sort(Sb)){let e=n.group??`Other`;t.set(e,[...t.get(e)??[],n])}return[...t.entries()].map(([e,t])=>({name:e,actions:t}))}function Sb(e,t){return(e.group??`Other`).localeCompare(t.group??`Other`)||e.title.localeCompare(t.title)}function Cb(e,t){if(!(t===void 0||!Object.hasOwn(t,e)))return t[e]}function wb(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>e!==t))}function Tb(e,t){let n=Cb(e.id,t);if(n!==null)return n??e.shortcut}function Eb(e,t){let n=Cb(e.id,t);return n===null?`disabled`:n===void 0?e.shortcut===void 0||e.shortcut===``?`unassigned`:`default`:`custom`}function Db(e){switch(e){case`default`:return`Default`;case`custom`:return`Custom`;case`disabled`:return`Disabled`;case`unassigned`:return`No default`}}function Ob(e){return e.target instanceof HTMLInputElement?e.target.value:``}async function kb(e){let[t,n]=await Promise.allSettled([e.loadConfig(),e.loadPlugins()]),r={error:``},i=[];return t.status===`fulfilled`?r.config=t.value:i.push(`config: ${jb(t.reason)}`),n.status===`fulfilled`?r.plugins=n.value:i.push(`PI WEB plugins: ${jb(n.reason)}`),i.length>0&&(r.error=`Failed to load settings: ${i.join(`; `)}`),r}async function Ab(e,t,n){if(Jy(n))return{error:n.message??`Pi package management is not available on ${Gy(e)}.`,skipped:!0};try{return{packagesResponse:await t(e.id),error:``}}catch(t){return{error:`Failed to load Pi packages from ${Gy(e)}: ${cb(jb(t),e)}`}}}function jb(e){return e instanceof Error?e.message:String(e)}function Mb(e,t){return{...e,config:Nb(e.config,t.config),effectiveConfig:Nb(e.effectiveConfig,t.effectiveConfig)}}function Nb(e,t){return{...e,...t.pathAccess===void 0?{}:{pathAccess:t.pathAccess},...t.uploads===void 0?{}:{uploads:t.uploads},...t.maxUploadBytes===void 0?{}:{maxUploadBytes:t.maxUploadBytes}}}function Pb(e){return e===void 0?{id:`local`,name:`local`,kind:`local`}:{id:e.id,name:e.name,kind:e.kind}}function X(e){return e.kind===`local`?`${e.name} (local gateway)`:`${e.name} (remote machine)`}function Fb(e,t){return e.kind===`local`?{state:`supported`}:t?.ok===!0?Rt(t,w.selectedMachineSettings)?{state:`supported`}:{state:`unsupported`,message:Bb(e)}:{state:`unknown`}}function Ib(e,t){return e.kind===`local`?{state:`supported`}:t?.ok===!0?Rt(t,w.agentProfileConfig)?{state:`supported`}:{state:`unsupported`,message:`Pi-compatible agent profile settings are not available on ${e.name}. Update and restart PI WEB on that machine, then try again.`}:{state:`unknown`,message:`Pi-compatible agent profile support could not be verified on ${e.name}. Reload machine status before changing the profile.`}}function Lb(e){return`${e.state}:${e.message??``}`}function Rb(e){return e?.state===`unsupported`}function zb(e){return e?.state===`supported`}function Bb(e){return`Selected-machine settings are not available on ${e.name}. Update and restart PI WEB on that machine, then try again.`}function Vb(e,t){let n=e.trim();return t.kind===`remote`?Hb(n)?Bb(t):n===`Remote machine timeout`?`Timed out while contacting ${t.name} for selected-machine settings. The operation may still be running remotely; reload before retrying.`:n===`Remote machine unavailable`?`Could not reach ${t.name} for selected-machine settings. Check the machine connection and try again.`:n:n}function Hb(e){return e===`Not Found`||/route\s+(GET|PUT):?\/api\/(config|plugins)\b.*not found/iu.test(e)||/cannot\s+(GET|PUT)\s+.*\/api\/(config|plugins)\b/iu.test(e)}function Ub(e,t,n){let r=e.plugins??{},i=r[t]??{};return{plugins:{...r,[t]:{...i,enabled:n}}}}function Wb(e,t){return{...e,config:Gb(e.config,t.config),effectiveConfig:Gb(e.effectiveConfig,t.effectiveConfig)}}function Gb(e,t){return t.plugins===void 0?e:{...e,plugins:t.plugins}}var Z=class extends v{constructor(...e){super(...e),this.section=`general`,this.actions=[],this.loading=!0,this.accessLoading=!0,this.sessiondLoading=!0,this.pluginLoading=!0,this.packageLoading=!0,this.saving=!1,this.error=``,this.accessError=``,this.sessiondError=``,this.pluginError=``,this.packageError=``,this.savedMessage=``,this.packageMessage=``,this.loadRequestSeq=0,this.accessLoadRequestSeq=0,this.sessiondLoadRequestSeq=0,this.pluginLoadRequestSeq=0,this.packageLoadRequestSeq=0,this.packageMutationSeq=0}connectedCallback(){super.connectedCallback(),this.loadConfig(),this.loadAccessConfigForTarget(),this.reloadSessiondState(),this.loadPluginsForTarget(),this.loadPackagesForTarget()}disconnectedCallback(){this.savedMessageTimer!==void 0&&window.clearTimeout(this.savedMessageTimer),this.savedMessageTimer=void 0,super.disconnectedCallback()}updated(e){let t=this.settingsTarget();if(e.has(`machine`)&&Pb(e.get(`machine`)).id!==t.id){this.resetAccessStateForTargetChange(),this.isConnected&&this.loadAccessConfigForTarget(t),this.resetSessiondStateForTargetChange(),this.isConnected&&this.loadSessiondConfigForTarget(t),this.resetPluginStateForTargetChange(),this.isConnected&&this.loadPluginsForTarget(t),this.resetPackageStateForTargetChange(),this.isConnected&&this.loadPackagesForTarget(t);return}e.has(`machineRuntime`)&&(this.selectedMachineSettingsSupportNeedsReload(e.get(`machineRuntime`),t)&&(this.resetAccessStateForTargetChange(),this.isConnected&&this.loadAccessConfigForTarget(t),this.resetSessiondStateForTargetChange(),this.isConnected&&this.loadSessiondConfigForTarget(t),this.resetPluginStateForTargetChange(),this.isConnected&&this.loadPluginsForTarget(t)),this.packageManagementSupportNeedsReload(e.get(`machineRuntime`),t)&&(this.resetPackageStateForTargetChange(),this.isConnected&&this.loadPackagesForTarget(t)))}render(){return g`
2407
- <div class="backdrop" @mousedown=${()=>this.onClose?.()}>
2408
- <section class="settings-shell" role="dialog" aria-modal="true" aria-label="PI WEB settings" @mousedown=${e=>{e.stopPropagation()}} @keydown=${e=>{this.handleKeyDown(e)}}>
2409
- <header class="settings-header">
2410
- <div>
2411
- <span class="eyebrow">Settings</span>
2412
- <h1>PI WEB</h1>
2413
- </div>
2414
- <button class="close-button" title="Close settings" aria-label="Close settings" @click=${()=>this.onClose?.()}>×</button>
2415
- </header>
2416
- <div class="settings-body">
2417
- <nav class="settings-nav" aria-label="Settings sections">
2418
- ${this.renderNavButton(`general`,`General`,`Gateway + selected machine`)}
2419
- ${this.renderNavButton(`sessiond`,`Session daemon`,`Selected machine`)}
2420
- ${this.renderNavButton(`packages`,`Pi packages`,`Selected machine`)}
2421
- ${this.renderNavButton(`plugins`,`PI WEB plugins`,`Selected machine`)}
2422
- ${this.renderNavButton(`shortcuts`,`Keyboard`,`Gateway shortcuts`)}
2423
- </nav>
2424
- <main class="settings-content">
2425
- ${this.renderActiveSection()}
2426
- </main>
2427
- </div>
2428
- </section>
2429
- </div>
2430
- `}renderActiveSection(){return this.section===`sessiond`?g`
2431
- <settings-sessiond-panel
2432
- .configResponse=${this.sessiondConfigResponse}
2433
- .loading=${this.sessiondLoading}
2434
- .saving=${this.saving}
2435
- .error=${this.sessiondError}
2436
- .savedMessage=${this.savedMessage}
2437
- .targetLabel=${X(this.settingsTarget())}
2438
- .activeAgentProfile=${this.machineRuntime?.components?.sessiond.activeAgentProfile}
2439
- .agentProfileSupport=${this.agentProfileSettingsSupport()}
2440
- .onReload=${()=>this.reloadSessiondState()}
2441
- .onSave=${e=>this.saveSessiondConfig(e)}
2442
- ></settings-sessiond-panel>
2443
- `:this.section===`shortcuts`?g`
2444
- <settings-shortcuts-panel
2445
- .actions=${this.actions}
2446
- .configResponse=${this.configResponse}
2447
- .loading=${this.loading}
2448
- .saving=${this.saving}
2449
- .error=${this.error}
2450
- .savedMessage=${this.savedMessage}
2451
- .onReload=${()=>this.loadConfig()}
2452
- .onSave=${e=>this.saveConfig(e)}
2453
- ></settings-shortcuts-panel>
2454
- `:this.section===`packages`?g`
2455
- <settings-packages-panel
2456
- .packagesResponse=${this.packagesResponse}
2457
- .targetMachine=${this.packageTarget()}
2458
- .managementSupport=${this.packageManagementSupport()}
2459
- .loading=${this.packageLoading}
2460
- .operation=${this.packageOperation}
2461
- .error=${this.packageError}
2462
- .operationMessage=${this.packageMessage}
2463
- .onReload=${()=>this.loadPackagesForTarget()}
2464
- .onInstallPackage=${e=>this.installPiPackage(e)}
2465
- .onRemovePackage=${(e,t)=>this.removePiPackage(e,t)}
2466
- .onUpdatePackage=${e=>this.updatePiPackage(e)}
2467
- ></settings-packages-panel>
2468
- `:this.section===`plugins`?g`
2469
- <settings-plugins-panel
2470
- .configResponse=${this.selectedPluginConfigResponse}
2471
- .pluginsResponse=${this.selectedPluginsResponse}
2472
- .loading=${this.pluginLoading}
2473
- .saving=${this.saving}
2474
- .error=${this.pluginError}
2475
- .savedMessage=${this.savedMessage}
2476
- .targetLabel=${X(this.settingsTarget())}
2477
- .onReload=${()=>this.loadPluginsForTarget()}
2478
- .onTogglePlugin=${(e,t)=>this.togglePlugin(e,t)}
2479
- ></settings-plugins-panel>
2480
- `:g`
2481
- <settings-general-panel
2482
- .configResponse=${this.configResponse}
2483
- .machineConfigResponse=${this.accessConfigResponse}
2484
- .loading=${this.loading}
2485
- .machineLoading=${this.accessLoading}
2486
- .saving=${this.saving}
2487
- .error=${this.error}
2488
- .machineError=${this.accessError}
2489
- .savedMessage=${this.savedMessage}
2490
- .targetLabel=${X(this.settingsTarget())}
2491
- .onReload=${()=>this.loadConfig()}
2492
- .onReloadMachine=${()=>this.loadAccessConfigForTarget()}
2493
- .onSave=${e=>this.saveConfig(e)}
2494
- .onSaveMachineConfig=${e=>this.saveMachineAccessConfig(e)}
2495
- ></settings-general-panel>
2496
- `}renderNavButton(e,t,n){let r=this.section===e;return g`
2497
- <button class=${r?`selected`:``} aria-current=${r?`page`:`false`} @click=${()=>{this.navigate(e)}}>
2498
- <strong>${t}</strong>
2499
- <small>${n}</small>
2500
- </button>
2501
- `}navigate(e){this.onNavigate?.(e)}async loadConfig(){let e=++this.loadRequestSeq;this.loading=!0,this.error=``;try{let t=await kb({loadConfig:()=>yi.config(),loadPlugins:()=>bi.plugins()});if(!this.isCurrentLoad(e))return;t.config!==void 0&&(this.configResponse=t.config),t.plugins!==void 0&&(this.pluginsResponse=t.plugins),this.error=t.error}finally{this.isCurrentLoad(e)&&(this.loading=!1)}}async loadAccessConfigForTarget(e=this.settingsTarget()){let t=++this.accessLoadRequestSeq,n=this.selectedMachineSettingsSupport(e);if(Rb(n)){this.accessConfigResponse=void 0,this.accessLoading=!1,this.accessError=n.message??`Selected-machine settings are not available on ${X(e)}.`;return}this.accessLoading=!0,this.accessError=``;try{let n=await yi.config(e.id);if(!this.isCurrentAccessLoad(t,e))return;this.accessConfigResponse=n}catch(n){this.isCurrentAccessLoad(t,e)&&(this.accessError=`Failed to load file access/upload config from ${X(e)}: ${Vb(Kb(n),e)}`)}finally{this.isCurrentAccessLoad(t,e)&&(this.accessLoading=!1)}}async reloadSessiondState(e=this.settingsTarget()){await Promise.all([this.loadSessiondConfigForTarget(e),this.onRefreshMachineRuntime?.(e.id)])}async loadSessiondConfigForTarget(e=this.settingsTarget()){let t=++this.sessiondLoadRequestSeq,n=this.selectedMachineSettingsSupport(e);if(Rb(n)){this.sessiondConfigResponse=void 0,this.sessiondLoading=!1,this.sessiondError=n.message??`Selected-machine settings are not available on ${X(e)}.`;return}this.sessiondLoading=!0,this.sessiondError=``;try{let n=await yi.config(e.id);if(!this.isCurrentSessiondLoad(t,e))return;this.sessiondConfigResponse=n}catch(n){this.isCurrentSessiondLoad(t,e)&&(this.sessiondError=`Failed to load session-daemon config from ${X(e)}: ${Vb(Kb(n),e)}`)}finally{this.isCurrentSessiondLoad(t,e)&&(this.sessiondLoading=!1)}}async loadPluginsForTarget(e=this.settingsTarget()){let t=++this.pluginLoadRequestSeq,n=this.selectedMachineSettingsSupport(e);if(Rb(n)){this.selectedPluginConfigResponse=void 0,this.selectedPluginsResponse=void 0,this.pluginLoading=!1,this.pluginError=n.message??`Selected-machine settings are not available on ${X(e)}.`;return}this.pluginLoading=!0,this.pluginError=``;try{let[n,r]=await Promise.allSettled([yi.config(e.id),bi.plugins(e.id)]);if(!this.isCurrentPluginLoad(t,e))return;let i=[];n.status===`fulfilled`?this.selectedPluginConfigResponse=n.value:i.push(`config: ${Vb(Kb(n.reason),e)}`),r.status===`fulfilled`?this.selectedPluginsResponse=r.value:i.push(`PI WEB plugins: ${Vb(Kb(r.reason),e)}`),this.pluginError=i.length===0?``:`Failed to load PI WEB plugin settings from ${X(e)}: ${i.join(`; `)}`}finally{this.isCurrentPluginLoad(t,e)&&(this.pluginLoading=!1)}}async loadPackagesForTarget(e=this.packageTarget()){let t=++this.packageLoadRequestSeq;this.packageLoading=!0,this.packageError=``,this.packageMessage=``;try{let n=await Ab(e,e=>Si.packages(e),this.packageManagementSupport(e));if(!this.isCurrentPackageLoad(t,e))return;this.packagesResponse=n.packagesResponse,this.packageError=n.error}finally{this.isCurrentPackageLoad(t,e)&&(this.packageLoading=!1)}}async togglePlugin(e,t){if(this.saving)return;let n=this.settingsTarget(),r=this.selectedMachineSettingsSupport(n);if(Rb(r)){this.pluginError=r.message??`Selected-machine settings are not available on ${X(n)}.`;return}if(this.selectedPluginConfigResponse===void 0){this.pluginError=`Plugin config is not loaded for ${X(n)}. Reload before changing plugin enablement.`;return}let i=Ub(this.selectedPluginConfigResponse.config,e,t);this.saving=!0,this.pluginError=``,this.savedMessage=``;try{let e=await yi.saveConfig(i,n.id);if(!this.isCurrentSettingsTarget(n))return;this.selectedPluginConfigResponse=e,n.kind===`local`&&this.configResponse!==void 0&&(this.configResponse=Wb(this.configResponse,e),this.onConfigSaved?.(this.configResponse.effectiveConfig));let t=await this.refreshPluginsForTarget(n);if(!this.isCurrentSettingsTarget(n))return;t!==void 0&&(this.pluginError=t),this.showSavedMessage()}catch(e){this.isCurrentSettingsTarget(n)&&(this.pluginError=`Failed to save PI WEB plugin config on ${X(n)}: ${Vb(Kb(e),n)}`)}finally{this.saving=!1}}async saveConfig(e){if(!this.saving){this.saving=!0,this.error=``,this.savedMessage=``;try{let t=await yi.saveConfig(e);this.configResponse=t,this.onConfigSaved?.(t.effectiveConfig),this.showSavedMessage()}catch(e){this.error=`Failed to save config: ${Kb(e)}`}finally{this.saving=!1}}}async saveMachineAccessConfig(e){if(this.saving)return;let t=this.settingsTarget(),n=this.selectedMachineSettingsSupport(t);if(Rb(n)){this.accessError=n.message??`Selected-machine settings are not available on ${X(t)}.`;return}this.saving=!0,this.accessError=``,this.savedMessage=``;try{let n=await yi.saveConfig(e,t.id);if(!this.isCurrentSettingsTarget(t))return;this.accessConfigResponse=n,t.kind===`local`&&this.configResponse!==void 0&&(this.configResponse=Mb(this.configResponse,n),this.onConfigSaved?.(this.configResponse.effectiveConfig)),this.showSavedMessage()}catch(e){this.isCurrentSettingsTarget(t)&&(this.accessError=`Failed to save file access/upload config on ${X(t)}: ${Vb(Kb(e),t)}`)}finally{this.saving=!1}}async saveSessiondConfig(e){if(this.saving)return;let t=this.settingsTarget(),n=this.selectedMachineSettingsSupport(t);if(Rb(n)){this.sessiondError=n.message??`Selected-machine settings are not available on ${X(t)}.`;return}if(e.agent!==void 0){let e=this.agentProfileSettingsSupport(t);if(!zb(e)){this.sessiondError=e.message??`Pi-compatible agent profile settings are not available on ${X(t)}.`;return}}this.saving=!0,this.sessiondError=``,this.savedMessage=``;try{let n=await yi.saveConfig(e,t.id);if(!this.isCurrentSettingsTarget(t))return;this.sessiondConfigResponse=n,t.kind===`local`&&this.configResponse!==void 0&&(this.configResponse=Iy(this.configResponse,n)),this.showSavedMessage()}catch(e){this.isCurrentSettingsTarget(t)&&(this.sessiondError=`Failed to save session-daemon config on ${X(t)}: ${Vb(Kb(e),t)}`)}finally{this.saving=!1}}async installPiPackage(e){let t=this.packageTarget();await this.runPiPackageMutation({kind:`install`,source:e},`install Pi package`,t,()=>Si.install(e,t.id))}async removePiPackage(e,t){let n=this.packageTarget();await this.runPiPackageMutation({kind:`remove`,source:e},`remove Pi package`,n,()=>Si.remove(e,t,n.id))}async updatePiPackage(e){let t=this.packageTarget();await this.runPiPackageMutation(e===void 0?{kind:`update-all`}:{kind:`update`,source:e},`update Pi packages`,t,()=>Si.update(e,t.id))}async runPiPackageMutation(e,t,n,r){let i=this.packageManagementSupport(n);if(Jy(i))throw this.packageError=i.message??`Pi package management is not available on ${Gy(n)}.`,Error(this.packageError);if(this.saving)throw Error(`A settings operation is already running.`);let a=++this.packageMutationSeq;this.packageLoadRequestSeq+=1,this.packageLoading=!1,this.saving=!0,this.packageOperation=e,this.packageError=``,this.packageMessage=``;try{let e=await r();if(!this.isCurrentPackageMutation(a,n))return;this.packagesResponse={packages:e.packages};let t=Xy(n)?await this.refreshGatewayPlugins():void 0;if(!this.isCurrentPackageMutation(a,n))return;t!==void 0&&(this.packageError=t),this.packageMessage=sb(e.action,n)}catch(e){throw this.isCurrentPackageMutation(a,n)&&(this.packageError=`Failed to ${t} on ${Gy(n)}: ${cb(Kb(e),n)}`),e}finally{this.packageMutationSeq===a&&(this.packageOperation=void 0,this.saving=!1)}}async refreshGatewayPlugins(){try{this.pluginsResponse=await bi.plugins();return}catch(e){return`Failed to refresh gateway PI WEB plugins: ${Kb(e)}`}}async refreshPluginsForTarget(e){try{let t=await bi.plugins(e.id);this.isCurrentSettingsTarget(e)&&(this.selectedPluginsResponse=t);return}catch(t){return`Config saved, but failed to refresh PI WEB plugins from ${X(e)}: ${Vb(Kb(t),e)}`}}settingsTarget(){return Pb(this.machine)}packageTarget(){return this.settingsTarget()}selectedMachineSettingsSupport(e=this.settingsTarget()){return Fb(e,this.machineRuntime)}agentProfileSettingsSupport(e=this.settingsTarget()){return Ib(e,this.machineRuntime)}selectedMachineSettingsSupportNeedsReload(e,t){let n=Fb(t,e),r=this.selectedMachineSettingsSupport(t);return Lb(n)!==Lb(r)}packageManagementSupport(e=this.packageTarget()){return Ky(e,this.machineRuntime)}packageManagementSupportNeedsReload(e,t){let n=Ky(t,e),r=this.packageManagementSupport(t);return qy(n)===qy(r)?!1:n.state===`unsupported`||r.state===`unsupported`}isCurrentLoad(e){return e===this.loadRequestSeq}isCurrentAccessLoad(e,t){return e===this.accessLoadRequestSeq&&this.isCurrentSettingsTarget(t)}isCurrentSessiondLoad(e,t){return e===this.sessiondLoadRequestSeq&&this.isCurrentSettingsTarget(t)}isCurrentPluginLoad(e,t){return e===this.pluginLoadRequestSeq&&this.isCurrentSettingsTarget(t)}isCurrentPackageLoad(e,t){return e===this.packageLoadRequestSeq&&this.isCurrentPackageTarget(t)}isCurrentPackageMutation(e,t){return e===this.packageMutationSeq&&this.isCurrentPackageTarget(t)}isCurrentPackageTarget(e){return this.packageTarget().id===e.id}isCurrentSettingsTarget(e){return this.settingsTarget().id===e.id}resetAccessStateForTargetChange(){this.accessLoadRequestSeq+=1,this.accessLoading=!1,this.accessError=``,this.accessConfigResponse=void 0,this.savedMessage=``}resetSessiondStateForTargetChange(){this.sessiondLoadRequestSeq+=1,this.sessiondLoading=!1,this.sessiondError=``,this.sessiondConfigResponse=void 0,this.savedMessage=``}resetPluginStateForTargetChange(){this.pluginLoadRequestSeq+=1,this.pluginLoading=!1,this.pluginError=``,this.selectedPluginConfigResponse=void 0,this.selectedPluginsResponse=void 0,this.savedMessage=``}resetPackageStateForTargetChange(){let e=this.packageOperation!==void 0;this.packageLoadRequestSeq+=1,this.packageMutationSeq+=1,this.packageLoading=!1,this.packageOperation=void 0,this.packageMessage=``,this.packageError=``,this.packagesResponse=void 0,e&&(this.saving=!1)}showSavedMessage(){this.savedMessage=`Config saved.`,this.savedMessageTimer!==void 0&&window.clearTimeout(this.savedMessageTimer),this.savedMessageTimer=window.setTimeout(()=>{this.savedMessage===`Config saved.`&&(this.savedMessage=``),this.savedMessageTimer=void 0},3e3)}handleKeyDown(e){e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),this.onClose?.())}static{this.styles=h`
2502
- :host { position: fixed; inset: 0; z-index: 30; color: var(--pi-text); font: 14px system-ui, sans-serif; }
2503
- .backdrop { box-sizing: border-box; width: 100%; height: 100dvh; display: grid; place-items: center; padding: max(20px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) max(20px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left)); background: var(--pi-overlay); overflow: hidden; }
2504
- .settings-shell { width: min(980px, 100%); max-height: min(760px, 100%); min-height: min(620px, 100%); display: grid; grid-template-rows: auto minmax(0, 1fr); border: 1px solid var(--pi-border); border-radius: 14px; background: var(--pi-bg); box-shadow: 0 20px 60px var(--pi-shadow-strong); overflow: hidden; }
2505
- .settings-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--pi-border); }
2506
- .eyebrow { display: block; color: var(--pi-muted); font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
2507
- h1 { margin: 0; font-size: 20px; line-height: 1.2; }
2508
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; font: inherit; cursor: pointer; }
2509
- .close-button { width: 34px; height: 34px; display: grid; place-items: center; border: 0; background: transparent; color: var(--pi-muted); padding: 0; font-size: 24px; }
2510
- .close-button:hover, .close-button:focus { color: var(--pi-text); background: var(--pi-surface-hover); }
2511
- .settings-body { min-height: 0; display: grid; grid-template-columns: 220px minmax(0, 1fr); }
2512
- .settings-nav { min-height: 0; padding: 10px; border-right: 1px solid var(--pi-border); background: var(--pi-surface); overflow: auto; }
2513
- .settings-nav button { display: grid; gap: 2px; width: 100%; margin: 0 0 6px; text-align: left; border-color: transparent; background: transparent; }
2514
- .settings-nav button:hover, .settings-nav button:focus { background: var(--pi-surface-hover); }
2515
- .settings-nav button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
2516
- .settings-nav small { color: var(--pi-muted); }
2517
- .settings-content { min-width: 0; min-height: 0; overflow: auto; padding: 18px; }
2518
-
2519
- @media (max-width: 760px) {
2520
- .backdrop { padding: 0; place-items: stretch; }
2521
- .settings-shell { width: 100%; height: 100dvh; max-height: none; min-height: 0; border: 0; border-radius: 0; }
2522
- .settings-header { padding: max(12px, env(safe-area-inset-top)) 12px 12px; }
2523
- .settings-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
2524
- .settings-nav { display: flex; gap: 8px; padding: 8px; border-right: 0; border-bottom: 1px solid var(--pi-border); overflow-x: auto; overflow-y: hidden; }
2525
- .settings-nav button { flex: 0 0 auto; width: auto; min-width: 128px; margin: 0; }
2526
- .settings-content { padding: 14px 12px calc(18px + env(safe-area-inset-bottom)); }
2527
- }
2528
- `}};R([b({attribute:!1})],Z.prototype,`section`,void 0),R([b({attribute:!1})],Z.prototype,`actions`,void 0),R([b({attribute:!1})],Z.prototype,`machine`,void 0),R([b({attribute:!1})],Z.prototype,`machineRuntime`,void 0),R([b({attribute:!1})],Z.prototype,`onNavigate`,void 0),R([b({attribute:!1})],Z.prototype,`onClose`,void 0),R([b({attribute:!1})],Z.prototype,`onConfigSaved`,void 0),R([b({attribute:!1})],Z.prototype,`onRefreshMachineRuntime`,void 0),R([x()],Z.prototype,`configResponse`,void 0),R([x()],Z.prototype,`accessConfigResponse`,void 0),R([x()],Z.prototype,`sessiondConfigResponse`,void 0),R([x()],Z.prototype,`pluginsResponse`,void 0),R([x()],Z.prototype,`selectedPluginConfigResponse`,void 0),R([x()],Z.prototype,`selectedPluginsResponse`,void 0),R([x()],Z.prototype,`packagesResponse`,void 0),R([x()],Z.prototype,`loading`,void 0),R([x()],Z.prototype,`accessLoading`,void 0),R([x()],Z.prototype,`sessiondLoading`,void 0),R([x()],Z.prototype,`pluginLoading`,void 0),R([x()],Z.prototype,`packageLoading`,void 0),R([x()],Z.prototype,`saving`,void 0),R([x()],Z.prototype,`packageOperation`,void 0),R([x()],Z.prototype,`error`,void 0),R([x()],Z.prototype,`accessError`,void 0),R([x()],Z.prototype,`sessiondError`,void 0),R([x()],Z.prototype,`pluginError`,void 0),R([x()],Z.prototype,`packageError`,void 0),R([x()],Z.prototype,`savedMessage`,void 0),R([x()],Z.prototype,`packageMessage`,void 0),Z=R([y(`settings-dialog`)],Z);function Kb(e){return e instanceof Error?e.message:String(e)}var qb=class extends v{constructor(...e){super(...e),this.tool=`core:workspace.files`,this.panels=[],this.hideToolTabs=!1,this.onSelectTool=()=>void 0,this.workspaceHeaderCanScrollLeft=!1,this.workspaceHeaderCanScrollRight=!1,this.onWorkspaceHeaderScroll=()=>{this.updateWorkspaceHeaderScrollState()}}firstUpdated(){this.observeWorkspaceHeaderStrip(),this.updateWorkspaceHeaderScrollState()}updated(){this.observeWorkspaceHeaderStrip(),this.updateWorkspaceHeaderScrollState()}disconnectedCallback(){this.workspaceHeaderResizeObserver?.disconnect(),this.workspaceHeaderResizeObserver=void 0,this.observedWorkspaceHeaderStrip=void 0,super.disconnectedCallback()}render(){if(this.workspace===void 0)return this.renderEmptyState(this.emptyState??{title:`Select a workspace`,body:`Choose a workspace to inspect files, Git, or terminals.`});let e=this.panelContext;if(e===void 0)return this.renderEmptyState({title:`Workspace tools unavailable`,body:`Try selecting the workspace again.`});let t=this.panels,n=t.find(e=>e.id===this.tool)??t[0];return g`
2529
- ${this.hideToolTabs?null:g`
2530
- <header>
2531
- <div class=${this.workspaceHeaderFrameClass()}>
2532
- <div class="workspace-header-strip" @scroll=${this.onWorkspaceHeaderScroll}>
2533
- <div class="tabs">
2534
- ${t.map(t=>{let r=n?.id===t.id,i=t.badge?.(e),a=this.panelTabAriaLabel(t,i);return g`
2535
- <button class=${this.panelTabClass(t,r)} title=${a} aria-label=${a} aria-pressed=${String(r)} @click=${()=>{this.onSelectTool(t.id)}}>
2536
- ${this.renderPanelTabContent(t,i)}
2537
- </button>
2538
- `})}
2539
- </div>
2540
- </div>
2541
- </div>
2542
- </header>
2543
- `}
2544
- ${n===void 0?this.renderEmptyState({title:`No workspace tools available`,body:`No tools are available for this workspace.`}):g`
2545
- <div class="panel-content">
2546
- ${n.render(e)}
2547
- </div>
2548
- `}
2549
- `}panelTabClass(e,t){return[...e.icon===void 0?[]:[`icon-tab`],...t?[`selected`]:[]].join(` `)}panelTabAriaLabel(e,t){if(typeof t!=`string`&&typeof t!=`number`)return e.title;let n=String(t).trim();return n===``?e.title:`${e.title}, ${n}`}renderPanelTabContent(e,t){return g`
2550
- ${e.icon===void 0?null:g`<span class="tab-custom-icon" aria-hidden="true">${e.icon}</span>`}
2551
- <span class="tab-label">${e.title}</span>
2552
- ${this.isEmptyBadge(t)?null:g`<span class="tab-badge">${t}</span>`}
2553
- `}isEmptyBadge(e){return e===void 0||e===``}renderEmptyState(e){return g`
2554
- <section class="empty-state" role="status">
2555
- <h2>${e.title}</h2>
2556
- ${e.body===void 0?null:g`<p>${e.body}</p>`}
2557
- </section>
2558
- `}workspaceHeaderFrameClass(){return`workspace-header-scroll-frame${this.workspaceHeaderCanScrollLeft?` can-scroll-left`:``}${this.workspaceHeaderCanScrollRight?` can-scroll-right`:``}`}observeWorkspaceHeaderStrip(){let e=this.workspaceHeaderStripElement();this.observedWorkspaceHeaderStrip!==e&&(this.workspaceHeaderResizeObserver?.disconnect(),this.observedWorkspaceHeaderStrip=e,this.workspaceHeaderResizeObserver=void 0,!(e===void 0||typeof ResizeObserver>`u`)&&(this.workspaceHeaderResizeObserver=new ResizeObserver(()=>{this.updateWorkspaceHeaderScrollState()}),this.workspaceHeaderResizeObserver.observe(e)))}updateWorkspaceHeaderScrollState(){let e=this.workspaceHeaderStripElement(),t=e===void 0?0:Math.max(0,e.scrollWidth-e.clientWidth),n=e!==void 0&&e.scrollLeft>1,r=e!==void 0&&t-e.scrollLeft>1;this.workspaceHeaderCanScrollLeft!==n&&(this.workspaceHeaderCanScrollLeft=n),this.workspaceHeaderCanScrollRight!==r&&(this.workspaceHeaderCanScrollRight=r)}workspaceHeaderStripElement(){let e=this.workspaceHeaderStrip;return e instanceof HTMLElement?e:void 0}static{this.styles=Xu}};R([b({attribute:!1})],qb.prototype,`workspace`,void 0),R([b({attribute:!1})],qb.prototype,`panelContext`,void 0),R([b({attribute:!1})],qb.prototype,`emptyState`,void 0),R([b()],qb.prototype,`tool`,void 0),R([b({attribute:!1})],qb.prototype,`panels`,void 0),R([b({type:Boolean})],qb.prototype,`hideToolTabs`,void 0),R([b({attribute:!1})],qb.prototype,`onSelectTool`,void 0),R([S(`.workspace-header-strip`)],qb.prototype,`workspaceHeaderStrip`,void 0),R([x()],qb.prototype,`workspaceHeaderCanScrollLeft`,void 0),R([x()],qb.prototype,`workspaceHeaderCanScrollRight`,void 0),qb=R([y(`workspace-panel`)],qb);var Jb=class extends v{constructor(...e){super(...e),this.machines=[],this.canScrollLeft=!1,this.canScrollRight=!1,this.onContextScroll=()=>{this.updateScrollState()}}disconnectedCallback(){this.contextItemsResizeObserver?.disconnect(),this.contextItemsResizeObserver=void 0,this.observedContextItems=void 0,super.disconnectedCallback()}firstUpdated(){this.observeContextItems(),this.updateScrollState()}updated(){this.observeContextItems(),this.updateScrollState()}render(){let e=Yb(this.machines),t=Xb(this.machine),n=Qb(this.project),r=ex(this.workspace),i=nx(this.session);return g`
2559
- <nav class=${this.contextBarClass()} aria-label="Current location">
2560
- <span class="context-bar-label">Location</span>
2561
- <ol class="context-items" @scroll=${this.onContextScroll}>
2562
- ${e?g`
2563
- <li class="context-item">
2564
- <button type="button" class=${this.machine===void 0?`context-chip empty`:`context-chip`} title=${Zb(this.machine)} aria-label=${`Machine: ${t}. Open machine selection.`} @click=${()=>{this.onOpenSection?.(`machines`)}}>
2565
- <span class="context-kind">Machine</span>
2566
- <span class="context-value">${t}</span>
2567
- </button>
2568
- </li>
2569
- `:null}
2570
- <li class="context-item">
2571
- <button type="button" class=${this.project===void 0?`context-chip empty`:`context-chip`} title=${$b(this.project)} aria-label=${`Project: ${n}. Open project selection.`} @click=${()=>{this.onOpenSection?.(`projects`)}}>
2572
- <span class="context-kind">Project</span>
2573
- <span class="context-value">${n}</span>
2574
- </button>
2575
- </li>
2576
- <li class="context-item">
2577
- <button type="button" class=${this.workspace===void 0?`context-chip empty`:`context-chip`} title=${tx(this.workspace)} aria-label=${`Workspace: ${r}. Open workspace selection.`} @click=${()=>{this.onOpenSection?.(`workspaces`)}}>
2578
- <span class="context-kind">Workspace</span>
2579
- <span class="context-value">${r}</span>
2580
- </button>
2581
- </li>
2582
- <li class="context-item">
2583
- <button type="button" class=${this.session===void 0?`context-chip empty`:`context-chip`} title=${rx(this.session)} aria-label=${`Session: ${i}. Open session selection.`} @click=${()=>{this.onOpenSection?.(`sessions`)}}>
2584
- <span class="context-kind">Session</span>
2585
- <span class="context-value">${i}</span>
2586
- </button>
2587
- </li>
2588
- </ol>
2589
- ${this.hasContextActions()?g`<div class="context-actions">${this.renderActionsButton()}${this.refreshControl}</div>`:null}
2590
- </nav>
2591
- `}renderActionsButton(){return this.onShowActions===void 0?null:g`
2592
- <button type="button" class="context-action-button" title="Show Actions" aria-label="Show Actions" @click=${e=>{e.stopPropagation(),this.onShowActions?.()}}>
2593
- <svg class="context-action-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
2594
- <path d="M13 2 4 14h7l-1 8 10-13h-7V2Z"></path>
2595
- </svg>
2596
- </button>
2597
- `}contextBarClass(){let e=[`context-bar`];return this.hasContextActions()&&e.push(`has-context-actions`),this.refreshControl!==void 0&&this.onShowActions!==void 0&&e.push(`has-context-actions-double`),this.canScrollLeft&&e.push(`can-scroll-left`),this.canScrollRight&&e.push(`can-scroll-right`),e.join(` `)}hasContextActions(){return this.refreshControl!==void 0||this.onShowActions!==void 0}observeContextItems(){let e=this.contextItemsElement();this.observedContextItems!==e&&(this.contextItemsResizeObserver?.disconnect(),this.observedContextItems=e,this.contextItemsResizeObserver=void 0,!(e===void 0||typeof ResizeObserver>`u`)&&(this.contextItemsResizeObserver=new ResizeObserver(()=>{this.updateScrollState()}),this.contextItemsResizeObserver.observe(e)))}updateScrollState(){let e=this.contextItemsElement(),t=e===void 0?0:Math.max(0,e.scrollWidth-e.clientWidth),n=e!==void 0&&e.scrollLeft>1,r=e!==void 0&&t-e.scrollLeft>1;this.canScrollLeft!==n&&(this.canScrollLeft=n),this.canScrollRight!==r&&(this.canScrollRight=r)}contextItemsElement(){let e=this.contextItems;return e instanceof HTMLElement?e:void 0}static{this.styles=h`
2598
- /* Keep the refresh menu in this shadow tree above the following mobile tab strip. */
2599
- :host { position: relative; z-index: 20; flex: 0 0 auto; min-width: 0; }
2600
- .context-bar { position: relative; flex: 0 0 auto; min-width: 0; display: flex; align-items: center; gap: 0; padding: 6px 0; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-bg); }
2601
- .context-bar::before, .context-bar::after { content: ""; position: absolute; top: 0; bottom: 0; z-index: 2; width: 20px; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
2602
- .context-bar::before { left: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
2603
- .context-bar::after { right: 0; background: linear-gradient(270deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
2604
- .context-bar.can-scroll-left::before, .context-bar.can-scroll-right::after { opacity: 1; }
2605
- .context-bar-label { display: none; }
2606
- .context-items { flex: 1 1 auto; min-width: 0; display: flex; align-items: stretch; gap: 5px; margin: 0; padding: 0 8px; list-style: none; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scroll-padding-inline: 8px; scrollbar-width: thin; }
2607
- .context-bar.has-context-actions .context-items { padding-right: 58px; scroll-padding-inline: 8px 58px; }
2608
- .context-bar.has-context-actions-double .context-items { padding-right: 102px; scroll-padding-inline: 8px 102px; }
2609
- .context-item { flex: 0 0 auto; min-width: 0; display: flex; }
2610
- .context-actions { position: absolute; top: 6px; right: 0; bottom: 6px; z-index: 3; display: flex; align-items: center; gap: 6px; padding: 0 8px; background: var(--pi-bg); pointer-events: none; }
2611
- .context-actions::before { content: ""; position: absolute; top: 0; bottom: 0; left: -24px; z-index: 0; width: 24px; background: linear-gradient(90deg, transparent, var(--pi-bg)); pointer-events: none; }
2612
- app-refresh-control, .context-action-button { position: relative; z-index: 1; pointer-events: auto; }
2613
- .context-action-button { box-sizing: border-box; width: 36px; height: 36px; display: grid; place-items: center; border: 1px solid var(--pi-border); border-radius: 999px; background: var(--pi-surface); color: var(--pi-text); padding: 0; line-height: 1; }
2614
- .context-action-button:hover, .context-action-button:focus-visible { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
2615
- .context-action-icon { width: 18px; height: 18px; fill: currentColor; pointer-events: none; }
2616
- .context-chip { flex: 0 0 auto; min-width: 0; display: inline-flex; align-items: baseline; gap: 5px; border: 1px solid var(--pi-border-muted); border-radius: 999px; background: var(--pi-surface); color: var(--pi-text); padding: 4px 8px; font: inherit; text-align: left; }
2617
- .context-chip:hover { background: var(--pi-surface-hover); }
2618
- .context-chip:focus-visible { outline: 2px solid var(--pi-accent); outline-offset: 2px; }
2619
- .context-chip.empty { border-style: dashed; color: var(--pi-muted); }
2620
- .context-kind { display: none; }
2621
- .context-value { min-width: 0; overflow: visible; text-overflow: clip; white-space: nowrap; }
2622
- button { cursor: pointer; }
2623
- `}};R([b({attribute:!1})],Jb.prototype,`machines`,void 0),R([b({attribute:!1})],Jb.prototype,`machine`,void 0),R([b({attribute:!1})],Jb.prototype,`project`,void 0),R([b({attribute:!1})],Jb.prototype,`workspace`,void 0),R([b({attribute:!1})],Jb.prototype,`session`,void 0),R([b({attribute:!1})],Jb.prototype,`refreshControl`,void 0),R([b({attribute:!1})],Jb.prototype,`onOpenSection`,void 0),R([b({attribute:!1})],Jb.prototype,`onShowActions`,void 0),R([S(`.context-items`)],Jb.prototype,`contextItems`,void 0),R([x()],Jb.prototype,`canScrollLeft`,void 0),R([x()],Jb.prototype,`canScrollRight`,void 0),Jb=R([y(`app-context-bar`)],Jb);function Yb(e){return e.length>1}function Xb(e){return e===void 0?`No machine`:`${e.name}${e.kind===`remote`?` · remote`:``}`}function Zb(e){return e===void 0?`No machine selected`:e.baseUrl??e.name}function Qb(e){return e?.name??`No project`}function $b(e){return e===void 0?`No project selected`:`${e.name} — ${e.path}`}function ex(e){return e===void 0?`No workspace`:`${e.label}${e.isMain?` · main`:``} · ${e.path}`}function tx(e){return e===void 0?`No workspace selected`:`${e.label}${e.isMain?` · main`:``} — ${e.path}`}function nx(e){let t=e?.name?.trim(),n=e?.firstMessage.trim();return t!==void 0&&t!==``?t:n!==void 0&&n!==``?n:e===void 0?`No session`:om(e.id)}function rx(e){return e===void 0?`No session selected`:e.path}var ix=class extends v{constructor(...e){super(...e),this.tabs=[],this.selectedView=`chat`,this.canScrollLeft=!1,this.canScrollRight=!1,this.onMobileTabsScroll=()=>{this.updateScrollState()}}disconnectedCallback(){this.mobileTabsResizeObserver?.disconnect(),this.mobileTabsResizeObserver=void 0,this.observedMobileTabs=void 0,super.disconnectedCallback()}firstUpdated(){this.observeMobileTabs(),this.updateScrollState()}updated(){this.observeMobileTabs(),this.updateScrollState()}render(){let e=this.fallbackLabels();return g`
2624
- <div class=${this.frameClass()}>
2625
- <div class="mobile-tabs" @scroll=${this.onMobileTabsScroll}>
2626
- ${this.tabs.map(t=>{let n=this.selectedView===t.id;return g`
2627
- <button class=${this.tabClass(t)} title=${t.label} aria-label=${this.tabAriaLabel(t)} aria-pressed=${String(n)} @click=${()=>{this.onSelect?.(t.id)}}>
2628
- ${this.renderTabMark(t,e)}
2629
- <span class="tab-label">${t.label}</span>
2630
- ${this.isEmptyBadge(t.badge)?null:g`<span class="tab-badge">${t.badge}</span>`}
2631
- </button>
2632
- `})}
2633
- </div>
2634
- </div>
2635
- `}frameClass(){return`mobile-tabs-frame${this.canScrollLeft?` can-scroll-left`:``}${this.canScrollRight?` can-scroll-right`:``}`}tabClass(e){return[...e.className===void 0?[]:[e.className],...this.selectedView===e.id?[`selected`]:[]].join(` `)}tabAriaLabel(e){if(typeof e.badge!=`string`&&typeof e.badge!=`number`)return e.label;let t=String(e.badge).trim();return t===``?e.label:`${e.label}, ${t}`}isEmptyBadge(e){return e===void 0||e===``}renderTabMark(e,t){return e.icon===void 0?g`<span class="tab-fallback" aria-hidden="true">${t.get(e.id)??this.initialsLabel(e.label)}</span>`:Ku(e.icon)}fallbackLabels(){let e=this.tabs.filter(e=>e.icon===void 0),t=new Map;for(let n of e){let e=this.initialsLabel(n.label);t.set(e,(t.get(e)??0)+1)}let n=new Map;for(let r of e){let e=this.initialsLabel(r.label);n.set(r.id,(t.get(e)??0)>1?this.fullFallbackLabel(r.label):e)}return n}initialsLabel(e){let t=(e.match(/[\p{L}\p{N}]+/gu)??[]).map(e=>Array.from(e)[0]??``).join(``).toLocaleUpperCase();return t===``?`?`:t}fullFallbackLabel(e){let t=e.trim();return t===``?`?`:t}observeMobileTabs(){let e=this.mobileTabsElement();this.observedMobileTabs!==e&&(this.mobileTabsResizeObserver?.disconnect(),this.observedMobileTabs=e,this.mobileTabsResizeObserver=void 0,!(e===void 0||typeof ResizeObserver>`u`)&&(this.mobileTabsResizeObserver=new ResizeObserver(()=>{this.updateScrollState()}),this.mobileTabsResizeObserver.observe(e)))}updateScrollState(){let e=this.mobileTabsElement(),t=e===void 0?0:Math.max(0,e.scrollWidth-e.clientWidth),n=e!==void 0&&e.scrollLeft>1,r=e!==void 0&&t-e.scrollLeft>1;this.canScrollLeft!==n&&(this.canScrollLeft=n),this.canScrollRight!==r&&(this.canScrollRight=r)}mobileTabsElement(){let e=this.mobileTabs;return e instanceof HTMLElement?e:void 0}static{this.styles=h`
2636
- :host { flex: 0 0 auto; min-width: 0; }
2637
- .mobile-tabs-frame { position: relative; display: flex; flex: 0 0 auto; min-width: 0; border-bottom: 1px solid var(--pi-border); background: var(--pi-bg); }
2638
- .mobile-tabs-frame::before, .mobile-tabs-frame::after { content: ""; position: absolute; top: 0; bottom: 0; z-index: 2; width: 20px; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
2639
- .mobile-tabs-frame::before { left: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
2640
- .mobile-tabs-frame::after { right: 0; background: linear-gradient(270deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
2641
- .mobile-tabs-frame.can-scroll-left::before, .mobile-tabs-frame.can-scroll-right::after { opacity: 1; }
2642
- .mobile-tabs { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; padding: 8px; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: thin; }
2643
- .mobile-tabs button { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
2644
- .mobile-tabs .navigation-tab { display: none; }
2645
- .mobile-tabs button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
2646
- .tab-icon { flex: 0 0 auto; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
2647
- .tab-custom-icon { flex: 0 0 auto; width: 18px; height: 18px; display: inline-grid; place-items: center; color: currentColor; pointer-events: none; }
2648
- .tab-custom-icon svg { width: 18px; height: 18px; pointer-events: none; }
2649
- .tab-fallback { display: none; font-weight: 650; letter-spacing: .01em; pointer-events: none; }
2650
- .tab-label { min-width: 0; }
2651
- .tab-badge { flex: 0 0 auto; display: inline-block; min-width: 14px; margin-left: 0; border: 1px solid var(--pi-success-border); border-radius: 999px; background: var(--pi-success-surface); color: var(--pi-success); padding: 0 5px; font-size: 11px; line-height: 16px; text-align: center; }
2652
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
2653
- @media (max-width: 760px) {
2654
- .mobile-tabs { gap: 4px; padding: 6px 8px; }
2655
- .mobile-tabs button { min-width: 40px; height: 36px; justify-content: center; gap: 4px; padding: 0 8px; }
2656
- .mobile-tabs .navigation-tab { display: inline-flex; }
2657
- .tab-fallback { display: inline-block; }
2658
- .tab-label { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
2659
- .tab-badge { min-width: 13px; padding: 0 4px; font-size: 10px; line-height: 13px; }
2660
- }
2661
- `}};R([b({attribute:!1})],ix.prototype,`tabs`,void 0),R([b({attribute:!1})],ix.prototype,`selectedView`,void 0),R([b({attribute:!1})],ix.prototype,`onSelect`,void 0),R([S(`.mobile-tabs`)],ix.prototype,`mobileTabs`,void 0),R([x()],ix.prototype,`canScrollLeft`,void 0),R([x()],ix.prototype,`canScrollRight`,void 0),ix=R([y(`app-mobile-main-tabs`)],ix);var ax=class extends v{constructor(...e){super(...e),this.machines=[],this.statuses={},this.activities={},this.open=!1,this.menuStyle=``,this.actionMenuStyle=``,this.onDocumentClick=e=>{e.composedPath().includes(this)||(this.open=!1,this.openActionsMachineId=void 0)}}connectedCallback(){super.connectedCallback(),document.addEventListener(`click`,this.onDocumentClick)}disconnectedCallback(){document.removeEventListener(`click`,this.onDocumentClick),super.disconnectedCallback()}updated(e){e.has(`machines`)&&this.open&&this.selectedMachine()===void 0&&(this.open=!1),e.has(`machines`)&&this.openActionsMachineId!==void 0&&!this.machines.some(e=>e.id===this.openActionsMachineId)&&(this.openActionsMachineId=void 0)}async focusSelectedOrFirst(){let e=this.switcherButton();return e!==null&&await this.openMenuAndFocusOption(e)}render(){let e=this.selectedMachine();if(e===void 0)return null;let t=ox(e,this.statuses),n=e.name;return g`
2662
- <div class="machine-switcher">
2663
- <button
2664
- type="button"
2665
- class="machine-switcher-button"
2666
- title=${cx(e)}
2667
- aria-label=${`Machine: ${n}. Switch machine.`}
2668
- aria-expanded=${String(this.open)}
2669
- @click=${e=>{this.toggleMenu(e.currentTarget)}}
2670
- @keydown=${e=>{this.handleSwitcherButtonKeydown(e)}}
2671
- >
2672
- ${this.renderActivity(e)}
2673
- <span class="machine-switcher-text">
2674
- <span class="machine-switcher-kicker">Machine</span>
2675
- <span class="machine-switcher-label">${n}</span>
2676
- </span>
2677
- <span class=${`machine-status ${t}`}>${sx(t)}</span>
2678
- <span class="machine-chevron" aria-hidden="true">▾</span>
2679
- </button>
2680
- ${this.open?g`
2681
- <div class="machine-switcher-menu" style=${this.menuStyle} @click=${e=>{e.stopPropagation()}}>
2682
- ${this.machines.map(e=>this.renderMachineOption(e))}
2683
- </div>
2684
- `:null}
2685
- </div>
2686
- `}renderMachineOption(e){let t=this.selected?.id===e.id,n=ox(e,this.statuses),r=Qp(e)&&this.onRemove!==void 0,i=this.openActionsMachineId===e.id;return g`
2687
- <div class=${`machine-option ${t?`selected`:``} ${r?``:`no-actions`}`}>
2688
- <button
2689
- type="button"
2690
- class="machine-option-main"
2691
- title=${cx(e)}
2692
- data-machine-id=${e.id}
2693
- @click=${()=>{this.select(e)}}
2694
- @keydown=${e=>{this.handleMachineOptionKeydown(e)}}
2695
- >
2696
- <span class="machine-option-name">${this.renderActivity(e)}<span>${e.name}</span></span>
2697
- <small>${e.kind===`local`?`Local Pi Web`:e.baseUrl??`Remote Pi Web`} · ${sx(n)}</small>
2698
- </button>
2699
- ${r?g`
2700
- <div class="machine-option-actions">
2701
- <button
2702
- type="button"
2703
- class="machine-option-actions-toggle"
2704
- title="Machine actions"
2705
- aria-label=${`Actions for ${e.name}`}
2706
- aria-expanded=${String(i)}
2707
- @click=${t=>{t.stopPropagation(),this.toggleActionsMenu(e.id,t.currentTarget)}}
2708
- >⋯</button>
2709
- ${i?g`
2710
- <div class="machine-option-actions-panel" style=${this.actionMenuStyle} @click=${e=>{e.stopPropagation()}}>
2711
- <button class="danger" title=${`Remove ${e.name}`} @click=${()=>{this.removeMachine(e)}}>Remove</button>
2712
- </div>
2713
- `:null}
2714
- </div>
2715
- `:null}
2716
- </div>
2717
- `}renderActivity(e){let t=ox(e,this.statuses);if(t===`offline`||t===`error`)return;let n=Op(this.activities[e.id]);return Lp(n,n===`terminal`?`Machine terminal active`:`Machine active`)}selectedMachine(){return this.selected??this.machines.find(e=>e.id===`local`)??this.machines[0]}switcherButton(){return this.renderRoot.querySelector(`.machine-switcher-button`)}handleSwitcherButtonKeydown(e){if(e.key===`ArrowDown`||e.key===`ArrowUp`){e.preventDefault(),e.stopPropagation(),this.openMenuAndFocusOption(e.currentTarget);return}if(e.key===`ArrowRight`&&this.onFocusNextSection!==void 0){e.preventDefault(),e.stopPropagation(),this.onFocusNextSection();return}e.key===`Escape`&&this.onCancelKeyboardNavigation!==void 0&&(e.preventDefault(),e.stopPropagation(),this.onCancelKeyboardNavigation())}handleMachineOptionKeydown(e){if(e.key===`ArrowUp`){this.focusRelativeMachineOption(e.currentTarget,-1,e);return}if(e.key===`ArrowDown`){this.focusRelativeMachineOption(e.currentTarget,1,e);return}if(e.key===`Home`){this.focusIndexedMachineOption(0,e);return}if(e.key===`End`){this.focusIndexedMachineOption(-1,e);return}if(e.key===`ArrowRight`&&this.onFocusNextSection!==void 0){e.preventDefault(),e.stopPropagation(),this.open=!1,this.onFocusNextSection();return}(e.key===`ArrowLeft`||e.key===`Escape`)&&(e.preventDefault(),e.stopPropagation(),this.open=!1,this.updateComplete.then(()=>{this.focusSwitcherButton()}))}toggleMenu(e){this.menuStyle=lx(e),this.open=!this.open,this.openActionsMachineId=void 0}focusSwitcherButton(){let e=this.switcherButton();return e===null?!1:(e.focus(),!0)}async openMenuAndFocusOption(e){return this.menuStyle=lx(e),this.open=!0,this.openActionsMachineId=void 0,await this.updateComplete,this.focusSelectedMachineOption()}focusSelectedMachineOption(){let e=this.renderRoot.querySelector(`.machine-option.selected .machine-option-main`),t=this.machineOptionButtons()[0],n=e??t;return n===void 0?!1:(n.focus(),n.scrollIntoView({block:`nearest`}),!0)}focusRelativeMachineOption(e,t,n){n.preventDefault(),n.stopPropagation();let r=this.machineOptionButtons();if(r.length===0||!(e instanceof HTMLElement))return;let i=r.indexOf(e);i<0||this.focusMachineOptionAt(i+t)}focusIndexedMachineOption(e,t){t.preventDefault(),t.stopPropagation(),this.focusMachineOptionAt(e<0?this.machineOptionButtons().length-1:e)}focusMachineOptionAt(e){let t=this.machineOptionButtons(),n=t[Math.min(Math.max(e,0),t.length-1)];n?.focus(),n?.scrollIntoView({block:`nearest`})}machineOptionButtons(){return Array.from(this.renderRoot.querySelectorAll(`.machine-option-main`))}toggleActionsMenu(e,t){if(this.openActionsMachineId===e){this.openActionsMachineId=void 0;return}this.actionMenuStyle=Np(t,{constrainTo:`viewport`}),this.openActionsMachineId=e}select(e){this.open=!1,this.openActionsMachineId=void 0,this.onSelect?.(e)}removeMachine(e){this.open=!1,this.openActionsMachineId=void 0,this.onRemove?.(e)}static{this.styles=h`
2718
- :host { min-width: 0; display: block; }
2719
- .machine-switcher { min-width: 0; }
2720
- .machine-switcher-button { box-sizing: border-box; width: 100%; min-width: 0; display: flex; align-items: center; gap: 6px; border: 1px solid var(--pi-border); border-radius: 999px; background: var(--pi-surface); color: var(--pi-text); padding: 5px 8px; cursor: pointer; text-align: left; }
2721
- .machine-switcher-button:hover, .machine-switcher-button:focus-visible { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
2722
- .machine-switcher-text { flex: 1 1 auto; min-width: 0; display: grid; gap: 1px; }
2723
- .machine-switcher-kicker { color: var(--pi-muted); font-size: 10px; line-height: 1; text-transform: uppercase; letter-spacing: .02em; }
2724
- .machine-switcher-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; font-weight: 600; line-height: 1.2; }
2725
- .machine-status { flex: 0 0 auto; color: var(--pi-muted); font-size: 11px; }
2726
- .machine-status.online { color: var(--pi-success); }
2727
- .machine-status.offline, .machine-status.error { color: var(--pi-danger); }
2728
- .machine-chevron { flex: 0 0 auto; color: var(--pi-muted); font-size: 11px; }
2729
- .activity-indicator { flex: 0 0 auto; display: inline-block; width: 7px; height: 7px; background: var(--pi-success); animation: pulse 1s ease-in-out infinite; }
2730
- .activity-indicator.session { border-radius: 50%; background: var(--pi-success); }
2731
- .activity-indicator.terminal { border-radius: 2px; background: var(--pi-accent); }
2732
- .activity-indicator.sending { border-radius: 50%; background: var(--pi-warning); }
2733
- .machine-switcher-menu { position: fixed; z-index: 10000; box-sizing: border-box; min-width: min(280px, calc(100vw - 16px)); overflow: auto; padding: 4px; border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); box-shadow: 0 8px 24px var(--pi-shadow); }
2734
- .machine-option { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px; align-items: stretch; margin: 2px 0; }
2735
- .machine-option.no-actions { grid-template-columns: minmax(0, 1fr); }
2736
- .machine-option-main, .machine-option-actions-toggle, .machine-option-actions-panel button { border: 0; border-radius: 7px; background: transparent; color: var(--pi-text); cursor: pointer; }
2737
- .machine-option-main { min-width: 0; display: grid; gap: 2px; padding: 7px 8px; text-align: left; }
2738
- .machine-option-name { min-width: 0; display: flex; align-items: baseline; gap: 6px; }
2739
- .machine-option-name span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2740
- .machine-option-main small { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--pi-muted); }
2741
- .machine-option-actions { position: relative; align-self: stretch; }
2742
- .machine-option-actions-toggle { display: grid; place-items: center; height: 100%; min-width: 32px; padding: 0; color: var(--pi-muted); }
2743
- .machine-option-actions-panel { position: fixed; z-index: 10001; box-sizing: border-box; min-width: min(120px, calc(100vw - 16px)); overflow: auto; padding: 4px; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); box-shadow: 0 8px 24px var(--pi-shadow); }
2744
- .machine-option-actions-panel button { display: block; width: 100%; padding: 7px 9px; text-align: left; white-space: nowrap; }
2745
- .machine-option-actions-panel button.danger { color: var(--pi-danger); }
2746
- .machine-option-main:hover, .machine-option-main:focus-visible, .machine-option-actions-toggle:hover, .machine-option-actions-toggle:focus-visible, .machine-option.selected .machine-option-main { background: var(--pi-selection-bg); }
2747
- .machine-option-actions-panel button:hover, .machine-option-actions-panel button:focus-visible { background: var(--pi-selection-bg); }
2748
- .machine-option-actions-panel button.danger:hover, .machine-option-actions-panel button.danger:focus-visible { background: color-mix(in srgb, var(--pi-danger) 14%, transparent); }
2749
- @keyframes pulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
2750
- `}};R([b({attribute:!1})],ax.prototype,`machines`,void 0),R([b({attribute:!1})],ax.prototype,`selected`,void 0),R([b({attribute:!1})],ax.prototype,`statuses`,void 0),R([b({attribute:!1})],ax.prototype,`activities`,void 0),R([b({attribute:!1})],ax.prototype,`onSelect`,void 0),R([b({attribute:!1})],ax.prototype,`onRemove`,void 0),R([b({attribute:!1})],ax.prototype,`onFocusNextSection`,void 0),R([b({attribute:!1})],ax.prototype,`onCancelKeyboardNavigation`,void 0),R([x()],ax.prototype,`open`,void 0),R([x()],ax.prototype,`menuStyle`,void 0),R([x()],ax.prototype,`openActionsMachineId`,void 0),R([x()],ax.prototype,`actionMenuStyle`,void 0),ax=R([y(`machine-switcher`)],ax);function ox(e,t){return t[e.id]?.status??e.status??`unknown`}function sx(e){return e===`online`?`online`:e===`offline`?`offline`:e===`error`?`error`:`unknown`}function cx(e){return e.baseUrl??e.name}function lx(e){if(typeof HTMLElement>`u`||typeof window>`u`||!(e instanceof HTMLElement))return``;let t=e.getBoundingClientRect(),n=Math.min(280,Math.max(0,window.innerWidth-16)),r=Math.min(Math.max(8,t.left),Math.max(8,window.innerWidth-8-n)),i=Math.max(0,window.innerHeight-t.bottom-8);return[`top: ${ux(t.bottom)};`,`left: ${ux(r)};`,`width: ${ux(n)};`,`max-height: ${ux(i)};`].join(` `)}function ux(e){return`${String(Math.round(e))}px`}var Q=class extends v{constructor(...e){super(...e),this.machines=[],this.machineStatuses={},this.machineActivities={},this.projects=[],this.workspaces=[],this.sessions=[],this.workspaceActivities={},this.sessionActivities={},this.sessionStatuses={},this.sendingPrompts={},this.workspacesByProjectId={},this.deletingWorkspaceIds=[],this.workspaceLabelItems=()=>[],this.collapsible=!1,this.compact=!1,this.machinesCollapsed=!1,this.projectsCollapsed=!1,this.workspacesCollapsed=!1,this.sessionsCollapsed=!1,this.startingSessionCount=0,this.canStartSession=!1,this.canDeleteArchivedSessions=!1,this.canReloadSessions=!1,this.canCleanupSessions=!1,this.authoritativeSessionPersistence=!1,this.archivedDeleteUnavailableMessage=`Update and restart Pi-Web on this machine to delete archived sessions.`,this.cleanupUnavailableMessage=`Update and restart Pi-Web on this machine to clean up sessions.`}async focusSection(e){switch(await this.updateComplete,e){case`machines`:return await this.focusNavigableSection(this.compact?this.machineList:this.machineSwitcher);case`projects`:return await this.focusNavigableSection(this.projectList);case`workspaces`:return await this.focusNavigableSection(this.workspaceList);case`sessions`:return await this.focusNavigableSection(this.sessionList)}}render(){return g`
2751
- <header>
2752
- <strong>PI WEB</strong>
2753
- ${dx(this.machines)?g`
2754
- <machine-switcher
2755
- .machines=${this.machines}
2756
- .selected=${this.selectedMachine}
2757
- .statuses=${this.machineStatuses}
2758
- .activities=${this.machineActivities}
2759
- .onSelect=${e=>this.onSelectMachine?.(e)}
2760
- .onRemove=${e=>this.onRemoveMachine?.(e)}
2761
- .onFocusNextSection=${()=>{this.focusNextFrom(`machines`)}}
2762
- .onCancelKeyboardNavigation=${()=>{this.cancelKeyboardNavigation()}}
2763
- ></machine-switcher>
2764
- `:null}
2765
- <div class="header-actions">
2766
- ${this.refreshControl}
2767
- <button title="Show Actions" aria-label="Show Actions" @click=${()=>{this.onShowActions?.()}}>Actions</button>
2768
- </div>
2769
- </header>
2770
- ${this.compact&&dx(this.machines)?g`
2771
- <machine-list
2772
- .machines=${this.machines}
2773
- .selected=${this.selectedMachine}
2774
- .statuses=${this.machineStatuses}
2775
- .activities=${this.machineActivities}
2776
- .collapsible=${this.collapsible}
2777
- .collapsed=${this.machinesCollapsed}
2778
- .onToggleCollapsed=${()=>{this.onToggleMachines?.()}}
2779
- .onSelect=${e=>this.onSelectMachine?.(e)}
2780
- .onRemove=${e=>this.onRemoveMachine?.(e)}
2781
- .onFocusNextSection=${()=>{this.focusNextFrom(`machines`)}}
2782
- .onCancelKeyboardNavigation=${()=>{this.cancelKeyboardNavigation()}}
2783
- ></machine-list>
2784
- `:null}
2785
- <project-list
2786
- .projects=${this.projects}
2787
- .selected=${this.selectedProject}
2788
- .activities=${this.workspaceActivities}
2789
- .workspacesByProjectId=${this.workspacesByProjectId}
2790
- .collapsible=${this.collapsible}
2791
- .collapsed=${this.projectsCollapsed}
2792
- .onToggleCollapsed=${()=>{this.onToggleProjects?.()}}
2793
- .onSelect=${e=>this.onSelectProject?.(e)}
2794
- .onClose=${e=>this.onCloseProject?.(e)}
2795
- .onFocusPreviousSection=${()=>{this.focusPreviousFrom(`projects`)}}
2796
- .onFocusNextSection=${()=>{this.focusNextFrom(`projects`)}}
2797
- .onCancelKeyboardNavigation=${()=>{this.cancelKeyboardNavigation()}}
2798
- ></project-list>
2799
- <workspace-list
2800
- .workspaces=${this.workspaces}
2801
- .selected=${this.selectedWorkspace}
2802
- .activities=${this.workspaceActivities}
2803
- .deletingWorkspaceIds=${this.deletingWorkspaceIds}
2804
- .collapsible=${this.collapsible}
2805
- .collapsed=${this.workspacesCollapsed}
2806
- .workspaceLabelItems=${this.workspaceLabelItems}
2807
- .onToggleCollapsed=${()=>{this.onToggleWorkspaces?.()}}
2808
- .onSelect=${e=>this.onSelectWorkspace?.(e)}
2809
- .onDelete=${e=>this.onDeleteWorkspace?.(e)}
2810
- .onFocusPreviousSection=${()=>{this.focusPreviousFrom(`workspaces`)}}
2811
- .onFocusNextSection=${()=>{this.focusNextFrom(`workspaces`)}}
2812
- .onCancelKeyboardNavigation=${()=>{this.cancelKeyboardNavigation()}}
2813
- ></workspace-list>
2814
- <session-list
2815
- .sessions=${this.sessions}
2816
- .statuses=${this.sessionStatuses}
2817
- .activities=${this.sessionActivities}
2818
- .sending=${this.sendingPrompts}
2819
- .selected=${this.selectedSession}
2820
- .startingCount=${this.startingSessionCount}
2821
- .canStart=${this.canStartSession}
2822
- .canDeleteArchived=${this.canDeleteArchivedSessions}
2823
- .canReload=${this.canReloadSessions}
2824
- .canCleanup=${this.canCleanupSessions}
2825
- .authoritativeSessionPersistence=${this.authoritativeSessionPersistence}
2826
- .archivedDeleteUnavailableMessage=${this.archivedDeleteUnavailableMessage}
2827
- .cleanupUnavailableMessage=${this.cleanupUnavailableMessage}
2828
- .collapsible=${this.collapsible}
2829
- .collapsed=${this.sessionsCollapsed}
2830
- .onToggleCollapsed=${()=>{this.onToggleSessions?.()}}
2831
- .onArchivedCollapsed=${()=>this.onArchivedCollapsed?.()}
2832
- .onStart=${()=>this.onStartSession?.()}
2833
- .onSelect=${e=>this.onSelectSession?.(e)}
2834
- .onArchive=${e=>this.onArchiveSession?.(e)}
2835
- .onArchiveWithDescendants=${e=>this.onArchiveSessionWithDescendants?.(e)}
2836
- .onArchiveMany=${e=>this.onArchiveSessions?.(e)}
2837
- .onRestore=${e=>this.onRestoreSession?.(e)}
2838
- .onDelete=${e=>this.onDeleteCachedNewSession?.(e)}
2839
- .onDeleteArchived=${e=>this.onDeleteArchivedSession?.(e)}
2840
- .onDeleteArchivedMany=${e=>this.onDeleteArchivedSessions?.(e)}
2841
- .onDetachParent=${e=>this.onDetachParentSession?.(e)}
2842
- .onReload=${e=>this.onReloadSession?.(e)}
2843
- .onCleanup=${()=>this.onCleanupSessions?.()}
2844
- .onFocusPreviousSection=${()=>{this.focusPreviousFrom(`sessions`)}}
2845
- .onFocusNextSection=${()=>{this.focusNextFrom(`sessions`)}}
2846
- .onCancelKeyboardNavigation=${()=>{this.cancelKeyboardNavigation()}}
2847
- ></session-list>
2848
- `}async focusNavigableSection(e){return e!==void 0&&await e.focusSelectedOrFirst()}focusPreviousFrom(e){let t=fx(e,this.machines);t!==void 0&&this.onFocusNavigationTarget?.(t)}focusNextFrom(e){this.onFocusNavigationTarget?.(px(e,this.machines))}cancelKeyboardNavigation(){this.onCancelKeyboardNavigation?.()}static{this.styles=h`
2849
- :host { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
2850
- :host([compact]) { flex: 1 1 auto; }
2851
- header { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px; border-bottom: 1px solid var(--pi-border); }
2852
- header strong { flex: 0 0 auto; }
2853
- machine-switcher { flex: 1 1 auto; min-width: 0; }
2854
- :host([compact]) header { display: none; }
2855
- .header-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
2856
- machine-list, project-list, workspace-list { flex: 0 0 auto; max-height: 26%; min-height: 0; overflow: hidden; border-bottom: 1px solid var(--pi-border-muted); }
2857
- session-list { flex: 1 1 auto; min-height: 0; overflow: hidden; }
2858
- machine-list[collapsed],
2859
- project-list[collapsed],
2860
- workspace-list[collapsed],
2861
- session-list[collapsed] { flex: 0 0 auto; min-height: auto; overflow: hidden; }
2862
- :host([compact]) machine-list,
2863
- :host([compact]) project-list,
2864
- :host([compact]) workspace-list,
2865
- :host([compact]) session-list { flex: 1 1 auto; max-height: none; min-height: 0; overflow: hidden; }
2866
- :host([compact]) machine-list[collapsed],
2867
- :host([compact]) project-list[collapsed],
2868
- :host([compact]) workspace-list[collapsed],
2869
- :host([compact]) session-list[collapsed] { flex: 0 0 auto; min-height: auto; overflow: hidden; }
2870
- button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
2871
- `}};R([b({attribute:!1})],Q.prototype,`machines`,void 0),R([b({attribute:!1})],Q.prototype,`selectedMachine`,void 0),R([b({attribute:!1})],Q.prototype,`machineStatuses`,void 0),R([b({attribute:!1})],Q.prototype,`machineActivities`,void 0),R([b({attribute:!1})],Q.prototype,`projects`,void 0),R([b({attribute:!1})],Q.prototype,`selectedProject`,void 0),R([b({attribute:!1})],Q.prototype,`workspaces`,void 0),R([b({attribute:!1})],Q.prototype,`selectedWorkspace`,void 0),R([b({attribute:!1})],Q.prototype,`sessions`,void 0),R([b({attribute:!1})],Q.prototype,`selectedSession`,void 0),R([b({attribute:!1})],Q.prototype,`workspaceActivities`,void 0),R([b({attribute:!1})],Q.prototype,`sessionActivities`,void 0),R([b({attribute:!1})],Q.prototype,`sessionStatuses`,void 0),R([b({attribute:!1})],Q.prototype,`sendingPrompts`,void 0),R([b({attribute:!1})],Q.prototype,`workspacesByProjectId`,void 0),R([b({attribute:!1})],Q.prototype,`deletingWorkspaceIds`,void 0),R([b({attribute:!1})],Q.prototype,`workspaceLabelItems`,void 0),R([b({attribute:!1})],Q.prototype,`refreshControl`,void 0),R([b({type:Boolean,reflect:!0})],Q.prototype,`collapsible`,void 0),R([b({type:Boolean,reflect:!0})],Q.prototype,`compact`,void 0),R([b({type:Boolean})],Q.prototype,`machinesCollapsed`,void 0),R([b({type:Boolean})],Q.prototype,`projectsCollapsed`,void 0),R([b({type:Boolean})],Q.prototype,`workspacesCollapsed`,void 0),R([b({type:Boolean})],Q.prototype,`sessionsCollapsed`,void 0),R([b({type:Number})],Q.prototype,`startingSessionCount`,void 0),R([b({type:Boolean})],Q.prototype,`canStartSession`,void 0),R([b({type:Boolean})],Q.prototype,`canDeleteArchivedSessions`,void 0),R([b({type:Boolean})],Q.prototype,`canReloadSessions`,void 0),R([b({type:Boolean})],Q.prototype,`canCleanupSessions`,void 0),R([b({type:Boolean})],Q.prototype,`authoritativeSessionPersistence`,void 0),R([b({type:String})],Q.prototype,`archivedDeleteUnavailableMessage`,void 0),R([b({type:String})],Q.prototype,`cleanupUnavailableMessage`,void 0),R([b({attribute:!1})],Q.prototype,`onShowActions`,void 0),R([b({attribute:!1})],Q.prototype,`onToggleMachines`,void 0),R([b({attribute:!1})],Q.prototype,`onToggleProjects`,void 0),R([b({attribute:!1})],Q.prototype,`onToggleWorkspaces`,void 0),R([b({attribute:!1})],Q.prototype,`onToggleSessions`,void 0),R([b({attribute:!1})],Q.prototype,`onSelectProject`,void 0),R([b({attribute:!1})],Q.prototype,`onCloseProject`,void 0),R([b({attribute:!1})],Q.prototype,`onSelectWorkspace`,void 0),R([b({attribute:!1})],Q.prototype,`onDeleteWorkspace`,void 0),R([b({attribute:!1})],Q.prototype,`onStartSession`,void 0),R([b({attribute:!1})],Q.prototype,`onSelectSession`,void 0),R([b({attribute:!1})],Q.prototype,`onArchiveSession`,void 0),R([b({attribute:!1})],Q.prototype,`onArchiveSessionWithDescendants`,void 0),R([b({attribute:!1})],Q.prototype,`onArchiveSessions`,void 0),R([b({attribute:!1})],Q.prototype,`onRestoreSession`,void 0),R([b({attribute:!1})],Q.prototype,`onDeleteCachedNewSession`,void 0),R([b({attribute:!1})],Q.prototype,`onDeleteArchivedSession`,void 0),R([b({attribute:!1})],Q.prototype,`onDeleteArchivedSessions`,void 0),R([b({attribute:!1})],Q.prototype,`onDetachParentSession`,void 0),R([b({attribute:!1})],Q.prototype,`onReloadSession`,void 0),R([b({attribute:!1})],Q.prototype,`onCleanupSessions`,void 0),R([b({attribute:!1})],Q.prototype,`onArchivedCollapsed`,void 0),R([b({attribute:!1})],Q.prototype,`onSelectMachine`,void 0),R([b({attribute:!1})],Q.prototype,`onRemoveMachine`,void 0),R([b({attribute:!1})],Q.prototype,`onFocusNavigationTarget`,void 0),R([b({attribute:!1})],Q.prototype,`onCancelKeyboardNavigation`,void 0),R([S(`machine-list`)],Q.prototype,`machineList`,void 0),R([S(`machine-switcher`)],Q.prototype,`machineSwitcher`,void 0),R([S(`project-list`)],Q.prototype,`projectList`,void 0),R([S(`workspace-list`)],Q.prototype,`workspaceList`,void 0),R([S(`session-list`)],Q.prototype,`sessionList`,void 0),Q=R([y(`app-navigation-panel`)],Q);function dx(e){return e.length>1}function fx(e,t){let n=mx(t);return n[n.indexOf(e)-1]}function px(e,t){let n=mx(t);return n[n.indexOf(e)+1]??`chat`}function mx(e){return jf.filter(t=>t!==`machines`||dx(e))}var hx=new Set([`ArrowLeft`,`ArrowRight`,`Home`,`End`]),gx=420,_x=4,$=class extends v{constructor(...e){super(...e),this.side=`navigation`,this.collapsed=!1,this.resizable=!1,this.controls=``,this.resizeLabel=`Resize panel`,this.expandLabel=`Expand panel`,this.collapseLabel=`Collapse panel`,this.lastTapAt=0}disconnectedCallback(){this.finishActiveResize(),super.disconnectedCallback()}render(){let e=this.collapsed?this.expandLabel:this.collapseLabel;return g`
2872
- ${this.renderResizeHandle()}
2873
- <button
2874
- type="button"
2875
- class="edge-button"
2876
- title=${e}
2877
- aria-label=${e}
2878
- aria-controls=${this.controls}
2879
- aria-expanded=${String(!this.collapsed)}
2880
- @click=${()=>{this.onToggle?.()}}
2881
- >${this.renderIcon()}</button>
2882
- `}renderResizeHandle(){if(!this.resizable)return _;let e=this.resizeConstraints();return g`
2883
- <div
2884
- class="resize-handle"
2885
- role="separator"
2886
- tabindex="0"
2887
- aria-label=${this.resizeLabel}
2888
- title=${`${this.resizeLabel}. Double-click or double-tap to reset.`}
2889
- aria-controls=${this.controls}
2890
- aria-orientation="vertical"
2891
- aria-valuemin=${String(e.minWidth)}
2892
- aria-valuemax=${String(e.maxWidth)}
2893
- aria-valuenow=${this.resizeAriaValueNow()}
2894
- @pointerdown=${e=>{this.onResizePointerDown(e)}}
2895
- @pointermove=${e=>{this.onResizePointerMove(e)}}
2896
- @pointerup=${e=>{this.onResizePointerUp(e)}}
2897
- @pointercancel=${e=>{this.onResizePointerCancel(e)}}
2898
- @dblclick=${e=>{this.onResizeDoubleClick(e)}}
2899
- @keydown=${e=>{this.onResizeKeyDown(e)}}
2900
- ></div>
2901
- `}resizeAriaValueNow(){return this.panelWidth===void 0?_:String(Math.round(this.panelWidth))}renderIcon(){return g`<svg class="edge-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d=${this.iconDirection()===`left`?`M15 18l-6-6 6-6`:`M9 18l6-6-6-6`}/></svg>`}iconDirection(){return this.side===`navigation`?this.collapsed?`right`:`left`:this.collapsed?`left`:`right`}onResizePointerDown(e){if(!this.resizable||e.button!==0)return;let t=e.currentTarget;if(!(t instanceof HTMLElement))return;let n=this.resizeStartWidth();n!==void 0&&(e.preventDefault(),e.stopPropagation(),t.setPointerCapture(e.pointerId),this.activeResize={pointerId:e.pointerId,startClientX:e.clientX,startWidth:n,handle:t,moved:!1},this.toggleAttribute(`resizing`,!0))}onResizePointerMove(e){let t=this.activeResize;t?.pointerId===e.pointerId&&(e.preventDefault(),!(Math.abs(e.clientX-t.startClientX)<=_x)&&(t.moved=!0,this.commitPanelWidth(Yf(this.side,t.startWidth,t.startClientX,e.clientX,this.resizeConstraints()))))}onResizePointerUp(e){let t=this.activeResize;t?.pointerId===e.pointerId&&(e.preventDefault(),this.finishActiveResize(),t.moved||this.registerTapForReset())}onResizePointerCancel(e){this.activeResize?.pointerId===e.pointerId&&this.finishActiveResize()}onResizeDoubleClick(e){e.preventDefault(),e.stopPropagation(),this.resetPanelSize()}onResizeKeyDown(e){if(!this.resizable||!hx.has(e.key))return;let t=this.resizeStartWidth();if(t===void 0)return;let n=Xf(this.side,t,e.key,{largeStep:e.shiftKey,constraints:this.resizeConstraints()});n!==void 0&&(e.preventDefault(),e.stopPropagation(),this.commitPanelWidth(n),this.onResizeEnd?.())}registerTapForReset(){let e=Date.now();if(e-this.lastTapAt<=gx){this.lastTapAt=0,this.resetPanelSize();return}this.lastTapAt=e}resetPanelSize(){this.finishActiveResize(),this.onReset?.()}resizeStartWidth(){let e=this.onResizeStart?.()??this.panelWidth;if(e!==void 0)return Zf(this.side,e,this.resizeConstraints())}commitPanelWidth(e){this.onResize?.(Zf(this.side,e,this.resizeConstraints()))}finishActiveResize(){let e=this.activeResize;if(e!==void 0){try{e.handle.releasePointerCapture(e.pointerId)}catch{}this.activeResize=void 0,this.toggleAttribute(`resizing`,!1),this.onResizeEnd?.()}}resizeConstraints(){let e=qf(this.side);return{...e,minWidth:this.minWidth??e.minWidth,maxWidth:this.maxWidth??e.maxWidth}}static{this.styles=h`
2902
- :host { position: relative; min-width: 0; min-height: 0; display: flex; align-items: center; justify-content: center; overflow: visible; background: var(--pi-border-muted); z-index: 2; }
2903
- :host([side="navigation"]) { grid-column: 2; }
2904
- :host([side="workspace"]) { grid-column: 4; }
2905
- .resize-handle { position: absolute; inset: 0 -6px; z-index: 0; cursor: col-resize; touch-action: none; outline: none; }
2906
- .resize-handle::after { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; transform: translateX(-50%); background: transparent; transition: width .12s ease, background .12s ease, opacity .12s ease; }
2907
- .resize-handle:hover::after, .resize-handle:focus-visible::after, :host([resizing]) .resize-handle::after { width: 3px; background: var(--pi-accent); opacity: .72; }
2908
- .edge-button { position: relative; z-index: 1; box-sizing: border-box; display: grid; place-items: center; width: 18px; height: 48px; padding: 0; border: 1px solid var(--pi-border-muted); border-radius: 999px; background: var(--pi-bg); color: var(--pi-muted); opacity: .75; cursor: pointer; }
2909
- .edge-button:hover, .edge-button:focus-visible { color: var(--pi-text); background: var(--pi-surface-hover); opacity: 1; }
2910
- :host([side="navigation"][collapsed]) .edge-button { transform: translateX(calc(50% - .5px)); }
2911
- :host([side="workspace"][collapsed]) .edge-button { transform: translateX(calc(-50% + .5px)); }
2912
- .edge-icon { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
2913
- @media (max-width: 1180px) {
2914
- :host([side="navigation"]) { grid-row: 1 / 3; }
2915
- :host([side="workspace"]) { display: none; }
2916
- }
2917
- @media (max-width: 760px) {
2918
- :host([side="navigation"]) { display: none; }
2919
- }
2920
- `}};R([b({reflect:!0})],$.prototype,`side`,void 0),R([b({type:Boolean,reflect:!0})],$.prototype,`collapsed`,void 0),R([b({type:Boolean})],$.prototype,`resizable`,void 0),R([b({type:Number})],$.prototype,`panelWidth`,void 0),R([b({type:Number})],$.prototype,`minWidth`,void 0),R([b({type:Number})],$.prototype,`maxWidth`,void 0),R([b()],$.prototype,`controls`,void 0),R([b()],$.prototype,`resizeLabel`,void 0),R([b()],$.prototype,`expandLabel`,void 0),R([b()],$.prototype,`collapseLabel`,void 0),R([b({attribute:!1})],$.prototype,`onToggle`,void 0),R([b({attribute:!1})],$.prototype,`onResizeStart`,void 0),R([b({attribute:!1})],$.prototype,`onResize`,void 0),R([b({attribute:!1})],$.prototype,`onResizeEnd`,void 0),R([b({attribute:!1})],$.prototype,`onReset`,void 0),$=R([y(`app-panel-edge-control`)],$);var vx=class extends v{constructor(...e){super(...e),this.onReloadClick=e=>{e.stopPropagation(),this.onReload?.()}}render(){let e=`Full page reload`;return g`
2921
- <button
2922
- class="app-refresh-button"
2923
- title=${e}
2924
- aria-label=${e}
2925
- @click=${this.onReloadClick}
2926
- >${this.renderRefreshIcon()}</button>
2927
- `}renderRefreshIcon(){return g`
2928
- <svg class="app-refresh-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
2929
- <path d="M20 6v5h-5"></path>
2930
- <path d="M4 18v-5h5"></path>
2931
- <path d="M18.2 9A7 7 0 0 0 6.1 6.8L4 9"></path>
2932
- <path d="M5.8 15a7 7 0 0 0 12.1 2.2L20 15"></path>
2933
- </svg>
2934
- `}static{this.styles=h`
2935
- :host { position: relative; z-index: 1; display: flex; align-items: center; pointer-events: auto; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
2936
- :host, :host * { -webkit-user-select: none; user-select: none; }
2937
- .app-refresh-button { box-sizing: border-box; width: 36px; height: 36px; display: grid; place-items: center; border: 1px solid var(--pi-border); border-radius: 999px; background: var(--pi-surface); color: var(--pi-text); padding: 0; line-height: 1; cursor: pointer; touch-action: manipulation; -webkit-touch-callout: none; }
2938
- .app-refresh-icon { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
2939
- `}};R([b({attribute:!1})],vx.prototype,`onReload`,void 0),vx=R([y(`app-refresh-control`)],vx);var yx=900*1e3,bx=750,xx=[1e3,3e3,8e3,15e3,3e4],Sx={capture:!0},Cx=`auto:on`,wx=`auto:off`,Tx=`theme:`,Ex=ya(`core:workspace.files`),Dx=ya(`core:workspace.git`),Ox=ya(`core:workspace.terminal`),kx=320,Ax=2,jx=`(min-width: 1181px)`,Mx=class extends v{constructor(...e){super(...e),this.state=sa(),this.sessions=new Pc(()=>this.state,e=>{this.setState(e)},()=>{this.updateUrl()},new wc),this.activity=new pa(()=>this.state,e=>{this.setState(e)}),this.auth=new ga(()=>this.state,e=>{this.setState(e)},e=>{this.sessions.applySessionStatus(e)}),this.workspaces=new sl(()=>this.state,e=>{this.setState(e)},()=>{this.updateUrl()},this.sessions,new al),this.projects=new Ha(()=>this.state,e=>{this.setState(e)},this.workspaces),this.machines=new za(()=>this.state,e=>{this.setState(e)},()=>{this.updateUrl()},this.projects),this.piWebStatusController=new Ua(()=>this.state,e=>{this.setState(e)},{onRefreshError:(e,t)=>{console.warn(`Failed to refresh PI WEB status for ${e}`,t)}}),this.files=new Ma(()=>this.state,e=>{this.setState(e)},()=>{this.updateUrl()}),this.git=new Ra(()=>this.state,e=>{this.setState(e)},()=>{this.updateUrl()}),this.keyboard=new kl,this.realtime=new ic,this.machineActivitySockets=new Map,this.activeTerminalIds=new Set,this.machineNavigation=new dl,this.terminalSelection=new wl,this.appShell=new wf(this),this.browserResume=new Ef({onResumeSignal:()=>{this.handleBrowserResumeSignal()},refreshAfterResume:()=>this.refreshAfterBrowserResume(),onRefreshError:e=>{console.warn(`Failed to refresh after browser resume`,e)}}),this.panelCollapse=new Hf(this),this.panelResize=new Kf(this),this.navigationSections=new zf(this,()=>this.state,()=>this.appShell.isMobileNavigationLayout),this.systemLightThemeMedia=typeof window<`u`&&`matchMedia`in window?window.matchMedia(`(prefers-color-scheme: light)`):void 0,this.refreshingWorkspaceDeletionRuns=!1,this.handledWorkspaceDeletionRunIds=new Set,this.terminalCommandRunRuntimes=new Map,this.machineNavigationRestoreSeq=0,this.navigationSelectionSeq=0,this.routeRestoreSeq=0,this.routeRestoreDepth=0,this.remoteRouteRestoreAttempt=0,this.remoteRouteRestoreInProgress=!1,this.plugins=Nx(),this.loadedMachinePluginIds=new Set,this.machinePluginLoadPromises=new Map,this.themePreference=_u()??pu,this.activeThemeId=fu,this.isRefreshingApp=!1,this.settingsSection=pp(),this.shortcutConfig={},this.workspaceUploadDefaultFolder=Vi(void 0),this.onPopState=()=>void this.withChatScrollTransition(async()=>{this.restoreSettingsRoute(),await this.restoreRoute(!1)}),this.onPageShow=()=>{this.appShell.repairViewportPosition(),this.retryPendingRemoteRouteRestoreSoon()},this.onSystemLightThemeChange=()=>{this.themePreference.auto&&this.applyPreferredTheme(!1)},this.onKeyDown=e=>{this.settingsSection===void 0&&this.keyboard.handle(e,this.getDefaultActions(),{shortcuts:this.shortcutConfig})&&(e.preventDefault(),e.stopPropagation())},this.handleSendPrompt=(e,t,n,r)=>{this.sendPrompt(e,t,n,r)},this.handleStopActiveWork=()=>{this.sessions.stopActiveWork()},this.handleClearServerQueue=()=>{this.sessions.clearServerQueue()},this.handleDismissWarning=e=>{this.sessions.dismissWarning(e)},this.handleSelectModel=()=>{this.openModelDialog()},this.handleSelectThinking=()=>{this.openThinkingDialog()}}get routeRestoreInProgress(){return this.routeRestoreDepth>0}willUpdate(){this.toggleAttribute(`pwa-display-mode`,this.appShell.isPwaDisplayMode)}connectedCallback(){super.connectedCallback(),window.addEventListener(`popstate`,this.onPopState),window.addEventListener(`pageshow`,this.onPageShow),this.browserResume.connect(),window.addEventListener(`keydown`,this.onKeyDown,Sx),this.systemLightThemeMedia?.addEventListener(`change`,this.onSystemLightThemeChange),this.applyPreferredTheme(!1),this.connectRealtime(),this.piWebStatusTimer=window.setInterval(()=>{this.schedulePiWebStatusRefresh()},yx),this.refreshWorkspaceActivity(),this.loadClientConfig(),this.ensureGatewayPluginsLoaded(),this.loadProjectsAndRestoreRoute().finally(()=>{this.schedulePiWebStatusRefresh()})}disconnectedCallback(){window.removeEventListener(`popstate`,this.onPopState),window.removeEventListener(`pageshow`,this.onPageShow),this.browserResume.disconnect(),window.removeEventListener(`keydown`,this.onKeyDown,Sx),this.systemLightThemeMedia?.removeEventListener(`change`,this.onSystemLightThemeChange),this.keyboard.reset(),this.auth.dispose(),this.sessions.dispose(),this.realtime.close(),this.closeMachineActivitySockets(),this.git.dispose(),this.piWebStatusTimer!==void 0&&window.clearInterval(this.piWebStatusTimer),this.piWebStatusTimer=void 0,this.clearScheduledPiWebStatusRefresh(),this.workspaceDeletionPollTimer!==void 0&&window.clearInterval(this.workspaceDeletionPollTimer),this.workspaceDeletionPollTimer=void 0,this.clearPendingRemoteRouteRestore(),super.disconnectedCallback()}setState(e){if(!Rx(this.state,e))return;let t=this.state;this.state={...this.state,...e},this.handleActivityTransition(t,this.state),this.handleWorkspaceChange(t,this.state),this.handleMachineChange(t,this.state),Fx(t,this.state)&&this.syncMachineActivitySubscriptions()}async loadProjectsAndRestoreRoute(){this.restoreSettingsRoute();let e=cp();await this.machines.loadMachines(e.machineId);let t=this.routeForSelectedMachine(e),n=this.state.machineStatuses[t.machineId??`local`];t!==e&&this.replaceRouteAndClearWorkspaceQuery(t),await this.projects.loadProjects(),await this.withChatScrollTransition(()=>this.restoreRouteFor(t,!1)),this.shouldDeferRemoteRouteRestore(t,n)?this.deferRemoteRouteRestore(t):(this.clearPendingRemoteRouteRestore(),this.rememberCurrentMachineNavigation()),await this.refreshWorkspaceDeletionRuns()}handleBrowserResumeSignal(){this.appShell.repairViewportPosition(),this.schedulePiWebStatusRefresh(),this.retryPendingRemoteRouteRestoreSoon()}async refreshAfterBrowserResume(){await Promise.all([this.sessions.refreshSelectedSession(),this.refreshMachineActivities(),this.refreshWorkspaceDeletionRuns()])}schedulePiWebStatusRefresh(e=bx){this.clearScheduledPiWebStatusRefresh(),this.piWebStatusDeferredTimer=window.setTimeout(()=>{this.piWebStatusDeferredTimer=void 0,this.piWebStatusController.refresh()},e)}clearScheduledPiWebStatusRefresh(){this.piWebStatusDeferredTimer!==void 0&&(window.clearTimeout(this.piWebStatusDeferredTimer),this.piWebStatusDeferredTimer=void 0)}async refreshWorkspaceActivity(e=I(this.state)){try{await this.activity.refresh(e)}catch(t){console.warn(`Failed to refresh workspace activity for ${e}`,t)}}async refreshMachineActivities(){let e=this.state.machines.length===0?[I(this.state)]:this.state.machines.filter(e=>Lx(e,this.state.machineStatuses[e.id])).map(e=>e.id);await Promise.all(e.map(e=>this.refreshWorkspaceActivity(e)))}async loadClientConfig(){try{this.applyClientConfig((await yi.config()).effectiveConfig)}catch(e){console.warn(`Failed to load PI WEB config`,e)}}applyClientConfig(e){this.shortcutConfig=e.shortcuts??{},this.workspaceUploadDefaultFolder=Vi(e)}async refreshAppData(){if(!this.isRefreshingApp){this.isRefreshingApp=!0;try{await Promise.all([this.sessions.refreshSelectedSession(),this.refreshMachineActivities(),this.loadClientConfig(),this.refreshWorkspaceDeletionRuns(),this.refreshCurrentWorkspaceSurface()]),this.schedulePiWebStatusRefresh()}finally{this.isRefreshingApp=!1}}}async refreshCurrentWorkspaceSurface(){let e=this.state.selectedWorkspace,t=this.state.mainView!==`chat`&&this.state.mainView!==`navigation`?this.state.mainView:this.state.workspaceTool;t===`core:workspace.files`?await this.files.refreshFiles():t===`core:workspace.git`?await this.git.refreshGit():t===`core:workspace.terminal`&&e!==void 0&&await this.refreshActiveTerminals(e)}hardReloadApp(){window.location.reload()}async restoreRoute(e){await this.restoreRouteFor(cp(),e),this.rememberCurrentMachineNavigation()}async restoreRouteFor(e,t,n=this.readWorkspaceRouteSurface(e),r){let i=I(this.state),a=e.projectId===void 0||e.projectId===``?Vx():n,o=++this.routeRestoreSeq;this.routeRestoreDepth+=1,this.restoringRouteTerminalId=a.selectedTerminalId;try{await this.restoreRouteMachine(e,!1);let n=this.loadPluginsForSelectedMachine();if(e.tool?.startsWith(`machine.`)===!0&&await n,!this.isCurrentRouteRestore(o))return;if(this.setState({workspaceTool:e.tool??this.state.workspaceTool,mainView:r??e.view??this.defaultRouteView(),selectedFilePath:a.selectedFilePath,selectedDiffPath:a.selectedDiffPath,selectedTerminalId:a.selectedTerminalId}),e.projectId===void 0||e.projectId===``){t&&this.updateUrl();return}if(this.routeMatchesCurrentSelection(e)){a.selectedTerminalId!==void 0&&this.rememberSelectedTerminal(a.selectedTerminalId),await this.refreshRestoredWorkspaceTool(e.tool,a.selectedFilePath),this.git.updatePolling(),t&&this.updateUrl();return}let i=this.state.projects.find(t=>t.id===e.projectId);if(!i){this.setState({selectedFilePath:void 0,selectedDiffPath:void 0,selectedTerminalId:void 0}),t&&this.updateUrl();return}if(await this.workspaces.selectProject(i,{workspaceId:e.workspaceId,sessionId:e.sessionId,updateUrl:!1}),!this.isCurrentRouteRestore(o))return;this.setState({selectedFilePath:a.selectedFilePath,selectedDiffPath:a.selectedDiffPath,selectedTerminalId:a.selectedTerminalId}),a.selectedTerminalId!==void 0&&this.rememberSelectedTerminal(a.selectedTerminalId),await this.refreshRestoredWorkspaceTool(e.tool,a.selectedFilePath),this.git.updatePolling(),t&&this.updateUrl()}finally{this.routeRestoreDepth=Math.max(0,this.routeRestoreDepth-1),this.routeRestoreDepth===0&&(this.restoringRouteTerminalId=void 0),I(this.state)!==i&&this.schedulePiWebStatusRefresh()}}isCurrentRouteRestore(e){return e===this.routeRestoreSeq}readWorkspaceRouteSurface(e){return e.projectId===void 0||e.projectId===``?Vx():{selectedFilePath:xa(Ex,`file`),selectedDiffPath:xa(Dx,`diff`),selectedTerminalId:xa(Ox,`terminal`)}}routeForSelectedMachine(e){let t=this.state.selectedMachine?.id??`local`;return(e.machineId??`local`)===t?e:{machineId:t,projectId:void 0,workspaceId:void 0,sessionId:void 0,tool:void 0,view:void 0}}replaceRouteAndClearWorkspaceQuery(e){lp(e,{replace:!0}),Sa(Ex,`file`,void 0,{replace:!0}),Sa(Dx,`diff`,void 0,{replace:!0}),Sa(Ox,`terminal`,void 0,{replace:!0})}shouldDeferRemoteRouteRestore(e,t=this.state.machineStatuses[e.machineId??`local`]){let n=e.machineId??`local`,r=this.state.selectedMachine;return n===`local`||r?.id!==n||r.kind!==`remote`||t?.ok!==!1?!1:e.projectId===void 0||e.projectId===``?this.state.projects.length===0:this.state.selectedProject?.id!==e.projectId}deferRemoteRouteRestore(e){this.pendingRemoteRouteRestore=e,this.remoteRouteRestoreAttempt=0,this.setRemoteRouteRestoreMessage(e),this.schedulePendingRemoteRouteRestore()}retryPendingRemoteRouteRestoreSoon(){this.pendingRemoteRouteRestore!==void 0&&this.schedulePendingRemoteRouteRestore(0)}schedulePendingRemoteRouteRestore(e=Ux(this.remoteRouteRestoreAttempt)){this.pendingRemoteRouteRestore!==void 0&&(this.clearPendingRemoteRouteRestoreTimer(),this.remoteRouteRestoreTimer=window.setTimeout(()=>{this.remoteRouteRestoreTimer=void 0,this.retryPendingRemoteRouteRestore()},e))}async retryPendingRemoteRouteRestore(){if(this.remoteRouteRestoreInProgress)return;let e=this.pendingRemoteRouteRestore;if(e!==void 0){if(!this.pendingRemoteRouteRestoreStillCurrent(e)){this.clearPendingRemoteRouteRestore();return}this.remoteRouteRestoreInProgress=!0;try{let t=e.machineId??`local`,n=await this.machines.refreshMachineHealth(t);if(!this.pendingRemoteRouteRestoreStillCurrent(e))return;if(n?.ok!==!0){this.scheduleNextRemoteRouteRestoreAttempt(e);return}if(await this.machines.refreshMachineRuntime(t),!this.pendingRemoteRouteRestoreStillCurrent(e)||(await this.projects.loadProjects(),!this.pendingRemoteRouteRestoreStillCurrent(e)))return;if(this.state.error!==``){this.scheduleNextRemoteRouteRestoreAttempt(e);return}if(await this.withChatScrollTransition(()=>this.restoreRouteFor(e,!1)),!this.pendingRemoteRouteRestoreStillCurrent(e))return;this.clearPendingRemoteRouteRestore(),this.rememberCurrentMachineNavigation(),await this.refreshWorkspaceDeletionRuns()}finally{this.remoteRouteRestoreInProgress=!1}}}scheduleNextRemoteRouteRestoreAttempt(e){if(this.remoteRouteRestoreAttempt+=1,this.remoteRouteRestoreAttempt>=xx.length){this.setRemoteRouteRestoreMessage(e,{exhausted:!0}),this.clearPendingRemoteRouteRestore();return}this.setRemoteRouteRestoreMessage(e),this.schedulePendingRemoteRouteRestore()}setRemoteRouteRestoreMessage(e,t={}){let n=e.machineId??`local`,r=this.state.machines.find(e=>e.id===n)?.name??this.state.selectedMachine?.name??`Remote machine`,i=this.state.machineStatuses[n]?.error??(this.state.error===``?void 0:this.state.error),a=t.exhausted===!0?`${r} is still unavailable.`:`${r} is unavailable; reconnecting…`;this.setState({error:`${a}${i===void 0?``:` ${i}`}`})}pendingRemoteRouteRestoreStillCurrent(e){let t=e.machineId??`local`;return t!==`local`&&this.pendingRemoteRouteRestore===e&&this.state.selectedMachine?.id===t&&this.state.machines.some(e=>e.id===t)}clearPendingRemoteRouteRestore(){this.clearPendingRemoteRouteRestoreTimer(),this.pendingRemoteRouteRestore=void 0,this.remoteRouteRestoreAttempt=0}clearPendingRemoteRouteRestoreTimer(){this.remoteRouteRestoreTimer!==void 0&&(window.clearTimeout(this.remoteRouteRestoreTimer),this.remoteRouteRestoreTimer=void 0)}async restoreRouteMachine(e,t){let n=e.machineId??`local`;if(this.state.selectedMachine?.id===n)return;let r=this.state.machines.find(e=>e.id===n);r!==void 0&&await this.machines.selectMachine(r,{updateUrl:t})}routeMatchesCurrentSelection(e){return(e.machineId??`local`)===(this.state.selectedMachine?.id??`local`)&&e.workspaceId!==void 0&&e.workspaceId!==``&&this.state.selectedProject?.id===e.projectId&&this.state.selectedWorkspace?.id===e.workspaceId&&this.state.selectedSession?.id===e.sessionId}async refreshRestoredWorkspaceTool(e,t){e===`core:workspace.files`&&await this.files.refreshFiles(),e===`core:workspace.files`&&t!==void 0&&await this.files.restoreFile(t),e===`core:workspace.git`&&await this.git.refreshGit()}async withChatScrollTransition(e,t=()=>!0){this.chatView?.saveScrollPosition(),await e(),t()&&(await this.updateComplete,t()&&(await this.chatView?.updateComplete,t()&&(await Kx(),t()&&(this.chatView?.restoreScrollPosition(),this.shouldAutoFocusPrompt()&&this.promptEditor?.focusInput()))))}shouldAutoFocusPrompt(){return this.appShell.shouldAutoFocusPrompt()}async withChatPrependTransition(e){await e(),await this.updateComplete,await this.chatView?.updateComplete}defaultRouteView(){return this.appShell.defaultRouteView()}updateUrl(e){this.rememberCurrentMachineNavigation(),lp({machineId:this.state.selectedMachine?.id,projectId:this.state.selectedProject?.id,workspaceId:this.state.selectedWorkspace?.id,sessionId:this.state.selectedSession?.id,tool:this.state.workspaceTool,view:this.state.mainView===`navigation`?void 0:this.state.mainView},e),this.syncWorkspaceRouteSurfaceToUrl()}rememberCurrentMachineNavigation(){this.machineNavigation.remember(pl(this.state))}syncWorkspaceRouteSurfaceToUrl(){this.writeWorkspaceRouteSurfaceToUrl(pl(this.state).surface)}writeMachineNavigationSnapshotToUrl(e,t){lp(ml(e),t),this.writeWorkspaceRouteSurfaceToUrl(e.surface)}writeWorkspaceRouteSurfaceToUrl(e){Sa(Ex,`file`,e.selectedFilePath,{replace:!0}),Sa(Dx,`diff`,e.selectedDiffPath,{replace:!0}),Sa(Ox,`terminal`,e.selectedTerminalId,{replace:!0})}async selectMachineWithMemory(e,t={}){if(this.state.selectedMachine?.id===e.id)return;t.rememberCurrent!==!1&&!this.routeRestoreInProgress&&this.rememberCurrentMachineNavigation();let n=++this.machineNavigationRestoreSeq,r=this.machineNavigation.latest(e.id)??fl(e.id);if(await this.restoreRouteFor(ml(r),!1,r.surface,r.view),!(n!==this.machineNavigationRestoreSeq||this.state.selectedMachine?.id!==e.id)){if(this.shouldPreserveUnrestoredMachineNavigation(r)){this.machineNavigation.remember(r),this.writeMachineNavigationSnapshotToUrl(r);return}this.updateUrl()}}shouldPreserveUnrestoredMachineNavigation(e){return e.projectId!==void 0&&this.state.selectedProject?.id!==e.projectId&&this.state.error!==``}openWorkspaceTool(e){e===`core:workspace.terminal`&&(this.terminalAutoStartWorkspaceId=this.state.selectedWorkspace?.id),this.setState({workspaceTool:e,mainView:e}),this.updateUrl(),this.refreshSelectedWorkspaceTool(e),this.git.updatePolling()}openTerminal(e){e?.terminalId!==void 0&&this.selectTerminal(e.terminalId,{replace:!0}),this.openWorkspaceTool(`core:workspace.terminal`)}terminalCommandRunsForOrigin(e,t=I(this.state)){let n=Hx(t,e),r=this.terminalCommandRunRuntimes.get(n);if(r!==void 0)return r;let i=bp(e,{api:{runTerminalCommand:(e,n)=>Di.runTerminalCommand(e,n,t),listCommandRuns:e=>Di.listCommandRuns(e,t),getCommandRun:e=>Di.getCommandRun(e,t)},openTerminal:(e,n)=>{this.openRuntimeTerminal(t,e,n)}});return this.terminalCommandRunRuntimes.set(n,i),i}async openRuntimeTerminal(e,t,n){if((I(this.state)!==e||t!==void 0&&(this.state.selectedWorkspace?.id!==t.id||this.state.selectedProject?.id!==t.projectId))&&(this.routeRestoreInProgress||this.rememberCurrentMachineNavigation(),await this.restoreRouteFor({machineId:e,projectId:t?.projectId,workspaceId:t?.id,sessionId:void 0,tool:`core:workspace.terminal`,view:`core:workspace.terminal`},!1,{selectedTerminalId:n?.terminalId},`core:workspace.terminal`),I(this.state)!==e)){this.setState({error:`Machine not found for terminal command run`});return}this.openTerminal(n)}selectTerminal(e,t){this.rememberSelectedTerminal(e),this.setState({selectedTerminalId:e}),this.rememberCurrentMachineNavigation(),this.writeSelectedTerminalToUrl(e,t)}rememberSelectedTerminal(e){let t=this.state.selectedWorkspace;t!==void 0&&(e===void 0?this.terminalSelection.forgetWorkspace(this.terminalWorkspaceKey(t)):this.terminalSelection.rememberTerminal(this.terminalWorkspaceKey(t),e))}writeSelectedTerminalToUrl(e,t){Sa(Ox,`terminal`,e,t)}terminalWorkspaceKey(e){return`${I(this.state)}:${e.path}`}selectMainView(e){if(e!==`navigation`&&e!==`chat`){this.openWorkspaceTool(e);return}this.setState({mainView:e}),this.updateUrl(),this.git.updatePolling()}openSettings(e=`general`){this.settingsSection=e,mp(e)}closeSettings(){this.settingsSection=void 0,mp(void 0)}navigateSettings(e){this.settingsSection=e,mp(e)}restoreSettingsRoute(){this.settingsSection=pp()}handleWorkspaceChange(e,t){if(e.selectedWorkspace?.id===t.selectedWorkspace?.id)return;this.terminalAutoStartWorkspaceId=void 0,this.activeTerminalIds.clear();let n=this.routeRestoreInProgress?this.restoringRouteTerminalId:t.selectedWorkspace===void 0?void 0:this.terminalSelection.latestTerminalId(this.terminalWorkspaceKey(t.selectedWorkspace));this.setState({activeTerminalCount:0,selectedTerminalId:n}),this.routeRestoreInProgress||(this.rememberCurrentMachineNavigation(),this.writeSelectedTerminalToUrl(n,{replace:!0})),t.selectedWorkspace!==void 0&&(this.refreshActiveTerminals(t.selectedWorkspace),this.refreshWorkspaceDeletionRuns(),this.refreshSelectedWorkspaceTool(t.workspaceTool),this.git.updatePolling())}connectRealtime(){this.realtime.connect(e=>{this.handleRealtimeEvent(e)},()=>{let e=this.state.selectedWorkspace;e!==void 0&&this.refreshActiveTerminals(e),this.refreshWorkspaceActivity()},I(this.state))}syncMachineActivitySubscriptions(){let e=this.machineActivitySubscriptionIds();for(let[t,n]of this.machineActivitySockets.entries())e.has(t)||(n.close(),this.machineActivitySockets.delete(t));for(let t of e){if(this.machineActivitySockets.has(t))continue;let e=new ic;e.connect(e=>{this.handleMachineActivityEvent(t,e)},()=>{this.refreshWorkspaceActivity(t)},t),this.machineActivitySockets.set(t,e)}}closeMachineActivitySockets(){for(let e of this.machineActivitySockets.values())e.close();this.machineActivitySockets.clear()}machineActivitySubscriptionIds(){let e=I(this.state);return new Set(this.state.machines.filter(t=>t.id!==e).filter(e=>Ix(e,this.state.machineStatuses[e.id])).map(e=>e.id))}handleMachineActivityEvent(e,t){t.type===`workspace.activity`&&this.activity.applyWorkspaceActivity(t.activity,e)}handleRealtimeEvent(e){e.type===`workspace.activity`?this.activity.applyWorkspaceActivity(e.activity):Bx(e)?(this.applyTerminalEvent(e),e.type===`terminal.exited`&&this.refreshWorkspaceDeletionRuns()):this.sessions.applyGlobalEvent(e)}applyTerminalEvent(e){let t=this.state.selectedWorkspace;t!==void 0&&(e.type===`terminal.closed`?e.cwd:e.terminal.cwd)===t.path&&(e.type===`terminal.created`&&!e.terminal.exited?this.activeTerminalIds.add(e.terminal.id):this.activeTerminalIds.delete(e.type===`terminal.closed`?e.terminalId:e.terminal.id),e.type===`terminal.closed`&&(this.terminalSelection.forgetTerminal(e.terminalId),this.state.selectedTerminalId===e.terminalId&&this.selectTerminal(void 0,{replace:!0})),this.setState({activeTerminalCount:this.activeTerminalIds.size}))}async refreshActiveTerminals(e){let t=I(this.state);try{let n=await Di.terminals(e.projectId,e.id,t);if(I(this.state)!==t||this.state.selectedWorkspace?.id!==e.id)return;this.activeTerminalIds.clear();for(let e of n)e.exited||this.activeTerminalIds.add(e.id);this.setState({activeTerminalCount:this.activeTerminalIds.size})}catch(e){this.setState({error:String(e)})}}handleActivityTransition(e,t){let n=zx(e),r=zx(t);n&&!r&&(this.setState({fileTreeStale:!0,gitStale:!0}),this.refreshSelectedWorkspaceTool(this.state.workspaceTool))}handleMachineChange(e,t){(e.selectedMachine?.id??`local`)!==(t.selectedMachine?.id??`local`)&&((this.pendingRemoteRouteRestore?.machineId??`local`)!==(t.selectedMachine?.id??`local`)&&this.clearPendingRemoteRouteRestore(),this.sessions.clearActiveSession(),this.realtime.close(),this.connectRealtime(),this.activeTerminalIds.clear(),this.sessionCleanupDialog=void 0,this.setState({piWebStatus:void 0}),this.git.updatePolling(),this.loadPluginsForSelectedMachine())}refreshSelectedWorkspaceTool(e){e===`core:workspace.files`&&this.files.refreshFiles(),e===`core:workspace.git`&&this.git.refreshGit()}renderWorkspacePanel(){let e=this.state.selectedWorkspace;return g`
2940
- <workspace-panel
2941
- id="workspace-panel"
2942
- .workspace=${e}
2943
- .panelContext=${e===void 0?void 0:this.createWorkspacePanelContext(e)}
2944
- .emptyState=${e===void 0?this.workspacePanelEmptyState():void 0}
2945
- .tool=${this.state.workspaceTool}
2946
- .panels=${this.visibleWorkspacePanels()}
2947
- .onSelectTool=${e=>{this.openWorkspaceTool(e)}}
2948
- ></workspace-panel>
2949
- `}renderNavigationPanelEdgeControl(){let e=this.resizablePanelConstraints(`navigation`);return g`
2950
- <app-panel-edge-control
2951
- side="navigation"
2952
- controls="navigation-panel"
2953
- resizeLabel="Resize navigation panel"
2954
- expandLabel="Expand navigation panel"
2955
- collapseLabel="Collapse navigation panel"
2956
- .collapsed=${this.panelCollapse.navigationPanelCollapsed}
2957
- .resizable=${!this.appShell.isMobileNavigationLayout}
2958
- .panelWidth=${this.panelResize.panelWidth(`navigation`)}
2959
- .minWidth=${e.minWidth}
2960
- .maxWidth=${e.maxWidth}
2961
- .onToggle=${()=>{this.panelCollapse.toggleNavigationPanel()}}
2962
- .onResizeStart=${()=>this.startPanelResize(`navigation`)}
2963
- .onResize=${e=>{this.panelResize.resizePanel(`navigation`,e,{persist:!1})}}
2964
- .onResizeEnd=${()=>{this.panelResize.persistPanelSizes()}}
2965
- .onReset=${()=>{this.resetResizablePanel(`navigation`)}}
2966
- ></app-panel-edge-control>
2967
- `}renderWorkspacePanelEdgeControl(){let e=this.resizablePanelConstraints(`workspace`);return g`
2968
- <app-panel-edge-control
2969
- side="workspace"
2970
- controls="workspace-panel"
2971
- resizeLabel="Resize workspace panel"
2972
- expandLabel="Expand workspace panel"
2973
- collapseLabel="Collapse workspace panel"
2974
- .collapsed=${this.panelCollapse.workspacePanelCollapsed}
2975
- .resizable=${!this.appShell.isMobileNavigationLayout}
2976
- .panelWidth=${this.panelResize.panelWidth(`workspace`)}
2977
- .minWidth=${e.minWidth}
2978
- .maxWidth=${e.maxWidth}
2979
- .onToggle=${()=>{this.panelCollapse.toggleWorkspacePanel()}}
2980
- .onResizeStart=${()=>this.startPanelResize(`workspace`)}
2981
- .onResize=${e=>{this.panelResize.resizePanel(`workspace`,e,{persist:!1})}}
2982
- .onResizeEnd=${()=>{this.panelResize.persistPanelSizes()}}
2983
- .onReset=${()=>{this.resetResizablePanel(`workspace`)}}
2984
- ></app-panel-edge-control>
2985
- `}startPanelResize(e){return e===`navigation`?this.panelCollapse.expandNavigationPanel():this.panelCollapse.expandWorkspacePanel(),this.measuredPanelWidth(e)??this.panelResize.panelWidth(e)}resizablePanelConstraints(e){let t=this.panelResize.constraints(e);return{...t,maxWidth:this.resizablePanelMaxWidth(e,t)}}resizablePanelMaxWidth(e,t){let n=this.getBoundingClientRect().width||(typeof window>`u`?0:window.innerWidth);if(n<=0)return t.maxWidth;let r=this.oppositeResizablePanelWidth(e),i=Math.floor(n-r-Ax-kx);return Math.max(t.minWidth,Math.min(t.maxWidth,i))}oppositeResizablePanelWidth(e){let t=e===`navigation`?`workspace`:`navigation`;return this.isResizablePanelCollapsedOrStacked(t)?0:this.measuredPanelWidth(t)??this.panelResize.panelWidth(t)}isResizablePanelCollapsedOrStacked(e){return e===`navigation`?this.panelCollapse.navigationPanelCollapsed:this.panelCollapse.workspacePanelCollapsed||!this.isDesktopSideBySideLayout()}isDesktopSideBySideLayout(){return typeof window>`u`||!(`matchMedia`in window)||window.matchMedia(jx).matches}measuredPanelWidth(e){let t=(e===`navigation`?this.navigationPanelFrame:this.workspacePanelFrame)?.getBoundingClientRect().width;return t===void 0||t<=0?void 0:t}resetResizablePanel(e){this.panelResize.resetPanel(e)}resetResizablePanels(){this.panelResize.resetPanels()}canDeleteArchivedSessions(){let e=this.selectedMachineRuntime();return e?.ok!==!0||Rt(e,w.sessionsDeleteArchived)}canReloadSessions(){let e=this.selectedMachineRuntime();return e?.ok===!0&&Rt(e,w.sessionsReload)}canClearServerQueue(){let e=this.selectedMachineRuntime();return e?.ok===!0&&Rt(e,w.sessionsClearQueue)}canCleanupSessions(){let e=this.selectedMachineRuntime();return e?.ok===!0&&Rt(e,w.sessionsCleanup)}hasAuthoritativeSessionPersistence(){return dc(this.selectedMachineRuntime())}supportsWorkspaceFileSuggestions(e=I(this.state)){if(e===`local`)return!0;let t=this.state.machineRuntimes[e];return t?.ok===!0&&Rt(t,w.workspaceFileSuggestions)}archivedDeleteUnavailableMessage(){return`Update and restart Pi-Web on ${this.state.selectedMachine?.name??`this machine`} to delete archived sessions.`}sessionCleanupUnavailableMessage(){return uu(this.state.selectedMachine?.name)}selectedMachineRuntime(){return this.state.machineRuntimes[I(this.state)]}openSessionCleanupDialog(){this.sessionCleanupDialog={error:``}}closeSessionCleanupDialog(){this.sessionCleanupDialog=void 0}async previewSessionCleanup(e){if(!this.canCleanupSessions()){this.sessionCleanupDialog={...this.sessionCleanupDialog??{},error:this.sessionCleanupUnavailableMessage(),preview:void 0,previewRequest:void 0,result:void 0,loading:!1};return}let t=I(this.state);this.sessionCleanupDialog={...this.sessionCleanupDialog??{},loading:!0,error:``,preview:void 0,previewRequest:void 0,result:void 0};try{let n=await Ei.cleanupPreview(e,t);if(I(this.state)!==t)return;this.sessionCleanupDialog={...this.sessionCleanupDialog,preview:n,previewRequest:e,result:void 0,loading:!1,error:``}}catch(e){I(this.state)===t&&(this.sessionCleanupDialog={...this.sessionCleanupDialog,loading:!1,error:`Failed to preview cleanup: ${Wx(e)}`})}}async runSessionCleanup(e){let t=this.sessionCleanupDialog;if(t?.preview===void 0||ru(t.previewRequest)!==ru(e)){this.sessionCleanupDialog={...t??{},error:`Preview cleanup before running it.`};return}if(!this.canCleanupSessions()){this.sessionCleanupDialog={...t,error:this.sessionCleanupUnavailableMessage(),running:!1};return}let n=I(this.state);this.sessionCleanupDialog={...t,running:!0,error:``};try{let t=await Ei.cleanup(e,n);if(I(this.state)!==n)return;this.sessionCleanupDialog={...this.sessionCleanupDialog,preview:t,previewRequest:e,result:t,running:!1,error:``},await this.sessions.applySessionCleanupResult(t,n)}catch(e){I(this.state)===n&&(this.sessionCleanupDialog={...this.sessionCleanupDialog,running:!1,error:`Failed to run cleanup: ${Wx(e)}`})}}renderNavigationPanel(){return g`
2986
- <app-navigation-panel
2987
- .machines=${this.state.machines}
2988
- .selectedMachine=${this.state.selectedMachine}
2989
- .machineStatuses=${this.state.machineStatuses}
2990
- .machineActivities=${this.state.machineActivities}
2991
- .machinesCollapsed=${this.navigationSections.isCollapsed(`machines`)}
2992
- .onToggleMachines=${()=>{this.navigationSections.toggle(`machines`)}}
2993
- .onSelectMachine=${e=>this.selectNavigationItem(`machines`,`projects`,()=>this.selectMachineWithMemory(e))}
2994
- .onRemoveMachine=${e=>{this.removeMachine(e)}}
2995
- .projects=${this.state.projects}
2996
- .selectedProject=${this.state.selectedProject}
2997
- .workspaceActivities=${this.state.workspaceActivities}
2998
- .workspacesByProjectId=${this.state.workspacesByProjectId}
2999
- .workspaces=${this.state.workspaces}
3000
- .selectedWorkspace=${this.state.selectedWorkspace}
3001
- .deletingWorkspaceIds=${Mu(this.state.workspaceDeletionRuns)}
3002
- .sessions=${this.state.sessions}
3003
- .sessionStatuses=${this.state.sessionStatuses}
3004
- .sessionActivities=${this.state.sessionActivities}
3005
- .sendingPrompts=${this.state.sendingPrompts}
3006
- .selectedSession=${this.state.selectedSession}
3007
- .startingSessionCount=${this.state.startingSessionCount}
3008
- .canStartSession=${!!this.state.selectedWorkspace}
3009
- .canDeleteArchivedSessions=${this.canDeleteArchivedSessions()}
3010
- .canReloadSessions=${this.canReloadSessions()}
3011
- .canCleanupSessions=${this.canCleanupSessions()}
3012
- .authoritativeSessionPersistence=${this.hasAuthoritativeSessionPersistence()}
3013
- .archivedDeleteUnavailableMessage=${this.archivedDeleteUnavailableMessage()}
3014
- .cleanupUnavailableMessage=${this.sessionCleanupUnavailableMessage()}
3015
- .collapsible=${!0}
3016
- .compact=${this.appShell.isMobileNavigationLayout}
3017
- .projectsCollapsed=${this.navigationSections.isCollapsed(`projects`)}
3018
- .workspacesCollapsed=${this.navigationSections.isCollapsed(`workspaces`)}
3019
- .sessionsCollapsed=${this.navigationSections.isCollapsed(`sessions`)}
3020
- .workspaceLabelItems=${e=>this.workspaceLabelItems(e)}
3021
- .refreshControl=${this.appShell.shouldShowAppRefreshInHeader()?this.renderAppRefresh():void 0}
3022
- .onShowActions=${()=>{this.setState({actionPaletteOpen:!0})}}
3023
- .onToggleProjects=${()=>{this.navigationSections.toggle(`projects`)}}
3024
- .onToggleWorkspaces=${()=>{this.navigationSections.toggle(`workspaces`)}}
3025
- .onToggleSessions=${()=>{this.navigationSections.toggle(`sessions`)}}
3026
- .onSelectProject=${e=>this.selectNavigationItem(`projects`,`workspaces`,()=>this.workspaces.selectProject(e))}
3027
- .onCloseProject=${e=>this.projects.closeProject(e.id)}
3028
- .onSelectWorkspace=${e=>this.selectNavigationItem(`workspaces`,`sessions`,()=>this.workspaces.selectWorkspace(e))}
3029
- .onDeleteWorkspace=${e=>{this.deleteWorkspace(e)}}
3030
- .onArchivedCollapsed=${()=>{this.sessions.clearSelectionAfterArchivedCollapse()}}
3031
- .onStartSession=${()=>this.startSessionFromNavigation()}
3032
- .onSelectSession=${e=>this.selectNavigationItem(`sessions`,`chat`,()=>this.sessions.selectSession(e))}
3033
- .onArchiveSession=${e=>this.sessions.archiveSession(e)}
3034
- .onArchiveSessionWithDescendants=${e=>this.sessions.archiveSessionWithDescendants(e)}
3035
- .onArchiveSessions=${e=>this.sessions.archiveSessions(e)}
3036
- .onRestoreSession=${e=>this.selectNavigationItem(`sessions`,`chat`,()=>this.sessions.restoreSession(e))}
3037
- .onDeleteCachedNewSession=${e=>this.sessions.deleteCachedNewSession(e)}
3038
- .onDeleteArchivedSession=${e=>this.sessions.deleteArchivedSessions([e])}
3039
- .onDeleteArchivedSessions=${e=>this.sessions.deleteArchivedSessions(e)}
3040
- .onDetachParentSession=${e=>this.sessions.detachParent(e)}
3041
- .onReloadSession=${e=>this.sessions.reloadSession(e)}
3042
- .onCleanupSessions=${()=>{this.openSessionCleanupDialog()}}
3043
- .onFocusNavigationTarget=${e=>{this.focusNavigationTarget(e)}}
3044
- .onCancelKeyboardNavigation=${()=>{this.focusChatComposer()}}
3045
- ></app-navigation-panel>
3046
- `}openNavigationSection(e){this.navigationSections.open(e,()=>{this.selectMainView(`navigation`)})}async selectNavigationItem(e,t,n){let r=++this.navigationSelectionSeq,i=()=>r===this.navigationSelectionSeq;await this.withChatScrollTransition(async()=>{this.navigationSections.advanceAfterSelection(e),await n()},i),i()&&await this.focusNavigationTarget(t)}async startSessionFromNavigation(){let e=++this.navigationSelectionSeq;this.navigationSections.advanceAfterSelection(`sessions`),await this.startSessionAndOpenChat(()=>e===this.navigationSelectionSeq)}async startSessionAndOpenChat(e=()=>!0){this.sessions.startSession().catch(t=>{e()&&this.setState({error:String(t)})}),e()&&await this.focusChatComposer()}async focusNavigationTarget(e){if(e===`chat`){await this.focusChatComposer();return}await this.focusNavigationSection(e)}async focusNavigationSection(e){if(e===`machines`&&!dx(this.state.machines)){await this.focusNavigationSection(`projects`);return}this.panelCollapse.expandNavigationPanel(),this.appShell.isMobileNavigationLayout&&this.selectMainView(`navigation`),this.navigationSections.expand(e),await this.updateComplete,await Kx(),await this.navigationPanel?.focusSection(e)}async focusChatComposer(){this.state.mainView!==`chat`&&this.selectMainView(`chat`),await this.updateComplete,await Kx(),this.promptEditor?.focusInput()}visibleWorkspacePanels(){let e=this.state.selectedWorkspace;if(e===void 0)return[];let t=this.createWorkspacePanelContext(e);return this.plugins.getWorkspacePanels().filter(e=>e.visible?.(t)??!0)}workspacePanelEmptyState(){let e=this.state.selectedProject;return this.state.isLoadingProjects?{title:`Loading projects…`,body:`Looking for projects you have added to PI WEB.`}:e===void 0?this.state.projects.length===0?{title:`No projects yet`,body:`Use Actions → Add Project to add a folder. Workspace tools will appear here after you choose a workspace.`}:{title:`Select a project`,body:`Choose a project from the sidebar, then select a workspace to inspect files, Git, or terminals.`}:this.state.isLoadingWorkspaces?{title:`Loading workspaces…`,body:`Preparing workspace tools for ${e.name}.`}:this.state.workspaces.length===0?{title:`No workspaces found`,body:`${e.name} does not have any available workspaces. Try selecting the project again or re-adding it.`}:{title:`Select a workspace`,body:`Choose a workspace in ${e.name} to inspect files, Git, or terminals.`}}sessionEmptyMessage(){return this.state.isLoadingProjects?`Loading projects…`:this.state.selectedWorkspace===void 0?this.state.selectedProject===void 0?this.state.projects.length===0?`Add a project to start a session.`:`Select a project and workspace to start a session.`:`Select a workspace to start a session.`:`Select or start a session.`}mobilePanelBadge(e){let t=this.state.selectedWorkspace;if(t!==void 0)return e.badge?.(this.createWorkspacePanelContext(t))}mobilePanelIcon(e){switch(e.id){case`core:workspace.files`:return`files`;case`core:workspace.git`:return`git`;case`core:workspace.terminal`:return`terminal`;default:return}}workspaceLabelItems(e){return this.plugins.getWorkspaceLabelItems(this.createWorkspaceLabelContext(e))}createWorkspaceLabelContext(e){let t=Px(this.state);return{machine:t,workspace:e,state:this.state,files:this.createWorkspaceFiles(e,t.id),host:this.createWorkspaceHost()}}createWorkspaceFiles(e,t){return{readFile:n=>Ti.workspaceFile(e.projectId,e.id,n,t),writeFile:async(n,r,i)=>{let a=await Ti.writeWorkspaceFile(e.projectId,e.id,n,r,i,t);return this.files.refreshFiles(),a},deleteFile:async n=>{let r=await Ti.deleteWorkspaceFile(e.projectId,e.id,n,t);return this.files.refreshFiles(),r},moveFile:async(n,r,i)=>{let a=await Ti.moveWorkspaceFile(e.projectId,e.id,n,r,i,t);return this.files.refreshFiles(),a}}}createWorkspaceHost(){return{requestRender:()=>{this.requestUpdate()}}}createWorkspacePanelContext(e){let t=Px(this.state),n=t.id,r=i=>{let a=this.terminalCommandRunsForOrigin(i,n);return ff({machine:t,workspace:e,state:this.state,files:this.createWorkspaceFiles(e,n),prompt:this.createPromptEditor(),terminal:{open:t=>{this.openRuntimeTerminal(n,e,t)},runCommand:t=>a.runCommand({...t,workspace:e})},openTerminal:t=>{this.openRuntimeTerminal(n,e,t)},host:this.createWorkspaceHost(),piWebUnstable:{terminalCommandRuns:a},fileTree:this.state.fileTree,expandedDirs:this.state.expandedDirs,selectedFilePath:this.state.selectedFilePath,selectedFileContent:this.state.selectedFileContent,fileTreeStale:this.state.fileTreeStale,gitStatus:this.state.gitStatus,selectedDiffPath:this.state.selectedDiffPath,selectedDiff:this.state.selectedDiff,selectedStagedDiff:this.state.selectedStagedDiff,gitStale:this.state.gitStale,activeTerminalCount:this.state.activeTerminalCount,selectedTerminalId:this.state.selectedTerminalId,terminalAutoStart:this.terminalAutoStartWorkspaceId===e.id,workspaceUploadDefaultFolder:Hi(e.effectiveConfig,this.workspaceUploadDefaultFolder),onRefreshFiles:()=>{this.files.refreshFiles()},onExpandDir:e=>{this.files.expandDir(e)},onSelectFile:e=>{this.files.selectFile(e)},onStartWorkspaceUpload:(e,t)=>this.files.startWorkspaceUpload(e,t),onCancelWorkspaceUpload:e=>{this.files.cancelWorkspaceUpload(e)},onClearWorkspaceUpload:e=>{this.files.clearWorkspaceUpload(e)},onRefreshGit:()=>{this.git.refreshGit()},onSelectDiff:e=>{this.git.selectDiff(e)},onSelectTerminal:(e,t)=>{this.selectTerminal(e,t)}},r)};return r(`core`)}getActions(){return _p(this.getDefaultActions(),this.shortcutConfig)}getDefaultActions(){return[...this.plugins.getActions(this.createPluginRuntimeContext()),...this.sessionActions(),...this.navigationFocusActions(),...this.panelLayoutActions()]}sessionActions(){return[{id:`app.sessions.cleanup`,title:`Clean Up Sessions`,description:`Preview and manually clean up idle or archived sessions on the selected machine`,group:`Sessions`,...this.canCleanupSessions()?{}:{enabled:!1,disabledReason:this.sessionCleanupUnavailableMessage()},run:()=>{this.openSessionCleanupDialog()}}]}panelLayoutActions(){return[{id:`app.layout.reset-navigation-panel-size`,title:`Reset Navigation Panel Size`,description:`Restore the navigation panel to its default width`,group:`View`,run:()=>{this.resetResizablePanel(`navigation`)}},{id:`app.layout.reset-workspace-panel-size`,title:`Reset Workspace Panel Size`,description:`Restore the workspace panel to its default width`,group:`View`,run:()=>{this.resetResizablePanel(`workspace`)}},{id:`app.layout.reset-panel-sizes`,title:`Reset Panel Sizes`,description:`Restore all side panels to their default widths`,group:`View`,run:()=>{this.resetResizablePanels()}}]}navigationFocusActions(){return[{id:`app.navigation.focus-machines`,title:`Focus Machines`,description:`Move keyboard focus to the machine selector`,shortcut:`mod+g m`,group:`Navigation`,run:()=>this.focusNavigationSection(`machines`)},{id:`app.navigation.focus-projects`,title:`Focus Projects`,description:`Move keyboard focus to the projects list`,shortcut:`mod+g p`,group:`Navigation`,run:()=>this.focusNavigationSection(`projects`)},{id:`app.navigation.focus-workspaces`,title:`Focus Workspaces`,description:`Move keyboard focus to the workspaces list`,shortcut:`mod+g w`,group:`Navigation`,run:()=>this.focusNavigationSection(`workspaces`)},{id:`app.navigation.focus-sessions`,title:`Focus Sessions`,description:`Move keyboard focus to the sessions list`,shortcut:`mod+g s`,group:`Navigation`,run:()=>this.focusNavigationSection(`sessions`)}]}ensureGatewayPluginsLoaded(){return this.gatewayPluginLoadPromise??=this.loadExternalPlugins(),this.gatewayPluginLoadPromise}async loadExternalPlugins(){await this.registerExternalPlugins(`PI WEB plugins`,()=>Jd())}async loadPluginsForSelectedMachine(){let e=this.state.selectedMachine;e?.kind===`remote`&&await this.loadPluginsForMachine(e)}async loadPluginsForMachine(e){if(await this.ensureGatewayPluginsLoaded(),e.kind!==`remote`||this.loadedMachinePluginIds.has(e.id))return;let t=this.machinePluginLoadPromises.get(e.id);if(t!==void 0)return t;let n=this.registerExternalPlugins(`PI WEB plugins from ${e.name}`,()=>Jd(`api/machines/${encodeURIComponent(e.id)}/pi-web-plugins/manifest.json`,{machineId:e.id,shouldLoadPlugin:e=>this.plugins.shouldLoadRemotePlugin(e.id,e.machineSpecific)})).then(t=>{t&&this.loadedMachinePluginIds.add(e.id)}).finally(()=>{this.machinePluginLoadPromises.delete(e.id)});this.machinePluginLoadPromises.set(e.id,n),await n}async registerExternalPlugins(e,t){try{let e=await t();for(let t of e)try{this.plugins.register(t)}catch(e){console.warn(`Failed to register PI WEB plugin ${t.id}`,e)}return this.applyPreferredTheme(!1),this.requestUpdate(),!0}catch(t){return console.warn(`Failed to load ${e}`,t),!1}}createPromptEditor(){return{insertText:e=>{let t=this.promptEditor?.view;if(!t)return;t.hasFocus||t.focus();let n=t.state.selection.main;t.dispatch({changes:{from:n.from,to:n.to,insert:e},selection:{anchor:n.from+e.length}})},getText:()=>this.promptEditor?.view?.state.doc.toString()??``,getSelection:()=>{let e=this.promptEditor?.view;if(!e)return null;let t=e.state.selection.main;return t.empty?null:{start:t.from,end:t.to,text:e.state.sliceDoc(t.from,t.to)}}}}createPluginRuntimeContext(){let e=t=>df({state:this.state,prompt:this.createPromptEditor(),piWebUnstable:{terminalCommandRuns:this.terminalCommandRunsForOrigin(t),openSettings:e=>{this.openSettings(e)}},openActionPalette:()=>{this.setState({actionPaletteOpen:!0})},focusPrompt:()=>{this.focusChatComposer()},addProject:()=>{this.setState({projectDialogOpen:!0})},addMachine:()=>{this.openMachineDialog()},refreshSelectedMachine:async()=>{await Promise.all([this.machines.refreshMachineHealth(),this.machines.refreshMachineRuntime()])},removeSelectedMachine:()=>this.removeMachine(),openSelectedMachine:()=>{this.openSelectedMachine()},configureAuth:()=>this.auth.openLogin(),logoutAuth:()=>this.auth.openLogout(),openThemePicker:()=>{this.openThemeDialog()},selectMainView:e=>{this.selectMainView(e)},selectWorkspaceTool:e=>{this.openWorkspaceTool(e)},openTerminal:e=>{this.openTerminal(e)},refreshFiles:()=>this.files.refreshFiles(),refreshGit:()=>this.git.refreshGit(),refreshAppData:()=>this.refreshAppData(),checkForPiWebUpdates:()=>this.piWebStatusController.checkForUpdates(),reloadPage:()=>{this.hardReloadApp()},deleteWorkspace:e=>this.deleteWorkspace(e),startSession:()=>this.withChatScrollTransition(()=>this.startSessionAndOpenChat()),archiveSession:()=>this.sessions.archiveSession(),reloadSession:()=>this.sessions.reloadSession(),deleteCachedNewSession:()=>this.sessions.deleteCachedNewSession(),stopActiveWork:()=>this.sessions.stopActiveWork()},e);return e(`core`)}async deleteWorkspace(e=this.state.selectedWorkspace){if(e===void 0)return;if(!cl(e)){this.setState({error:`Only secondary Git worktrees can be deleted`});return}if(Nu(this.state,e))return;let t=e.branch??e.label;if(!confirm(`Delete workspace ${t}?\n\nThis will run git worktree remove and delete:\n${e.path}\n\nThe Git branch will not be deleted.`))return;let n=I(this.state);try{let t=await Ti.deleteWorkspace(e.projectId,e.id,n);if(I(this.state)!==n)return;this.recordWorkspaceDeletionRun(t,n);let r=await this.workspaceForCommandRun(t);if(I(this.state)!==n)return;r!==void 0&&this.openRuntimeTerminal(n,r,{terminalId:t.terminalId})}catch(e){I(this.state)===n&&this.setState({error:`Failed to start workspace deletion: ${Wx(e)}`})}}async workspaceForCommandRun(e){let t=this.state.selectedProject?.id===e.projectId?this.state.workspaces:this.state.workspacesByProjectId[e.projectId];return(t===void 0||t.length===0)&&(t=await this.workspaces.refreshProjectWorkspaces(e.projectId)),t.find(t=>t.id===e.workspaceId)}recordWorkspaceDeletionRun(e,t){if(I(this.state)!==t)return;let n=Pu(e);n!==void 0&&(this.setState({workspaceDeletionRuns:{...this.state.workspaceDeletionRuns,[n]:e}}),this.updateWorkspaceDeletionPolling())}async refreshWorkspaceDeletionRuns(){if(this.refreshingWorkspaceDeletionRuns)return;let e=I(this.state),t=this.state.selectedProject;if(t===void 0){this.setState({workspaceDeletionRuns:{}}),this.updateWorkspaceDeletionPolling();return}this.refreshingWorkspaceDeletionRuns=!0;try{let n=await this.terminalCommandRunsForOrigin(`core`,e).listCommandRuns(Au(t.id));if(I(this.state)!==e)return;let r=ju(n);this.setState({workspaceDeletionRuns:r});for(let t of Object.values(r))Fu(t)||await this.handleCompletedWorkspaceDeletionRun(t,e)}catch(e){console.warn(`Failed to refresh workspace deletion runs`,e)}finally{this.refreshingWorkspaceDeletionRuns=!1,this.updateWorkspaceDeletionPolling()}}updateWorkspaceDeletionPolling(){let e=Object.values(this.state.workspaceDeletionRuns).some(Fu);if(e&&this.workspaceDeletionPollTimer===void 0){this.workspaceDeletionPollTimer=window.setInterval(()=>{this.refreshWorkspaceDeletionRuns()},1e3);return}!e&&this.workspaceDeletionPollTimer!==void 0&&(window.clearInterval(this.workspaceDeletionPollTimer),this.workspaceDeletionPollTimer=void 0)}async handleCompletedWorkspaceDeletionRun(e,t=I(this.state)){if(I(this.state)!==t)return;let n=Hx(t,e.id);if(this.handledWorkspaceDeletionRunIds.has(n))return;let r=Pu(e);if(r!==void 0){if(this.handledWorkspaceDeletionRunIds.add(n),e.status===`succeeded`){if(await this.workspaces.refreshAfterWorkspaceDeleted(e.projectId,r),I(this.state)!==t)return;this.setState({workspaceDeletionRuns:Gx(this.state.workspaceDeletionRuns,r)}),this.updateWorkspaceDeletionPolling();return}e.status===`failed`&&(this.setState({error:`Workspace deletion failed. See terminal output.`}),this.updateWorkspaceDeletionPolling())}}openMachineDialog(){this.setState({machineDialogOpen:!0,error:``})}async submitMachineDialog(e){await this.machines.addMachine(e)!==void 0&&(this.setState({machineDialogOpen:!1}),this.schedulePiWebStatusRefresh())}async removeMachine(e=this.state.selectedMachine){if(e===void 0||e.kind===`local`||!window.confirm(`Remove ${e.name}?\n\nThis only removes it from this PI WEB gateway.`))return;let t=this.state.selectedMachine?.id===e.id;t&&this.rememberCurrentMachineNavigation();let n=await this.machines.deleteMachine(e,{selectFallback:!t});this.state.machines.some(t=>t.id===e.id)||this.machineNavigation.forget(e.id),t&&n!==void 0&&await this.selectMachineWithMemory(n,{rememberCurrent:!1})}openSelectedMachine(){let e=this.state.selectedMachine;e?.kind!==`remote`||e.baseUrl===void 0||window.open(e.baseUrl,`_blank`,`noopener,noreferrer`)}runAction(e){Promise.resolve().then(()=>e.run()).catch(t=>{let n=t instanceof Error?t.message:String(t);console.warn(`Action failed: ${e.id}`,t),this.setState({error:`Action failed: ${n}`})})}async openModelDialog(){let e=await this.sessions.listModels(),t=this.state.status?.model?.provider,n=this.state.status?.model?.id;this.setState({modelDialog:{title:`Select Model`,...t!==void 0&&n!==void 0?{selectedValue:`${t}/${n}`}:{},options:e.map(e=>{let r=e.provider??``,i=e.id??``,a=r===t&&i===n;return{value:`${r}/${i}`,label:`${i}${a?` ✓ current`:``}`,description:r}})}})}async pickModel(e){this.setState({modelDialog:void 0});let t=e.indexOf(`/`);t<=0||await this.sessions.setModel(e.slice(0,t),e.slice(t+1))}openThemeDialog(){let e=this.plugins.getThemes(),t=this.resolveCurrentThemePreference(e),n=t.selectedTheme?.id,r=this.themePreference.auto?wx:Cx;this.setState({themeDialog:{title:`Select Theme`,selectedValue:n===void 0?r:`${Tx}${n}`,options:[{value:r,label:`Auto ${this.themePreference.auto?`✓ on`:`off`}`,description:this.autoThemeDescription(t)},...e.map(e=>({value:`${Tx}${e.id}`,label:this.themeOptionLabel(e,n),description:this.themeOptionDescription(e)}))]}})}pickTheme(e){if(this.setState({themeDialog:void 0}),e===Cx||e===wx){let t=this.resolveCurrentThemePreference().selectedTheme?.id;if(t===void 0)return;this.themePreference={themeId:t,auto:e===Cx},this.applyPreferredTheme(!0);return}if(!e.startsWith(Tx))return;let t=e.slice(6),n=this.plugins.getThemes().find(e=>e.id===t);n!==void 0&&(this.themePreference={themeId:n.id,auto:this.themePreference.auto},this.applyPreferredTheme(!0))}applyPreferredTheme(e){let t=this.resolveCurrentThemePreference().activeTheme;t!==void 0&&(this.activeThemeId=t.id,yu(t),e&&vu(this.themePreference))}resolveCurrentThemePreference(e=this.plugins.getThemes()){return bu({themes:e,themePairs:this.plugins.getThemePairs(),preference:this.themePreference,prefersLight:this.systemPrefersLight()})}themePairForTheme(e){return Su(this.plugins.getThemePairs(),e)}systemPrefersLight(){return this.systemLightThemeMedia?.matches??!1}autoThemeDescription(e){return!this.themePreference.auto||e.selectedTheme===void 0?`Follow the system light/dark preference when the selected theme has a pair.`:e.selectedThemePair===void 0?`On, but the selected theme has no light/dark pair, so it will stay selected.`:`On · ${e.selectedThemePair.name} follows the system ${this.systemPrefersLight()?`light`:`dark`} preference.`}themeOptionLabel(e,t){let n=[...e.id===t?[`selected`]:[],...e.id===this.activeThemeId&&e.id!==t?[`active`]:[]];return n.length===0?e.name:`${e.name} ✓ ${n.join(` · `)}`}themeOptionDescription(e){let t=[e.colorScheme];return this.themePairForTheme(e.id)!==void 0&&t.push(`auto pair`),e.description!==void 0&&t.push(e.description),t.join(` · `)}async openThinkingDialog(){let e=await this.sessions.listThinkingLevels(),t=this.state.status?.thinkingLevel??`off`;this.setState({thinkingDialog:{title:`Select Thinking Level`,selectedValue:t,options:e.map(e=>{let n=qx(e);return{value:e,label:`${e}${e===t?` ✓ current`:``}`,...n===void 0?{}:{description:n}}})}})}async pickThinking(e){this.setState({thinkingDialog:void 0}),e!==``&&await this.sessions.setThinkingLevel(e)}sendPrompt(e,t,n,r){!(n!==void 0&&n.length>0)&&t===void 0&&this.auth.handleSlashCommand(e)||this.sessions.send(e,t,n,r)}renderChatView(e,t){return g`
3047
- <chat-view .sessionId=${t.id} .messages=${e.messages} .messageStart=${e.messagePageStart} .messageEnd=${e.messagePageEnd} .messageTotal=${e.messagePageTotal} .hasMore=${e.messagePageStart>0} .loadingMore=${e.isLoadingEarlierMessages} .isSendingPrompt=${e.sendingPrompts[t.id]===!0} .isCompacting=${e.status?.isCompacting===!0} .pendingMessageCount=${e.status?.pendingMessageCount??0} .clientQueuedMessages=${e.clientQueuedSessionMessages[t.id]??[]} .status=${e.status} .activity=${e.activity} .canClearServerQueue=${this.canClearServerQueue()} .onClearServerQueue=${this.handleClearServerQueue} .onDismissWarning=${this.handleDismissWarning} .onLoadMore=${()=>this.withChatPrependTransition(()=>this.sessions.loadEarlierMessages())}></chat-view>
3048
- `}renderContextBar(){return this.appShell.isMobileNavigationLayout?g`
3049
- <app-context-bar
3050
- .machines=${this.state.machines}
3051
- .machine=${this.state.selectedMachine}
3052
- .project=${this.state.selectedProject}
3053
- .workspace=${this.state.selectedWorkspace}
3054
- .session=${this.state.selectedSession}
3055
- .refreshControl=${this.appShell.shouldShowAppRefreshInContextBar()?this.renderAppRefresh():void 0}
3056
- .onOpenSection=${e=>{this.openNavigationSection(e)}}
3057
- .onShowActions=${()=>{this.setState({actionPaletteOpen:!0})}}
3058
- ></app-context-bar>
3059
- `:null}renderMobileMainTabs(){return g`
3060
- <app-mobile-main-tabs
3061
- .tabs=${this.mobileMainTabs()}
3062
- .selectedView=${this.state.mainView}
3063
- .onSelect=${e=>{this.selectMainView(e)}}
3064
- ></app-mobile-main-tabs>
3065
- `}mobileMainTabs(){return[{id:`navigation`,label:`Sessions`,icon:`navigation`,className:`navigation-tab`},{id:`chat`,label:`Chat`,icon:`chat`},...this.visibleWorkspacePanels().map(e=>{let t=e.icon??this.mobilePanelIcon(e);return{id:e.id,label:e.title,...t===void 0?{}:{icon:t},badge:this.mobilePanelBadge(e)}})]}renderAppRefresh(){return g`<app-refresh-control .onReload=${()=>{this.hardReloadApp()}}></app-refresh-control>`}render(){let e=this.state;return g`
3066
- <div class=${this.panelCollapse.shellClass(e.mainView)} style=${this.panelResize.shellStyle({navigation:this.resizablePanelConstraints(`navigation`),workspace:this.resizablePanelConstraints(`workspace`)})}>
3067
- <aside id="navigation-panel">${this.appShell.isMobileNavigationLayout?null:this.renderNavigationPanel()}</aside>
3068
- ${this.renderNavigationPanelEdgeControl()}
3069
- <main class=${Uf(e.mainView)}>
3070
- ${this.renderContextBar()}
3071
- ${this.renderMobileMainTabs()}
3072
- ${e.error?g`<div class="error">${e.error}</div>`:null}
3073
- <div class="mobile-navigation-panel">${this.appShell.isMobileNavigationLayout?this.renderNavigationPanel():null}</div>
3074
- ${e.selectedSession?g`
3075
- ${this.renderChatView(e,e.selectedSession)}
3076
- <prompt-editor .sessionId=${e.selectedSession.id} .cwd=${e.selectedWorkspace?.path} .machineId=${I(e)} .projectId=${e.selectedWorkspace?.projectId} .workspaceId=${e.selectedWorkspace?.id} .workspaceScopedFileSuggestions=${this.supportsWorkspaceFileSuggestions()} .disabled=${e.selectedSession.archived===!0} .canSteer=${e.status?.isStreaming===!0} .isCompacting=${e.status?.isCompacting===!0} .canStop=${e.status?.isStreaming===!0||e.status?.isBashRunning===!0||e.status?.isCompacting===!0||(e.status?.pendingMessageCount??0)>0} .status=${e.status} .availableThinkingLevels=${e.availableThinkingLevels} .sending=${e.sendingPrompts[e.selectedSession.id]===!0} .onSend=${this.handleSendPrompt} .onStop=${this.handleStopActiveWork} .onSelectModel=${this.handleSelectModel} .onSelectThinking=${this.handleSelectThinking}></prompt-editor>
3077
- <status-bar .status=${e.status}></status-bar>
3078
- ${e.commandDialog===void 0?null:g`<command-picker .title=${e.commandDialog.title} .options=${e.commandDialog.options} .onPick=${t=>this.sessions.respondToCommand(e.commandDialog?.requestId??``,t)} .onCancel=${()=>{this.sessions.cancelCommand()}}></command-picker>`}
3079
- ${e.modelDialog===void 0?null:g`<command-picker title=${e.modelDialog.title} .searchable=${!0} .options=${e.modelDialog.options} .selectedValue=${e.modelDialog.selectedValue} .onPick=${e=>{this.pickModel(e)}} .onCancel=${()=>{this.setState({modelDialog:void 0})}}></command-picker>`}
3080
- ${e.thinkingDialog===void 0?null:g`<command-picker title=${e.thinkingDialog.title} .options=${e.thinkingDialog.options} .selectedValue=${e.thinkingDialog.selectedValue} .onPick=${e=>{this.pickThinking(e)}} .onCancel=${()=>{this.setState({thinkingDialog:void 0})}}></command-picker>`}
3081
- ${e.authDialog===void 0?null:g`<auth-dialog .state=${e.authDialog} .onChooseMethod=${e=>{this.auth.chooseLoginMethod(e)}} .onSelectProvider=${(e,t)=>{this.auth.selectLoginProvider(e,t)}} .onApiKeyInput=${e=>{this.auth.updateApiKey(e)}} .onSaveApiKey=${()=>{this.auth.saveApiKey()}} .onLogoutProvider=${e=>{this.auth.logoutProvider(e)}} .onOAuthInput=${e=>{this.auth.updateOAuthInput(e)}} .onOAuthRespond=${e=>{this.auth.respondOAuth(e)}} .onOAuthCancel=${()=>{this.auth.cancelOAuth()}} .onCancel=${()=>{this.auth.closeDialog()}}></auth-dialog>`}
3082
- `:g`<div class="empty">${this.sessionEmptyMessage()}</div>`}
3083
- </main>
3084
- ${this.renderWorkspacePanelEdgeControl()}
3085
- ${this.renderWorkspacePanel()}
3086
- ${e.actionPaletteOpen?g`<action-palette .actions=${this.getActions()} .onRun=${e=>{this.setState({actionPaletteOpen:!1}),this.runAction(e)}} .onCancel=${()=>{this.setState({actionPaletteOpen:!1})}}></action-palette>`:null}
3087
- ${e.projectDialogOpen?g`<project-dialog .machineId=${I(e)} .onSubmit=${(e,t)=>this.projects.addProject(e,t)} .onCancel=${()=>{this.setState({projectDialogOpen:!1})}}></project-dialog>`:null}
3088
- ${e.machineDialogOpen?g`<machine-dialog .error=${e.error} .onSubmit=${e=>this.submitMachineDialog(e)} .onCancel=${()=>{this.setState({machineDialogOpen:!1})}}></machine-dialog>`:null}
3089
- ${this.sessionCleanupDialog===void 0?null:g`<session-cleanup-dialog .canCleanup=${this.canCleanupSessions()} .unavailableMessage=${this.sessionCleanupUnavailableMessage()} .preview=${this.sessionCleanupDialog.preview} .previewRequest=${this.sessionCleanupDialog.previewRequest} .result=${this.sessionCleanupDialog.result} .loading=${this.sessionCleanupDialog.loading===!0} .running=${this.sessionCleanupDialog.running===!0} .error=${this.sessionCleanupDialog.error??``} .onPreview=${e=>{this.previewSessionCleanup(e)}} .onRun=${e=>{this.runSessionCleanup(e)}} .onClose=${()=>{this.closeSessionCleanupDialog()}}></session-cleanup-dialog>`}
3090
- ${e.themeDialog===void 0?null:g`<command-picker title=${e.themeDialog.title} .options=${e.themeDialog.options} .selectedValue=${e.themeDialog.selectedValue} .onPick=${e=>{this.pickTheme(e)}} .onCancel=${()=>{this.setState({themeDialog:void 0})}}></command-picker>`}
3091
- ${this.settingsSection===void 0?null:g`<settings-dialog .section=${this.settingsSection} .machine=${e.selectedMachine} .machineRuntime=${this.selectedMachineRuntime()} .actions=${this.getDefaultActions()} .onNavigate=${e=>{this.navigateSettings(e)}} .onClose=${()=>{this.closeSettings()}} .onConfigSaved=${e=>{this.applyClientConfig(e)}} .onRefreshMachineRuntime=${e=>this.machines.refreshMachineRuntime(e)}></settings-dialog>`}
3092
- </div>
3093
- `}static{this.styles=Yu}};R([x()],Mx.prototype,`state`,void 0),R([S(`chat-view`)],Mx.prototype,`chatView`,void 0),R([S(`prompt-editor`)],Mx.prototype,`promptEditor`,void 0),R([S(`app-navigation-panel`)],Mx.prototype,`navigationPanel`,void 0),R([S(`#navigation-panel`)],Mx.prototype,`navigationPanelFrame`,void 0),R([S(`#workspace-panel`)],Mx.prototype,`workspacePanelFrame`,void 0),R([x()],Mx.prototype,`activeThemeId`,void 0),R([x()],Mx.prototype,`isRefreshingApp`,void 0),R([x()],Mx.prototype,`sessionCleanupDialog`,void 0),R([x()],Mx.prototype,`settingsSection`,void 0),R([x()],Mx.prototype,`shortcutConfig`,void 0),R([x()],Mx.prototype,`workspaceUploadDefaultFolder`,void 0),Mx=R([y(`pi-web-app`)],Mx);function Nx(){let e=new cf;return e.register({id:`core`,plugin:Rd}),e.register({id:`themes`,plugin:Hd}),e}function Px(e){let t=e.selectedMachine;return t===void 0?{id:`local`,name:`local`,kind:`local`}:{id:t.id,name:t.name,kind:t.kind}}function Fx(e,t){return e.machines!==t.machines||e.machineStatuses!==t.machineStatuses||(e.selectedMachine?.id??`local`)!==(t.selectedMachine?.id??`local`)}function Ix(e,t){return Lx(e,t)}function Lx(e,t){if(e.kind===`local`)return!0;let n=t?.status??e.status;return n===void 0||n===`unknown`||n===`online`}function Rx(e,t){return Object.entries(t).some(([t,n])=>Reflect.get(e,t)!==n)}function zx(e){return ca(e.status,e.activity)}function Bx(e){return e.type===`terminal.created`||e.type===`terminal.exited`||e.type===`terminal.closed`}function Vx(){return{}}function Hx(e,t){return JSON.stringify([e,t])}function Ux(e){return xx[Math.min(e,xx.length-1)]??3e4}function Wx(e){return e instanceof Error?e.message:String(e)}function Gx(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>e!==t))}function Kx(){return new Promise(e=>requestAnimationFrame(()=>{e()}))}function qx(e){switch(e){case`off`:return`No reasoning`;case`minimal`:return`Very brief reasoning (~1k tokens)`;case`low`:return`Light reasoning (~2k tokens)`;case`medium`:return`Moderate reasoning (~8k tokens)`;case`high`:return`Deep reasoning (~16k tokens)`;case`xhigh`:return`Maximum reasoning (~32k tokens)`;default:return}}export{h as _,R as a,Fi as c,x as d,b as f,g,Ye as h,gm as i,Di as l,v as m,_m as n,El as o,y as p,vm as r,Tl as s,Um as t,S as u};