@chainingintention/pi-web-cn 1.202607.5-dev.0 → 1.202607.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/cli.js +283 -315
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/CodeViewer-DxWBEGHy.js +4 -0
- package/dist/client/assets/TerminalPanel-CLBbwrSg.js +184 -0
- package/dist/client/assets/UnifiedDiffViewer-CvVtrOUV.js +39 -0
- package/dist/client/assets/index-CEswQiQV.js +3149 -0
- package/dist/client/assets/vendor-editor-core-vUi74DnD.js +12 -0
- package/dist/client/assets/vendor-editor-languages-DoaXUodB.js +46 -0
- package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +1 -0
- package/dist/client/assets/vendor-terminal-BrP-ENHg.css +1 -0
- package/dist/client/assets/vendor-terminal-D8k4UKM2.js +35 -0
- package/dist/client/index.html +6 -6
- package/dist/client/manifest.webmanifest +4 -4
- package/dist/config.js +221 -9
- package/dist/config.js.map +1 -1
- package/dist/nativeServices/serviceDoctor.js +480 -0
- package/dist/nativeServices/serviceDoctor.js.map +1 -0
- package/dist/nativeServices/serviceInstall.js +35 -0
- package/dist/nativeServices/serviceInstall.js.map +1 -0
- package/dist/nativeServices/servicePlan.js +357 -0
- package/dist/nativeServices/servicePlan.js.map +1 -0
- package/dist/nativeServices/serviceProbe.js +445 -0
- package/dist/nativeServices/serviceProbe.js.map +1 -0
- package/dist/nativeServices/serviceRendering.js +122 -0
- package/dist/nativeServices/serviceRendering.js.map +1 -0
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +11 -0
- package/dist/plugin-api.d.ts +2 -0
- package/dist/server/activeAgentProfileProvider.js +25 -0
- package/dist/server/activeAgentProfileProvider.js.map +1 -0
- package/dist/server/app.js +63 -16
- package/dist/server/app.js.map +1 -1
- package/dist/server/browserMessageProjection.js +56 -0
- package/dist/server/browserMessageProjection.js.map +1 -0
- package/dist/server/configRoutes.js +152 -10
- package/dist/server/configRoutes.js.map +1 -1
- package/dist/server/machines/machineClient.js +19 -9
- package/dist/server/machines/machineClient.js.map +1 -1
- package/dist/server/machines/machinePluginProxyRoutes.js +7 -4
- package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineProxyRoutes.js +16 -4
- package/dist/server/machines/machineProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineRoutes.js +1 -1
- package/dist/server/machines/machineRoutes.js.map +1 -1
- package/dist/server/machines/machineService.js +2 -2
- package/dist/server/machines/machineService.js.map +1 -1
- package/dist/server/managementEmbed.js +28 -11
- package/dist/server/managementEmbed.js.map +1 -1
- package/dist/server/piPackageRoutes.js +7 -3
- package/dist/server/piPackageRoutes.js.map +1 -1
- package/dist/server/piPackageService.js +34 -2
- package/dist/server/piPackageService.js.map +1 -1
- package/dist/server/piWebPluginService.js +48 -12
- package/dist/server/piWebPluginService.js.map +1 -1
- package/dist/server/piWebReleaseLookupCache.js +37 -0
- package/dist/server/piWebReleaseLookupCache.js.map +1 -0
- package/dist/server/piWebStatus.js +48 -49
- package/dist/server/piWebStatus.js.map +1 -1
- package/dist/server/piWebStatusCache.js +19 -6
- package/dist/server/piWebStatusCache.js.map +1 -1
- package/dist/server/realtime/sessionEventHub.js +2 -1
- package/dist/server/realtime/sessionEventHub.js.map +1 -1
- package/dist/server/realtime/sessionEventScope.js +0 -3
- package/dist/server/realtime/sessionEventScope.js.map +1 -1
- package/dist/server/sessiond/sessionDaemonStartup.js +49 -0
- package/dist/server/sessiond/sessionDaemonStartup.js.map +1 -0
- package/dist/server/sessiond.js +102 -70
- package/dist/server/sessiond.js.map +1 -1
- package/dist/server/sessions/authProviderOptions.js +23 -22
- package/dist/server/sessions/authProviderOptions.js.map +1 -1
- package/dist/server/sessions/authRoutes.js +14 -12
- package/dist/server/sessions/authRoutes.js.map +1 -1
- package/dist/server/sessions/authService.js +28 -22
- package/dist/server/sessions/authService.js.map +1 -1
- package/dist/server/sessions/oauthLoginFlowService.js +17 -19
- package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
- package/dist/server/sessions/piSessionManagerGateway.js +22 -21
- package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
- package/dist/server/sessions/piSessionService.js +237 -111
- package/dist/server/sessions/piSessionService.js.map +1 -1
- package/dist/server/sessions/projectAuthService.js +135 -0
- package/dist/server/sessions/projectAuthService.js.map +1 -0
- package/dist/server/sessions/sessionArchiveMigration.js +590 -0
- package/dist/server/sessions/sessionArchiveMigration.js.map +1 -0
- package/dist/server/sessions/sessionArchiveStore.js +7 -4
- package/dist/server/sessions/sessionArchiveStore.js.map +1 -1
- package/dist/server/sessions/sessionRoutes.js +15 -4
- package/dist/server/sessions/sessionRoutes.js.map +1 -1
- package/dist/server/sessions/sessionService.js +2 -0
- package/dist/server/sessions/sessionService.js.map +1 -0
- package/dist/server/sessions/spawnSubsessionTool.js +71 -31
- package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
- package/dist/server/terminals/terminalService.js +2 -2
- package/dist/server/terminals/terminalService.js.map +1 -1
- package/dist/sessiond/activeAgentProfile.js +31 -0
- package/dist/sessiond/activeAgentProfile.js.map +1 -0
- package/dist/sessiond/sessionDaemonClient.js +38 -0
- package/dist/sessiond/sessionDaemonClient.js.map +1 -1
- package/dist/shared/activeAgentProfile.js +76 -0
- package/dist/shared/activeAgentProfile.js.map +1 -0
- package/dist/shared/apiTypes.d.ts +26 -0
- package/dist/shared/apiTypes.js +2 -0
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/capabilities.js +5 -0
- package/dist/shared/capabilities.js.map +1 -1
- package/dist/shared/federatedRoutes.js +1 -0
- package/dist/shared/federatedRoutes.js.map +1 -1
- package/dist/shared/piWebConfigParsing.js +0 -5
- package/dist/shared/piWebConfigParsing.js.map +1 -1
- package/dist/shared/piWebStatusParsing.js +6 -0
- package/dist/shared/piWebStatusParsing.js.map +1 -1
- package/dist/shared/thinkingLevels.d.ts +1 -1
- package/dist/shared/thinkingLevels.js +1 -1
- package/dist/shared/thinkingLevels.js.map +1 -1
- package/docs/config.md +63 -9
- package/docs/plugins.md +18 -5
- package/package.json +35 -31
- package/dist/client/assets/CodeViewer-_Lzl-tA7.js +0 -4
- package/dist/client/assets/TerminalPanel-BVBJC-6w.js +0 -126
- package/dist/client/assets/UnifiedDiffViewer-BwONrl2w.js +0 -34
- package/dist/client/assets/index-Ce8_7l5M.js +0 -3084
- package/dist/client/assets/vendor-editor-core-C7aWiQy0.js +0 -12
- package/dist/client/assets/vendor-editor-languages-EW34FfVy.js +0 -26
- package/dist/client/assets/vendor-editor-legacy-B4QLsWF8.js +0 -1
- package/dist/client/assets/vendor-terminal-DDGTF8rc.css +0 -1
- package/dist/client/assets/vendor-terminal-DjQ08hXu.js +0 -16
|
@@ -0,0 +1,3149 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./CodeViewer-DxWBEGHy.js","./vendor-editor-core-vUi74DnD.js","./vendor-editor-languages-DoaXUodB.js","./vendor-editor-legacy-CYBnW6ZU.js","./TerminalPanel-CLBbwrSg.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)}})}}var _t=`management`;function vt(e=Tt()){return wt(e)===_t}function yt(e=Et()){return vt(e?.search)?`management`:`normal`}function bt(e,t=Et(),n=`management`){return St(e,t,n,!0)}function xt(e,t=Et(),n=`management`){return St(e,t,n,!1)}function St(e,t,n,r){if(n===`normal`||t===void 0)return e;let i=Ct(t);if(i===void 0)return e;let a=new URL(e,t.origin);return a.searchParams.set(`embed`,i.embed),i.token!==void 0&&a.searchParams.set(`token`,i.token),`${a.pathname}${a.search}${r?a.hash:``}`}function Ct(e){if(e===void 0)return;let t=wt(e.search),n=e.searchParams.get(`token`)?.trim();if(t===_t)return{embed:t,...n===void 0||n===``?{}:{token:n}}}function wt(e){if(e===void 0||e===``)return;let t=new URLSearchParams(e).get(`embed`)?.trim();return t===``?void 0:t}function Tt(){return typeof window>`u`?void 0:window.location.search}function Et(){if(globalThis.location===void 0)return;let e=globalThis.location;if(typeof e.href==`string`&&e.href!==``)return new URL(e.href);let t=typeof e.protocol==`string`&&e.protocol!==``?e.protocol:`http:`,n=typeof e.host==`string`&&e.host!==``?e.host:`localhost`,r=typeof e.search==`string`?e.search:``;return new URL(`${t}//${n}/${r}`)}function Dt(e,t=kt()){let n=new URL(t.viteBaseUrl,t.documentBaseUrl);return new URL(At(e),n).toString()}function Ot(e,t=kt()){let n=new URL(Dt(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 kt(){return{viteBaseUrl:`./`,documentBaseUrl:typeof document>`u`?`http://localhost/`:document.baseURI}}function At(e){return e.startsWith(`/`)?`.${e}`:e}var jt=yt();function Mt(e){jt=e}function Nt(e){return Dt(bt(e,void 0,jt))}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(Nt(e),{...n,headers:r});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(Ft(e)??i.statusText)}return t(await i.json())}async function Pt(e,t){let n=await fetch(Nt(e));if(!(n.status===204||n.status===404)){if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(Ft(e)??n.statusText)}return t(await n.json())}}function Ft(e){if(It(e))return typeof e.error==`string`?e.error:void 0}function It(e){return typeof e==`object`&&!!e}function w(e){return typeof e==`object`&&!!e}function T(e){if(!w(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 Lt(e,t){let n=e[t];if(n!==void 0){if(typeof n!=`number`)throw Error(`Expected optional 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 Rt(e,t){if(T(e)[t]!==!0)throw Error(`Expected ${t} response`);return!0}function j(e,t){return t===void 0?{}:{[e]:t}}function zt(e){return(e.split(/[\\/]/u).at(-1)?.toLowerCase()??e.toLowerCase()).replace(/(?:\.[cm]?js|\.exe|\.cmd)$/iu,``)===`pi`}function Bt(e){return!e.includes(`/`)&&!e.includes(`\\`)&&zt(e)}var Vt=new Set([`schemaVersion`,`revision`,`command`,`dir`,`sessionDirEnvKeys`]),Ht=/^sha256:[0-9a-f]{64}$/u,Ut=/^[A-Za-z0-9_][A-Za-z0-9._+-]*$/u,Wt=new Set([`PI_WEB_AGENT_SESSION_DIR`,`PI_CODING_AGENT_SESSION_DIR`]);function Gt(e){if(!Xt(e)||Object.keys(e).some(e=>!Vt.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`||!Ht.test(n))&&!(typeof r!=`string`||!Kt(r))&&!(typeof i!=`string`||!qt(i))&&Yt(a)&&new Set(a).size===a.length&&!(a[0]!==`PI_WEB_AGENT_SESSION_DIR`||a.some(e=>!Wt.has(e))))return Object.freeze({schemaVersion:t,revision:n,command:r,dir:i,sessionDirEnvKeys:Object.freeze([...a])})}function Kt(e){return e!==e.trim()||/[\s;&|`$<>]/u.test(e)?!1:qt(e)?!e.endsWith(`/`)&&!e.endsWith(`\\`):Ut.test(e)}function qt(e){if(e===``||e!==e.trim()||Jt(e))return!1;let t=e.replace(/\\/g,`/`);return t.startsWith(`/`)||/^[A-Za-z]:\//u.test(t)}function Jt(e){for(let t of e){let e=t.charCodeAt(0);if(e<32||e===127)return!0}return!1}function Yt(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`&&e!==``)}function Xt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}var M={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`},Zt=Object.values(M),Qt=new Set(Zt);M.sessionsDeleteArchived,M.sessionsBulkMutations,M.sessionsCleanup,M.sessionsReload,M.sessionsClearQueue,M.sessionsPersistedState,M.promptAttachments,M.workspaceFileSuggestions,M.piPackagesManage,M.selectedMachineSettings,M.agentProfileConfig,M.sessionsDeleteArchived,M.sessionsBulkMutations,M.sessionsCleanup,M.sessionsReload,M.sessionsClearQueue,M.sessionsPersistedState,M.promptAttachments,M.sessionsDeleteArchived,M.sessionsBulkMutations,M.sessionsCleanup,M.sessionsReload,M.sessionsClearQueue,M.sessionsPersistedState,M.promptAttachments,M.workspaceFileSuggestions,M.piPackagesManage,M.selectedMachineSettings,M.agentProfileConfig;function $t(e){return typeof e==`string`&&Qt.has(e)}function en(e,t){return e?.capabilities?.includes(t)===!0}function tn(e){if(!(!Array.isArray(e)||!e.every(e=>typeof e==`string`)))return e.filter($t)}function nn(e){let t=T(e);return{path:E(t,`path`),exists:k(t,`exists`),config:rn(t.config),effectiveConfig:rn(t.effectiveConfig),envOverrides:pn(t.envOverrides)}}function rn(e){let t=T(e);return{...j(`host`,D(t,`host`)),...j(`port`,Lt(t,`port`)),...j(`allowedHosts`,sn(t.allowedHosts)),...j(`shortcuts`,dn(t.shortcuts)),...j(`plugins`,fn(t.plugins)),...j(`normalAuth`,on(t.normalAuth)),...j(`managementEmbed`,mn(t.managementEmbed)),...j(`pathAccess`,cn(t.pathAccess)),...j(`uploads`,un(t.uploads)),...j(`maxUploadBytes`,Lt(t,`maxUploadBytes`)),...j(`spawnSessions`,Bn(t,`spawnSessions`)),...j(`subsessions`,Bn(t,`subsessions`)),...j(`agent`,an(t.agent))}}function an(e){if(e!==void 0){if(!w(e)||Array.isArray(e))throw Error(`Invalid PI WEB agent field`);return{...j(`command`,D(e,`command`)),...j(`dir`,D(e,`dir`))}}}function on(e){if(e!==void 0){if(!w(e)||Array.isArray(e))throw Error(`Invalid PI WEB normalAuth field`);return{...j(`passwordHash`,D(e,`passwordHash`))}}}function sn(e){if(e!==void 0){if(e===!0)return!0;if(Array.isArray(e)&&e.every(e=>typeof e==`string`))return e;throw Error(`Invalid PI WEB allowedHosts field`)}}function cn(e){if(e===void 0)return;if(!w(e)||Array.isArray(e))throw Error(`Invalid PI WEB pathAccess field`);let t=e.allowedPaths;return{...j(`allowedPaths`,ln(t,`pathAccess.allowedPaths`))}}function ln(e,t){if(e!==void 0){if(Array.isArray(e)&&e.every(e=>typeof e==`string`&&e!==``))return e;throw Error(`Invalid PI WEB ${t} field`)}}function un(e){if(e!==void 0){if(!w(e)||Array.isArray(e))throw Error(`Invalid PI WEB uploads field`);return{...j(`defaultFolder`,D(e,`defaultFolder`))}}}function dn(e){if(e!==void 0){if(!w(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 fn(e){if(e!==void 0){if(!w(e)||Array.isArray(e))throw Error(`Invalid PI WEB plugins field`);return Object.fromEntries(Object.entries(e).map(([e,t])=>{if(!w(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&&(!w(r)||Array.isArray(r)))throw Error(`Invalid PI WEB plugin settings field`);return[e,t]}))}}function pn(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:Bn(t,`agentCommand`)??!1,agentDir:Bn(t,`agentDir`)??!1,...Sn(t),agentSessionDir:Bn(t,`agentSessionDir`)??!1}}function mn(e){if(e!==void 0){if(!w(e)||Array.isArray(e))throw Error(`Invalid PI WEB managementEmbed field`);return{...j(`enabled`,Bn(e,`enabled`)),...j(`projectRoot`,D(e,`projectRoot`)),...j(`auth`,hn(e.auth,[`sharedSecretEnv`,`issuer`,`audience`],`managementEmbed.auth`)),...j(`sandbox`,gn(e.sandbox)),...j(`tools`,_n(e.tools))}}}function hn(e,t,n){if(e!==void 0){if(!w(e)||Array.isArray(e))throw Error(`Invalid PI WEB ${n} field`);return Object.fromEntries(t.flatMap(t=>{let n=D(e,t);return n===void 0?[]:[[t,n]]}))}}function gn(e){if(e!==void 0){if(!w(e)||Array.isArray(e))throw Error(`Invalid PI WEB managementEmbed.sandbox field`);return{...j(`pythonExecutable`,D(e,`pythonExecutable`)),...j(`env`,vn(e.env,`managementEmbed.sandbox.env`))}}}function _n(e){if(e!==void 0){if(!w(e)||Array.isArray(e))throw Error(`Invalid PI WEB managementEmbed.tools field`);return{...j(`allow`,ln(e.allow,`managementEmbed.tools.allow`)),...j(`deny`,ln(e.deny,`managementEmbed.tools.deny`)),...j(`permissions`,yn(e.permissions,`managementEmbed.tools.permissions`))}}}function vn(e,t){if(e!==void 0){if(!w(e)||Array.isArray(e)||Object.values(e).some(e=>typeof e!=`string`))throw Error(`Invalid PI WEB ${t} field`);return Object.fromEntries(Object.entries(e).map(([e,n])=>[e,bn(n,t)]))}}function yn(e,t){if(e!==void 0){if(!w(e)||Array.isArray(e)||Object.values(e).some(e=>typeof e!=`boolean`))throw Error(`Invalid PI WEB ${t} field`);return Object.fromEntries(Object.entries(e).map(([e,n])=>[e,xn(n,t)]))}}function bn(e,t){if(typeof e!=`string`)throw Error(`Invalid PI WEB ${t} field`);return e}function xn(e,t){if(typeof e!=`boolean`)throw Error(`Invalid PI WEB ${t} field`);return e}function Sn(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 Cn(e){let t=T(e);return{plugins:A(wn)(t.plugins)}}function wn(e){let t=T(e);return{id:E(t,`id`),module:E(t,`module`),source:E(t,`source`),scope:Tn(t.scope),machineSpecific:zn(t.machineSpecific,`machineSpecific`)??!1,enabled:k(t,`enabled`)}}function Tn(e){if(e!==`bundled`&&e!==`local`&&e!==`user`&&e!==`project`)throw Error(`Invalid PI WEB plugin scope`);return e}function En(e){let t=T(e);return{packageName:E(t,`packageName`),generatedAt:E(t,`generatedAt`),components:On(t.components),release:Nn(t.release),commands:Pn(t.commands),messages:A(Fn)(t.messages)}}function Dn(e){let t=T(e);return{packageName:E(t,`packageName`),generatedAt:E(t,`generatedAt`),components:kn(t.components),capabilities:Ln(t.capabilities)}}function On(e){let t=T(e);return{web:jn(t.web),sessiond:jn(t.sessiond)}}function kn(e){let t=T(e);return{web:An(t.web),sessiond:An(t.sessiond)}}function An(e){let t=T(e),n=In(t.component),r=t.activeAgentProfile,i=r===void 0?void 0:Gt(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:Ln(t.capabilities),...j(`activeAgentProfile`,i),...j(`error`,D(t,`error`))}}function jn(e){let t=T(e);return{component:In(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`,Mn(t.installation)),...j(`error`,D(t,`error`))}}function Mn(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 Nn(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 Pn(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 Fn(e){let t=T(e);return{id:E(t,`id`),severity:Rn(t.severity),title:E(t,`title`),body:E(t,`body`),...j(`command`,D(t,`command`))}}function In(e){if(e!==`web`&&e!==`sessiond`)throw Error(`Invalid PI WEB service component`);return e}function Ln(e){let t=tn(e);if(t===void 0)throw Error(`Invalid PI WEB capabilities`);return t}function Rn(e){if(e!==`info`&&e!==`warning`&&e!==`error`)throw Error(`Invalid PI WEB status severity`);return e}function zn(e,t){if(e!==void 0){if(typeof e!=`boolean`)throw Error(`Expected optional boolean field: ${t}`);return e}}function Bn(e,t){let n=e[t];if(n!==void 0){if(typeof n!=`boolean`)throw Error(`Invalid PI WEB ${t} field`);return n}}function Vn(e){let t=T(e);return A(Hn)(t.machines)}function Hn(e){let t=T(e),n=Gn(t,`kind`),r=D(t,`baseUrl`),i=Kn(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 Un(e){let t=T(e),n=Kn(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:jn(t.web)},...t.sessiond===void 0?{}:{sessiond:jn(t.sessiond)},...r===void 0?{}:{error:r}}}function Wn(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:kn(t.components)},...t.capabilities===void 0?{}:{capabilities:Ln(t.capabilities)},...n===void 0?{}:{error:n}}}function Gn(e,t){let n=E(e,t);if(n!==`local`&&n!==`remote`)throw Error(`Expected machine kind field: ${t}`);return n}function Kn(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 qn(e){let t=T(e);return{configured:k(t,`configured`),authenticated:k(t,`authenticated`)}}function Jn(e){if(!Array.isArray(e))throw Error(`Expected array response`);return e}function Yn(e,t){if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw Error(`Expected string array field: ${t}`);return e}function Xn(e,t){if(e!==void 0){if(typeof e!=`boolean`)throw Error(`Expected optional boolean field: ${t}`);return e}}function Zn(e){if(Array.isArray(e))return{messages:e,start:0,total:e.length};let t=T(e);return{messages:Jn(t.messages),start:O(t,`start`),total:O(t,`total`)}}function Qn(e){let t=T(e);return{id:E(t,`id`),name:E(t,`name`),path:E(t,`path`),createdAt:E(t,`createdAt`)}}function $n(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`,er(t.effectiveConfig))}}function er(e){if(e!==void 0){if(!w(e)||Array.isArray(e))throw Error(`Invalid workspace effectiveConfig field`);return{...j(`uploads`,Xr(e.uploads))}}}function tr(e){return{path:E(T(e),`path`)}}function nr(e){let t=T(e);if(t.deleted!==!0)throw Error(`Expected deleted response`);return{deleted:!0,path:E(t,`path`)}}function rr(e){let t=T(e),n=D(t,`name`),r=Xn(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 ir(e){let t=T(e);return{sessionId:E(t,`sessionId`),...j(`persisted`,Xn(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(pr)(t.queuedMessages),...j(`messageCount`,Lt(t,`messageCount`)),tokens:mr(t.tokens),cost:O(t,`cost`),...gr(t.model),...Ar(t.contextUsage),...j(`thinkingLevel`,D(t,`thinkingLevel`))}}function ar(e){let t=T(e),n=t.skippedBusySessionIds===void 0?void 0:Yn(t.skippedBusySessionIds,`skippedBusySessionIds`);return{generatedAt:E(t,`generatedAt`),thresholds:ur(t.thresholds),projects:A(dr)(t.projects),totals:fr(t.totals),...n===void 0?{}:{skippedBusySessionIds:n}}}function or(e){let t=T(e);return{...ar(t),archivedSessionIds:Yn(t.archivedSessionIds,`archivedSessionIds`),deletedSessionIds:Yn(t.deletedSessionIds,`deletedSessionIds`)}}function sr(e){let t=T(e);if(t.archived!==!0)throw Error(`Expected bulk archived response`);return{archived:!0,archivedSessionIds:Yn(t.archivedSessionIds,`archivedSessionIds`),failures:A(lr)(t.failures),generatedAt:E(t,`generatedAt`)}}function cr(e){let t=T(e);if(t.deleted!==!0)throw Error(`Expected bulk deleted response`);return{deleted:!0,deletedSessionIds:Yn(t.deletedSessionIds,`deletedSessionIds`),failures:A(lr)(t.failures),generatedAt:E(t,`generatedAt`)}}function lr(e){let t=T(e);return{sessionId:E(t,`sessionId`),error:E(t,`error`)}}function ur(e){let t=T(e);return{...j(`archiveIdleDays`,Lt(t,`archiveIdleDays`)),...j(`deleteArchivedDays`,Lt(t,`deleteArchivedDays`))}}function dr(e){let t=T(e);return{cwd:E(t,`cwd`),archiveCount:O(t,`archiveCount`),deleteCount:O(t,`deleteCount`)}}function fr(e){let t=T(e);return{archiveCount:O(t,`archiveCount`),deleteCount:O(t,`deleteCount`)}}function pr(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 mr(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 hr(e){let t=T(e);return{...j(`provider`,D(t,`provider`)),...j(`id`,D(t,`id`)),...j(`name`,D(t,`name`)),...j(`contextWindow`,Lt(t,`contextWindow`)),...j(`reasoning`,t.reasoning)}}function gr(e){return e===void 0?{}:{model:hr(e)}}function _r(e){let t=T(e);return{models:A(hr)(t.models)}}function vr(e){if(typeof e!=`string`)throw Error(`Invalid thinking level`);return e}function yr(e){let t=T(e);return{levels:A(vr)(t.levels)}}function br(e){if(e!==`oauth`&&e!==`api_key`)throw Error(`Invalid auth type`);return e}function xr(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 Sr(e){let t=T(e),n=t.source===void 0?void 0:xr(t.source);return{configured:k(t,`configured`),...j(`source`,n),...j(`label`,D(t,`label`))}}function Cr(e){let t=T(e);return{id:E(t,`id`),name:E(t,`name`),authType:br(t.authType),status:Sr(t.status)}}function wr(e){let t=T(e);return{providers:A(Cr)(t.providers)}}function Tr(e){let t=T(e);return{flowId:E(t,`flowId`),providerId:E(t,`providerId`),providerName:E(t,`providerName`),status:Er(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`,Dr(t.auth)),...j(`prompt`,Or(t.prompt)),...j(`select`,kr(t.select))}}function Er(e){if(e!==`running`&&e!==`complete`&&e!==`error`&&e!==`cancelled`)throw Error(`Invalid OAuth flow status`);return e}function Dr(e){if(e===void 0)return;let t=T(e);return{url:E(t,`url`),...j(`instructions`,D(t,`instructions`))}}function Or(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`);return{requestId:E(t,`requestId`),message:E(t,`message`),kind:n,...j(`placeholder`,D(t,`placeholder`)),...t.allowEmpty===!0?{allowEmpty:!0}:{}}}function kr(e){if(e===void 0)return;let t=T(e);return{requestId:E(t,`requestId`),message:E(t,`message`),options:A(ri)(t.options)}}function Ar(e){if(e===void 0)return{};let t=T(e);return{contextUsage:{tokens:gi(t,`tokens`),contextWindow:O(t,`contextWindow`),percent:gi(t,`percent`)}}}function jr(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 Mr(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 Nr(e){let t=T(e);return{path:E(t,`path`),entries:A(Pr)(t.entries),scannedAt:E(t,`scannedAt`),truncated:k(t,`truncated`)}}function Pr(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`,Lt(t,`size`)),...j(`modifiedAt`,D(t,`modifiedAt`))}}function Fr(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`,zr(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 Ir(e){let t=T(e);return{path:E(t,`path`),size:O(t,`size`),modifiedAt:E(t,`modifiedAt`),created:k(t,`created`)}}function Lr(e){let t=T(e);return{path:E(t,`path`),existed:k(t,`existed`)}}function Rr(e){let t=T(e);return{fromPath:E(t,`fromPath`),toPath:E(t,`toPath`),size:O(t,`size`),modifiedAt:E(t,`modifiedAt`)}}function zr(e){if(e!==void 0){if(e!==`image`)throw Error(`Invalid file media type`);return e}}function Br(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`,Lt(t,`ahead`)),...j(`behind`,Lt(t,`behind`)),files:A(Vr)(t.files)}}function Vr(e){let t=T(e);return{path:E(t,`path`),...j(`oldPath`,D(t,`oldPath`)),index:Hr(t.index),workingTree:Hr(t.workingTree)}}function Hr(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 Ur(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 Wr(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`,Lt(t,`exitCode`)),...j(`commandRunId`,D(t,`commandRunId`))}}function Gr(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:Kr(t.status),...j(`exitCode`,Lt(t,`exitCode`)),createdAt:E(t,`createdAt`),...j(`startedAt`,D(t,`startedAt`)),...j(`completedAt`,D(t,`completedAt`)),metadata:qr(t.metadata,`metadata`)}}function Kr(e){if(e!==`queued`&&e!==`running`&&e!==`succeeded`&&e!==`failed`)throw Error(`Invalid terminal command run status`);return e}function qr(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 Jr(e){let t=T(e);return{cwd:E(t,`cwd`),hasSessionActivity:k(t,`hasSessionActivity`),hasTerminalActivity:k(t,`hasTerminalActivity`),updatedAt:E(t,`updatedAt`)}}function Yr(e){let t=T(e);return{workspaces:A(Jr)(t.workspaces),generatedAt:E(t,`generatedAt`)}}function Xr(e){if(e!==void 0){if(!w(e)||Array.isArray(e))throw Error(`Invalid uploads field`);return{...j(`defaultFolder`,D(e,`defaultFolder`))}}}function Zr(e){let t=T(e);return{packages:A($r)(t.packages)}}function Qr(e){let t=T(e),n=D(t,`source`),r=t.scope===void 0?void 0:ei(t.scope),i=Xn(t.removed,`removed`);return{action:ti(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:ei(t.scope),filtered:k(t,`filtered`),...j(`installedPath`,D(t,`installedPath`))}}function ei(e){if(e!==`user`&&e!==`project`)throw Error(`Invalid Pi package scope`);return e}function ti(e){if(e!==`install`&&e!==`remove`&&e!==`update`)throw Error(`Invalid Pi package mutation action`);return e}function ni(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(ri)(t.options)};if(n===`done`)return{type:n,...j(`message`,D(t,`message`)),...ii(t.session),...j(`promptDraft`,D(t,`promptDraft`))};throw Error(`Invalid command result type`)}function ri(e){let t=T(e);return{value:E(t,`value`),label:E(t,`label`),...j(`description`,D(t,`description`))}}function ii(e){return e===void 0?{}:{session:rr(e)}}function ai(e){return{accepted:Rt(e,`accepted`)}}function oi(e){let t=T(e);return A(si)(t.attachments)}function si(e){let t=T(e);return{path:E(t,`path`),mimeType:E(t,`mimeType`),size:O(t,`size`)}}function ci(e){return{closed:Rt(e,`closed`)}}function li(e){return{aborted:Rt(e,`aborted`)}}function ui(e){return{stopped:Rt(e,`stopped`)}}function di(e){let t=T(e);if(t.archived!==!0)throw Error(`Expected archived response`);let n=t.sessionIds===void 0?void 0:Yn(t.sessionIds,`sessionIds`),r=Lt(t,`archivedCount`),i=Lt(t,`skippedAlreadyArchivedCount`);return{archived:!0,...n===void 0?{}:{sessionIds:n},...r===void 0?{}:{archivedCount:r},...i===void 0?{}:{skippedAlreadyArchivedCount:i}}}function fi(e){return{restored:Rt(e,`restored`)}}function pi(e){return{deleted:Rt(e,`deleted`)}}function mi(e){return{detached:Rt(e,`detached`)}}function hi(e){return{reloaded:Rt(e,`reloaded`)}}function gi(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 _i(e){return typeof e==`string`?e:e.id}function vi(e){return typeof e==`string`?void 0:e.cwd}function yi(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 bi(e,t,n=`local`){let r=new URLSearchParams,i=vi(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(_i(e))}/messages${a===``?``:`?${a}`}`}function xi(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`),Dt(bt(`${`api/machines/${encodeURIComponent(r?.machineId??`local`)}`}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file?${i.toString()}`))}function Si(e,t,n,r){let i=new URLSearchParams;return i.set(`path`,n),r?.modifiedAt!==void 0&&i.set(`v`,r.modifiedAt),Dt(bt(`${`api/machines/${encodeURIComponent(r?.machineId??`local`)}`}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file/preview?${i.toString()}`))}function Ci(e,t,n,r){let i=new URLSearchParams;return i.set(`path`,n),Dt(bt(`${`api/machines/${encodeURIComponent(r?.machineId??`local`)}`}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file/download?${i.toString()}`))}var N=(e=`local`)=>`api/machines/${encodeURIComponent(e)}`;function wi(e){return typeof e==`string`?e:e.id}function Ti(e){return typeof e==`string`?void 0:e.cwd}function Ei(e,t=`local`){return`${N(t)}/sessions/${encodeURIComponent(wi(e))}`}function P(e,t,n=`local`){return`${Ei(e,n)}/${t}`}function Di(e,t,n=`local`){return`${P(e,t,n)}${ki(e)}`}function Oi(e,t=`local`){return`${Ei(e,t)}${ki(e)}`}function ki(e){let t=Ti(e);return t===void 0||t===``?``:`?${new URLSearchParams({cwd:t}).toString()}`}function F(e,t={}){let n=Ti(e);return JSON.stringify(n===void 0||n===``?t:{cwd:n,...t})}function Ai(e){return JSON.stringify({sessions:e.map(ji)})}function ji(e){let t=wi(e),n=Ti(e);return n===void 0||n===``?{id:t}:{id:t,cwd:n}}function Mi(e,t){let n=new URLSearchParams;t.projectId!==void 0&&n.set(`projectId`,t.projectId);let r=n.toString();return`${N(t.machineId)}/auth/${e}${r===``?``:`?${r}`}`}function Ni(e){return e===`local`?`api/pi-web/status`:`${N(e)}/pi-web/status`}var Pi={piWebStatus:(e=`local`)=>C(Ni(e),En),checkForUpdates:(e=`local`)=>C(`${Ni(e)}?refresh=1`,En,{cache:`no-store`}),piWebRuntime:()=>C(`api/pi-web/runtime`,Dn)},Fi={machines:()=>C(`api/machines`,Vn),addMachine:e=>C(`api/machines`,Hn,{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`,Un),runtime:(e,t=!1)=>C(`api/machines/${encodeURIComponent(e)}/runtime${t?`?refresh=1`:``}`,Wn,t?{cache:`no-store`}:{})};function Ii(e){return e===void 0?`api/config`:`${N(e)}/config`}function Li(e){return e===void 0?`api/plugins`:`${N(e)}/plugins`}var Ri={config:e=>C(Ii(e),nn),saveConfig:(e,t)=>C(Ii(t),nn,{method:`PUT`,body:JSON.stringify({config:e})})},zi={status:()=>C(`/api/normal-auth/status`,qn),setup:e=>C(`/api/normal-auth/setup`,ai,{method:`POST`,body:JSON.stringify({password:e})}),login:e=>C(`/api/normal-auth/login`,ai,{method:`POST`,body:JSON.stringify({password:e})}),changePassword:(e,t)=>C(`/api/normal-auth/change-password`,ai,{method:`POST`,body:JSON.stringify({currentPassword:e,newPassword:t})})},Bi={plugins:e=>C(Li(e),Cn)};function Vi(e=``,t){let n=t===void 0?`api/pi-packages`:`${N(t)}/pi-packages`;return e===``?n:`${n}/${e}`}var Hi={packages:e=>C(Vi(``,e),Zr),install:(e,t)=>{let n={source:e};return C(Vi(`install`,t),Qr,{method:`POST`,body:JSON.stringify(n)})},remove:(e,t,n)=>{let r=t===void 0?{source:e}:{source:e,scope:t};return C(Vi(`remove`,n),Qr,{method:`POST`,body:JSON.stringify(r)})},update:(e,t)=>{let n=e===void 0?void 0:{source:e};return C(Vi(`update`,t),Qr,{method:`POST`,...n===void 0?{}:{body:JSON.stringify(n)}})}},Ui={workspaceActivity:(e=`local`)=>C(`${N(e)}/activity`,Yr)},Wi={projects:(e=`local`)=>C(`${N(e)}/projects`,A(Qn)),addProject:(e,t,n,r=`local`)=>C(`${N(r)}/projects`,Qn,{method:`POST`,body:JSON.stringify({path:e,name:t,create:n})}),closeProject:(e,t=`local`)=>C(`${N(t)}/projects/${encodeURIComponent(e)}`,ci,{method:`DELETE`}),projectDirectories:(e,t=`local`)=>C(`${N(t)}/project-directories?q=${encodeURIComponent(e)}`,A(Mr))};function Gi(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(`${N(a)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file?${o.toString()}`,Ir,{method:`PUT`,body:c,headers:{"Content-Type":s?`application/octet-stream`:`text/plain`}})}var Ki={workspaces:(e,t=`local`)=>C(`${N(t)}/projects/${encodeURIComponent(e)}/workspaces`,A($n)),deleteWorkspace:(e,t,n=`local`)=>C(`${N(n)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}`,Gr,{method:`DELETE`}),workspaceTree:(e,t,n=``,r=`local`)=>C(`${N(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/tree?path=${encodeURIComponent(n)}`,Nr),workspaceFile:(e,t,n,r=`local`)=>C(`${N(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file?path=${encodeURIComponent(n)}`,Fr),optionalWorkspaceFile:(e,t,n,r=`local`)=>Pt(`${N(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file?path=${encodeURIComponent(n)}&optional=true`,Fr),createWorkspaceFile:(e,t,n,r=`local`)=>Gi(e,t,n,new Uint8Array,void 0,r),writeWorkspaceFile:Gi,deleteWorkspaceFile:(e,t,n,r=`local`)=>{let i=new URLSearchParams({path:n});return C(`${N(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file?${i.toString()}`,Lr,{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(`${N(a)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/file/move?${o.toString()}`,Rr,{method:`POST`})},createWorkspaceDirectory:(e,t,n,r=`local`)=>C(`${N(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/directory`,tr,{method:`POST`,body:JSON.stringify({path:n})}),moveWorkspaceDirectory:(e,t,n,r,i=`local`)=>C(`${N(i)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/directory`,tr,{method:`PATCH`,body:JSON.stringify({fromPath:n,toPath:r})}),deleteWorkspaceDirectory:(e,t,n,r=`local`)=>C(`${N(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/directory?path=${encodeURIComponent(n)}`,nr,{method:`DELETE`}),downloadWorkspaceFile:(e,t,n,r=`local`)=>Qi(e,t,n,r)},qi={sessions:(e,t=`local`)=>C(`${N(t)}/sessions?cwd=${encodeURIComponent(e)}`,A(rr)),startSession:(e,t=`local`)=>C(`${N(t)}/sessions`,rr,{method:`POST`,body:JSON.stringify({cwd:e})}),cleanupPreview:(e,t=`local`)=>C(`${N(t)}/sessions/cleanup/preview`,ar,{method:`POST`,body:JSON.stringify(e)}),cleanup:(e,t=`local`)=>C(`${N(t)}/sessions/cleanup`,or,{method:`POST`,body:JSON.stringify(e)}),archiveMany:(e,t=`local`)=>C(`${N(t)}/sessions/bulk/archive`,sr,{method:`POST`,body:Ai(e)}),deleteArchivedMany:(e,t=`local`)=>C(`${N(t)}/sessions/bulk/delete-archived`,cr,{method:`POST`,body:Ai(e)}),messages:(e,t,n=`local`)=>C(bi(e,t,n),Zn),status:(e,t=`local`)=>C(Di(e,`status`,t),ir),models:(e,t=`local`)=>C(Di(e,`models`,t),_r),setModel:(e,t,n,r=`local`)=>C(P(e,`model`,r),ir,{method:`POST`,body:F(e,{provider:t,modelId:n})}),cycleModel:(e,t,n=`local`)=>C(P(e,`model/cycle`,n),ir,{method:`POST`,body:F(e,{direction:t})}),thinkingLevels:(e,t=`local`)=>C(Di(e,`thinking-levels`,t),yr),setThinkingLevel:(e,t,n=`local`)=>C(P(e,`thinking-level`,n),ir,{method:`POST`,body:F(e,{level:t})}),cycleThinkingLevel:(e,t=`local`)=>C(P(e,`thinking-level/cycle`,t),ir,{method:`POST`,body:F(e)}),commands:(e,t=`local`)=>C(Di(e,`commands`,t),A(jr)),prompt:(e,t,n,r=`local`,i)=>C(P(e,`prompt`,r),ai,{method:`POST`,body:F(e,{text:t,...n===void 0?{}:{streamingBehavior:n},...i!==void 0&&i.length>0?{attachments:i}:{}})}),saveAttachments:(e,t,n=`local`,r)=>C(P(e,`attachments`,n),oi,{method:`POST`,body:F(e,{attachments:t,...r===void 0?{}:{folder:r}})}),shell:(e,t,n=`local`)=>C(P(e,`shell`,n),ai,{method:`POST`,body:F(e,{text:t})}),runCommand:(e,t,n=`local`)=>C(P(e,`commands/run`,n),ni,{method:`POST`,body:F(e,{text:t})}),respondToCommand:(e,t,n,r=`local`)=>C(P(e,`commands/respond`,r),ni,{method:`POST`,body:F(e,{requestId:t,value:n})}),abort:(e,t=`local`)=>C(P(e,`abort`,t),li,{method:`POST`,body:F(e)}),stop:(e,t=`local`)=>C(P(e,`stop`,t),ui,{method:`POST`,body:F(e)}),archive:(e,t=`local`)=>C(P(e,`archive`,t),di,{method:`POST`,body:F(e)}),archiveWithDescendants:(e,t=`local`)=>C(P(e,`archive-tree`,t),di,{method:`POST`,body:F(e)}),restore:(e,t=`local`)=>C(P(e,`restore`,t),fi,{method:`POST`,body:F(e)}),deleteArchived:(e,t=`local`)=>C(Oi(e,t),pi,{method:`DELETE`}),detachParent:(e,t=`local`)=>C(P(e,`detach-parent`,t),mi,{method:`POST`,body:F(e)}),reloadSession:(e,t=`local`)=>C(P(e,`reload`,t),hi,{method:`POST`,body:F(e)}),clearQueue:(e,t=`local`)=>C(P(e,`queue/clear`,t),ir,{method:`POST`,body:F(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),e.projectId!==void 0&&t.set(`projectId`,e.projectId);let n=t.toString();return C(`${N(e.machineId)}/auth/providers${n===``?``:`?${n}`}`,wr)},saveApiKey:(e,t,n)=>C(Mi(`api-key`,n),ai,{method:`POST`,body:JSON.stringify({providerId:e,key:t})}),logoutProvider:(e,t)=>C(Mi(`logout`,t),ai,{method:`POST`,body:JSON.stringify({providerId:e})}),startOAuthLogin:(e,t)=>C(Mi(`oauth`,t),Tr,{method:`POST`,body:JSON.stringify({providerId:e})}),oauthFlow:(e,t)=>C(Mi(`oauth/${encodeURIComponent(e)}`,t),Tr),respondOAuthFlow:(e,t,n,r)=>C(Mi(`oauth/${encodeURIComponent(e)}/respond`,r),Tr,{method:`POST`,body:JSON.stringify({requestId:t,value:n})}),cancelOAuthFlow:(e,t)=>C(Mi(`oauth/${encodeURIComponent(e)}/cancel`,t),Tr,{method:`POST`})},Ji={terminals:(e,t,n=`local`)=>C(`${N(n)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals`,A(Wr)),startTerminal:(e,t,n,r=`local`)=>C(`${N(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals`,Wr,{method:`POST`,body:JSON.stringify(n??{})}),closeWorkspaceTerminals:(e,t,n=`local`)=>C(`${N(n)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals`,ci,{method:`DELETE`}),closeTerminal:(e,t,n,r=`local`)=>C(`${N(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals/${encodeURIComponent(n)}`,ci,{method:`DELETE`}),continueTerminal:(e,t,n,r=`local`)=>C(`${N(r)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals/${encodeURIComponent(n)}/continue`,Wr,{method:`POST`}),runTerminalCommand:(e,t,n=`local`)=>C(`${N(n)}/projects/${encodeURIComponent(t.workspace.projectId)}/workspaces/${encodeURIComponent(t.workspace.id)}/terminal-command-runs`,Gr,{method:`POST`,body:JSON.stringify({origin:e,title:t.title,command:t.command,metadata:t.metadata??{}})}),listCommandRuns:(e,t=`local`)=>C(`${N(t)}/terminal-command-runs${Xi(e)}`,A(Gr)),getCommandRun:(e,t=`local`)=>Yi(e,t),cancelCommandRun:(e,t=`local`)=>C(`${N(t)}/terminal-command-runs/${encodeURIComponent(e)}/cancel`,Gr,{method:`POST`})};async function Yi(e,t){return Pt(`${N(t)}/terminal-command-runs/${encodeURIComponent(e)}`,Gr)}function Xi(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 Zi(e){if(!$i(e))return;let t=e.error;return typeof t==`string`?t:void 0}async function Qi(e,t,n,r){let i=await fetch(Ci(e,t,n,{machineId:r}));if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(Zi(e)??i.statusText)}let a=await i.blob(),o=URL.createObjectURL(a),s=document.createElement(`a`);s.href=o;let c=n.split(`/`).pop();s.download=c===void 0||c===``?`download`:c,document.body.append(s),s.click(),s.remove(),URL.revokeObjectURL(o)}function $i(e){return typeof e==`object`&&!!e}var ea={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(`${N(n.machineId)}/projects/${encodeURIComponent(n.projectId)}/workspaces/${encodeURIComponent(n.workspaceId)}/files?${r.toString()}`,A(Mr)):(r.set(`cwd`,e),C(`${N(n.machineId)}/files?${r.toString()}`,A(Mr)))}},ta={gitStatus:(e,t,n=`local`)=>C(`${N(n)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/git/status`,Br),gitDiff:(e,t,n,r=`local`)=>C(yi(r,e,t,n),Ur)},I={...Pi,...Fi,...Ri,...zi,...Bi,...Hi,...Ui,...Wi,...Ki,...qi,...Ji,...ea,...ta};function na(e,t=`local`,n=yt()){let r=typeof e==`string`?void 0:e.cwd,i=r===void 0||r===``?``:`?${new URLSearchParams({cwd:r}).toString()}`,a=typeof e==`string`?e:e.id,o=xt(`${aa(t)}/sessions/${encodeURIComponent(a)}/events${i}`,void 0,n);return new WebSocket(Ot(o))}function ra(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(Ot(`${aa(i)}/projects/${encodeURIComponent(e)}/workspaces/${encodeURIComponent(t)}/terminals/${encodeURIComponent(n)}/socket${a}`))}function ia(e=`local`,t=yt()){let n=xt(`${aa(e)}/events`,void 0,t);return new WebSocket(Ot(n))}function aa(e){return`api/machines/${encodeURIComponent(e)}`}var oa=`.pi-web/uploads`,sa=class extends Error{constructor(e=`Workspace upload cancelled`){super(e),this.name=`WorkspaceUploadCancelledError`}},ca=class extends Error{constructor(e,t){super(ya(e)),this.name=`WorkspaceUploadBatchError`,this.failures=e.map(e=>({...e})),this.responses=t.map(e=>({...e}))}};function la(e){return e?.uploads?.defaultFolder??`.pi-web/uploads`}function ua(e,t){return e?.uploads?.defaultFolder??t}function da(e,t){let n=Sa(e,`upload destination`,{allowEmpty:!0}),r=Sa(t,`upload file name`,{allowEmpty:!1});return n===``?r:`${n}/${r}`}function fa(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`,xi(e,t,n.path,ha(r)),!0),i.responseType=`json`,i.setRequestHeader(`Content-Type`,(n.contentType??n.file.type)||`application/octet-stream`),i.upload.onprogress=e=>{r.onProgress?.(ga(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(Ir(wa(i)))}catch(e){l(e instanceof Error?e:Error(String(e)))}return}l(Error(Ta(i)))},i.onerror=()=>{l(Error(`Workspace upload failed`))},i.onabort=()=>{l(new sa(o?void 0:`Workspace upload aborted`))},i.send(n.file)}),cancel:()=>{a||(o=!0,i.abort())}}}function pa(e,t,n,r={}){let i=r.destinationFolder??`.pi-web/uploads`,a=n.map((e,t)=>({index:t,name:e.name,path:da(i,e.name),loaded:0,total:e.size,percent:va(0,e.size),lengthComputable:!0,done:!1})),o,s=0,c={requested:!1},l=()=>{r.onProgress?.(_a(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 sa;s=d;let f=n[d],p=a[d];if(!(f===void 0||p===void 0)){o=fa(e,t,{path:p.path,file:f},{...ma(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(xa(e,c))throw e;let t=ba(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 ca(u,i);return i})(),cancel:()=>{c.requested=!0,o?.cancel()}}}function ma(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 ha(e){return{...e.createDirs===void 0?{}:{createDirs:e.createDirs},...e.overwrite===void 0?{}:{overwrite:e.overwrite},...e.machineId===void 0?{}:{machineId:e.machineId}}}function ga(e,t){let n=e.lengthComputable?e.total:t;return{loaded:e.loaded,total:n,percent:va(e.loaded,n),lengthComputable:e.lengthComputable}}function _a(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:va(i,r),done:n}}function va(e,t){return t<=0?e<=0?0:1:Math.max(0,Math.min(1,e/t))}function ya(e){return e.length===1?e[0]?.error??`Workspace upload failed`:`${String(e.length)} files failed to upload`}function ba(e){return e instanceof Error?e.message:String(e)}function xa(e,t){return t.requested||e instanceof sa}function Sa(e,t,n){let r=e.trim();if(r===``){if(n.allowEmpty)return``;throw Error(`${t} must not be empty`)}if(Ca(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 Ca(e){let t=e.replace(/\\/g,`/`);return t.startsWith(`/`)||/^[A-Za-z]:\//u.test(t)}function wa(e){return e.response!==void 0&&e.response!==null&&e.response!==``?e.response:e.responseText===``?{}:JSON.parse(e.responseText)}function Ta(e){let t=Ea(e);return Da(t)&&typeof t.error==`string`?t.error:e.statusText||`HTTP ${String(e.status)}`}function Ea(e){try{return wa(e)}catch{return}}function Da(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 ka(){return{machines:[],selectedMachine:void 0,isLoadingMachines:!1,machineStatuses:{},machineRuntimes:{},projects:[],workspaces:[],sessions:[],messages:[],messagePageStart:0,messagePageEnd:0,messagePageTotal:0,isLoadingEarlierMessages:!1,isReceivingPartialStream:!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 Aa(e,t){return t?.phase===`active`||e?.isStreaming===!0||e?.isBashRunning===!0||e?.isCompacting===!0||(e?.pendingMessageCount??0)>0}function ja(e){return e!==void 0&&(e.hasSessionActivity||e.hasTerminalActivity)}function Ma(e,t){return`${e}:${t}`}function Na(e,t){return`${e}:${t}`}function L(e){return e.selectedMachine?.id??`local`}var Pa=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}},Fa=class{constructor(e,t,n={}){this.getState=e,this.setState=t,this.refreshes=new Pa,this.api=n.api??Ui}refresh(e=L(this.getState())){return this.refreshes.request(e,async()=>{this.applyMachineActivitySnapshot(e,Ia(await this.api.workspaceActivity(e)))})}applyWorkspaceActivity(e,t=L(this.getState())){let n=this.getState(),r=L(n)===t,i=La(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},...L(n)===e?{workspaceActivities:t}:{}})}};function Ia(e){let t={};for(let n of e.workspaces)ja(n)&&(t[n.cwd]=n);return t}function La(e,t){let n={...e};return ja(t)?(n[t.cwd]=t,n):Object.fromEntries(Object.entries(n).filter(([e])=>e!==t.cwd))}var Ra=class{constructor(e,t,n,r){this.getState=e,this.setState=t,this.applyStatus=n,this.api=r.api??I,this.pollIntervalMs=r.pollIntervalMs??1e3,this.scope=r.scope}dispose(){this.stopPolling()}handleSlashCommand(e){let t=za(e);return t===void 0?!1:(t.command===`login`?this.openLogin(t.providerId):this.openLogout(t.providerId),!0)}async openLogin(e){let t=this.captureTarget();if(t!==void 0){if(e!==void 0&&e!==``){await this.openLoginProvider(e,t);return}this.setState({authDialog:{step:`method`,target:t}})}}async chooseLoginMethod(e){let t=this.getState().authDialog;if(t?.step===`method`)try{let{providers:n}=await this.api.authProviders({mode:`login`,authType:e,...t.target});this.setState({authDialog:{step:`providers`,mode:`login`,authType:e,providers:n,target:t.target}})}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`?await this.startOAuth(r,n.target):this.setState({authDialog:{step:`apiKey`,provider:r,value:``,target:n.target}}))}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{let n=e.target;await this.api.saveApiKey(e.provider.id,t,n),this.closeDialog(),this.refreshStatus(n)}catch(t){this.setState({authDialog:{...e,saving:!1,error:String(t)}})}}async openLogout(e){let t=this.captureTarget();if(t!==void 0)try{let{providers:n}=await this.api.authProviders({mode:`logout`,...t});if(e!==void 0&&e!==``){let r=n.find(t=>t.id===e);r!==void 0&&!this.rejectRemoteOAuth(`logout`,r,t)?await this.logoutProviderForTarget(r.id,t):r===void 0&&this.setState({error:`No stored credentials for ${e}`});return}this.setState({authDialog:{step:`logout`,providers:n,target:t}})}catch(e){this.setState({error:String(e)})}}async logoutProvider(e){let t=this.getState().authDialog;if(t?.step!==`logout`)return;let n=t.providers.find(t=>t.id===e);n===void 0||this.rejectRemoteOAuth(`logout`,n,t.target)||await this.logoutProviderForTarget(e,t.target)}async logoutProviderForTarget(e,t){try{await this.api.logoutProvider(e,t),this.closeDialog(),this.refreshStatus(t)}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=e??t.inputValue??``,i={...t};delete i.error,this.setState({authDialog:{...i,responding:!0}});try{let e=await this.api.respondOAuthFlow(t.flow.flowId,n.requestId,r,t.target);this.updateOAuthFlow(e,t.target)}catch(e){this.setState({authDialog:{...t,responding:!1,error:String(e)}})}}async cancelOAuth(){let e=this.getState().authDialog;if(e?.step!==`oauth`){this.closeDialog();return}this.stopPolling();try{await this.api.cancelOAuthFlow(e.flow.flowId,e.target)}catch{}this.closeDialog()}closeDialog(){this.stopPolling(),this.setState({authDialog:void 0})}async openLoginProvider(e,t){try{let{providers:n}=await this.api.authProviders({mode:`login`,...t}),r=n.filter(t=>t.id===e);if(r.length===0){this.setState({error:`Auth provider not found: ${e}`});return}if(r.length>1){this.setState({authDialog:{step:`providers`,mode:`login`,providers:r,target:t}});return}let i=r[0];if(i===void 0)return;i.authType===`oauth`?await this.startOAuth(i,t):this.setState({authDialog:{step:`apiKey`,provider:i,value:``,target:t}})}catch(e){this.setState({error:String(e)})}}async startOAuth(e,t){if(!this.rejectRemoteOAuth(`login`,e,t))try{let n=await this.api.startOAuthLogin(e.id,t);this.updateOAuthFlow(n,t),this.startPolling(n.flowId)}catch(e){this.setState({error:String(e)})}}rejectRemoteOAuth(e,t,n){let r=this.getState().selectedMachine;if(t.authType!==`oauth`||n.machineKind!==`remote`)return!1;let i=r?.baseUrl??`that remote PI WEB instance`;return this.setState({error:`OAuth ${e} for remote machines must be configured directly on ${i}.`}),!0}updateOAuthFlow(e,t){if(e.status===`complete`){this.stopPolling(),this.closeDialog(),this.refreshStatus(t);return}(e.status===`error`||e.status===`cancelled`)&&this.stopPolling();let n=this.getState().authDialog,r=n?.step===`oauth`&&n.flow.flowId===e.flowId?n.inputValue??``:``,i=n?.step===`oauth`?n.flow.prompt?.requestId??n.flow.select?.requestId:void 0,a=e.prompt?.requestId??e.select?.requestId,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,inputValue:s,responding:c,target:t}})}startPolling(e){this.stopPolling(),this.pollTimer=window.setInterval(()=>{this.poll(e)},this.pollIntervalMs)}stopPolling(){this.pollTimer!==void 0&&(window.clearInterval(this.pollTimer),this.pollTimer=void 0)}async poll(e){let t=this.getState().authDialog;if(t?.step!==`oauth`||t.flow.flowId!==e){this.stopPolling();return}try{this.updateOAuthFlow(await this.api.oauthFlow(e,t.target),t.target)}catch(e){this.stopPolling(),this.setState({authDialog:{...t,error:String(e)}})}}async refreshStatus(e){let t=this.session();if(t!==void 0&&this.targetStillSelected(e))try{this.applyStatus(await this.api.status(t,e.machineId))}catch{}}session(){let e=this.getState().selectedSession;if(!(e===void 0||e.archived===!0))return e}captureTarget(){let e=this.getState(),t=e.selectedMachine,n={machineId:L(e),...t?.kind===void 0?{}:{machineKind:t.kind}};if(this.scope===`management`)return n;let r=e.selectedProject;if(r===void 0){this.setState({error:`请先选择项目,再配置提供商认证。`});return}return{...n,projectId:r.id,projectName:r.name}}targetStillSelected(e){return L(this.getState())===e.machineId?e.projectId===void 0||this.getState().selectedProject?.id===e.projectId:!1}};function za(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 Ba(e){return e.replaceAll(`:`,`.`)}function Va(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 Ha(e,t){let n=Va(e)[t];return Array.isArray(n)?n[0]:n===``?void 0:n}function Ua(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));Wa(i,r)}function Wa(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 Ga(e){let t=e.files.map((t,n)=>{let r=t.size;return{index:n,name:t.name,path:da(e.destinationFolder,t.name),size:t.size,loaded:0,total:r,percent:Za(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:Za(0,n),status:`uploading`,startedAt:e.startedAt}}function Ka(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 qa(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=Xa(r);return{...e,files:r,currentFileIndex:r.length===0?-1:r.length-1,...i,status:`completed`,completedAt:n}}function Ja(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,...Xa(r),status:`error`,error:t,completedAt:n}}function Ya(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,...Xa(r),status:`cancelled`,error:n,completedAt:t}}function Xa(e){let t=e.reduce((e,t)=>e+t.total,0);return{loaded:t,total:t,percent:e.length===0?0:1}}function Za(e,t){return t<=0?e<=0?0:1:Math.max(0,Math.min(1,e/t))}var Qa=Ba(`core:workspace.files`),$a=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??I,this.uploadWorkspaceFiles=r.uploadWorkspaceFiles??pa,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=L(this.getState()),r=await this.api.workspaceTree(e.id,t.id,``,n),i=await Promise.all(Object.keys(this.getState().expandedDirs).map(async r=>{try{return[r,(await this.api.workspaceTree(e.id,t.id,r,n)).entries]}catch(e){if(eo(e))return;throw e}})),a=Object.fromEntries(i.filter(e=>e!==void 0));this.setState({fileTree:r.entries,expandedDirs:a,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:ro(this.getState().expandedDirs,e)});return}try{let r=await this.api.workspaceTree(t.id,n.id,e,L(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`}),Ua(Qa,`file`,e),this.updateUrl({replace:!0}),await this.restoreFile(e)}selectDirectory(e){this.setState({selectedFilePath:e,selectedFileContent:void 0,workspaceTool:`core:workspace.files`,mainView:this.getState().mainView===`chat`?`chat`:`core:workspace.files`}),Ua(Qa,`file`,void 0,{replace:!0}),this.updateUrl({replace:!0})}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,L(this.getState()));this.getState().selectedFilePath===e&&this.setState({selectedFileContent:r,error:``})}catch(t){if(this.getState().selectedFilePath!==e)return;if(eo(t)){this.setState({selectedFilePath:void 0,selectedFileContent:void 0,error:``}),Ua(Qa,`file`,void 0,{replace:!0}),this.updateUrl({replace:!0});return}this.setState({error:String(t)})}}}async createFile(e){let t=this.getState().selectedProject,n=this.getState().selectedWorkspace;if(!(t===void 0||n===void 0||e===``))try{await this.api.createWorkspaceFile(t.id,n.id,e,L(this.getState())),await this.refreshFiles(),await this.selectFile(e),this.setState({error:``})}catch(e){this.setState({error:String(e)})}}async createDirectory(e){let t=this.getState().selectedProject,n=this.getState().selectedWorkspace;if(!(t===void 0||n===void 0||e===``))try{await this.api.createWorkspaceDirectory(t.id,n.id,e,L(this.getState())),await this.refreshFiles(),this.selectDirectory(e),this.setState({error:``})}catch(e){this.setState({error:String(e)})}}async moveSelectedPath(e){let t=this.getState().selectedProject,n=this.getState().selectedWorkspace,r=this.getState().selectedFilePath;if(!(t===void 0||n===void 0||r===void 0||r===``||e===``))try{let i=L(this.getState());io(this.getState())===`directory`?(await this.api.moveWorkspaceDirectory(t.id,n.id,r,e,i),await this.refreshFiles(),this.selectDirectory(e)):(await this.api.moveWorkspaceFile(t.id,n.id,r,e,void 0,i),await this.refreshFiles(),await this.selectFile(e)),this.setState({error:``})}catch(e){this.setState({error:String(e)})}}async deleteSelectedPath(){let e=this.getState().selectedProject,t=this.getState().selectedWorkspace,n=this.getState().selectedFilePath;if(!(e===void 0||t===void 0||n===void 0||n===``))try{let r=L(this.getState());io(this.getState())===`directory`?await this.api.deleteWorkspaceDirectory(e.id,t.id,n,r):await this.api.deleteWorkspaceFile(e.id,t.id,n,r),await this.refreshFiles(),this.clearSelection(),this.setState({error:``})}catch(e){this.setState({error:String(e)})}}async downloadSelectedFile(){let e=this.getState().selectedProject,t=this.getState().selectedWorkspace,n=this.getState().selectedFilePath;if(!(e===void 0||t===void 0||n===void 0||n===``||io(this.getState())===`directory`))try{await this.api.downloadWorkspaceFile(e.id,t.id,n,L(this.getState())),this.setState({error:``})}catch(e){this.setState({error:String(e)})}}clearSelection(){this.setState({selectedFilePath:void 0,selectedFileContent:void 0}),Ua(Qa,`file`,void 0,{replace:!0}),this.updateUrl({replace:!0})}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=L(this.getState()),a=t.overwrite??!1,o=t.createDirs??!0,s;try{s=Ga({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(Ya(t,this.now())),this.uploadTasks.get(e)?.cancel())}clearWorkspaceUpload(e){this.uploadTasks.get(e)?.cancel(),this.uploadTasks.delete(e),this.setState({workspaceUploadBatches:ro(this.getState().workspaceUploadBatches,e)})}updateUploadProgress(e,t){let n=this.getUploadBatch(e);n?.status===`uploading`&&this.setUploadBatch(Ka(n,t))}async completeUploadBatch(e,t,n){let r=this.getUploadBatch(e);if(r?.status!==`uploading`||(this.setUploadBatch(qa(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 ca)||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(to(t)){let e=Ya(n,this.now());return this.setUploadBatch(e),e}let r=no(t),i=Ja(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&&L(t)===e.machineId}};function eo(e){let t=String(e);return t.includes(`Path does not exist`)||t.includes(`ENOENT`)||t.includes(`no such file or directory`)}function to(e){return e instanceof sa}function no(e){return e instanceof Error?e.message:String(e)}function ro(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>e!==t))}function io(e){let t=e.selectedFilePath;return t===void 0?`file`:ao(e.fileTree,e.expandedDirs,t)?.type===`directory`?`directory`:`file`}function ao(e,t,n){let r=e.find(e=>e.path===n);if(r!==void 0)return r;for(let e of Object.values(t)){let t=e.find(e=>e.path===n);if(t!==void 0)return t}}var oo=Ba(`core:workspace.git`),so=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 I.gitStatus(e.id,t.id,L(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}),Ua(oo,`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`}),Ua(oo,`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([I.gitDiff(t.id,n.id,{path:e},L(this.getState())),I.gitDiff(t.id,n.id,{path:e,staged:!0},L(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))}},co=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 I.machines(),n=await this.selectInitialMachine(t,e),r=new Set(t.map(e=>e.id));this.setState({machines:t,selectedMachine:n,machineActivities:uo(this.getState().machineActivities,r),machineRuntimes:uo(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 I.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 I.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:lo(this.getState().machineStatuses,e.id),machineRuntimes:lo(this.getState().machineRuntimes,e.id),machineActivities:lo(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 I.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 I.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 I.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=>I.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=>I.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 lo(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>e!==t))}function uo(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>t.has(e)))}var fo=class{constructor(e,t,n){this.getState=e,this.setState=t,this.workspaces=n}async loadProjects(){let e=L(this.getState());this.setState({error:``,isLoadingProjects:!0});try{let t=await I.projects(e);if(L(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){L(this.getState())===e&&this.setState({error:String(t)})}finally{L(this.getState())===e&&this.setState({isLoadingProjects:!1})}}async addProject(e,t){if(e.trim()!==``)try{let n=await I.addProject(e.trim(),void 0,t,L(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 I.closeProject(e,L(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)})}}},po=class{constructor(e,t,n={}){this.getState=e,this.setState=t,this.requestSequence=0,this.api=n.api??Pi,this.onRefreshError=n.onRefreshError??(()=>void 0)}async refresh(){let e=L(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=L(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}),mo(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 L(this.getState())===e&&t===this.requestSequence}};function mo(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 ho=`pi-web:cached-new-sessions:v1`,go=`browserCachedNew`,_o=`local`;function vo(){try{return typeof localStorage>`u`?void 0:localStorage}catch{return}}function yo(e,t=_o,n=vo()){if(e.messageCount!==0||e.archived===!0)return;let r=To(n).filter(n=>n.id!==e.id||n.machineId!==t);Eo([bo(e,t),...r],n)}function bo(e,t=_o){return{...e,browserCachedNew:!0,machineId:t}}function xo(e,t=_o,n=vo()){Eo(To(n).filter(n=>n.id!==e||n.machineId!==t),n)}function So(e,t,n=_o,r=vo()){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&&Eo(o,r),[...o.filter(t=>t.machineId===n&&t.cwd===e),...t]}function Co(e){return e!==void 0&&Oo(e)&&e.browserCachedNew===!0}function wo(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:_o},...e.archived===!0?{archived:!0}:{},...e.archivedAt===void 0?{}:{archivedAt:e.archivedAt}}}function To(e=vo()){try{let t=e?.getItem(ho);if(t==null||t===``)return[];let n=JSON.parse(t);return Array.isArray(n)?n.flatMap(e=>Do(e)):[]}catch{return[]}}function Eo(e,t=vo()){try{e.length===0?t?.removeItem(ho):t?.setItem(ho,JSON.stringify(e))}catch{}}function Do(e){if(!ko(e))return[];let t=Ao(e,`id`),n=Ao(e,`path`),r=Ao(e,`cwd`),i=Ao(e,`created`),a=Ao(e,`modified`),o=Ao(e,`firstMessage`),s=Mo(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=jo(e,`name`),l=jo(e,`parentSessionPath`),u=jo(e,`machineId`)??_o;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 Oo(e){return go in e}function ko(e){return typeof e==`object`&&!!e}function Ao(e,t){let n=e[t];return typeof n==`string`?n:void 0}function jo(e,t){let n=e[t];return n===void 0||typeof n!=`string`?void 0:n}function Mo(e,t){let n=e[t];return typeof n==`number`?n:void 0}function No(e){return Qo(e.flatMap(Ro)).filter(e=>e.parts.length>0)}function Po(e,t){return{role:e,parts:[{type:`text`,text:t}]}}function Fo(e,t){let n=Wo(t);return n===void 0?e:{...e,meta:n}}function Io(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,Po(t,n)]}function Lo(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 Ro(e){if(Bo(e))return[e];if(R(e,`role`)===`bashExecution`)return[Fo(qo(e),e)];let t=Jo(R(e,`role`)),n=Yo(os(e,`content`),e),r=t===`user`?Vo(n):void 0;if(r!==void 0)return r.map(t=>Fo(t,e));let i=Uo(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=zo(e);return c===void 0?s:[...s,Fo(c,e)]}function zo(e){if(R(e,`role`)!==`assistant`||R(e,`stopReason`)!==`error`)return;let t=R(e,`errorMessage`)?.trim();return Po(`system`,`Model response failed: ${t===void 0||t===``?`The model returned an error.`:t}`)}function Bo(e){let t=R(e,`role`);return(t===`user`||t===`assistant`||t===`tool`||t===`system`||t===`bash`||t===`skill`)&&Array.isArray(os(e,`parts`))}function Vo(e){if(e.length!==1||e[0]?.type!==`text`)return;let t=Ho(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 Ho(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 Uo(e){let t=R(e,`source`);if(t===`compaction`||t===`branch_summary`)return t}function Wo(e){let t=Go(os(e,`timestamp`)),n=Ko(e);if(!(t===void 0&&n===void 0))return{...t===void 0?{}:{timestamp:t},...n===void 0?{}:{model:n}}}function Go(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 Ko(e){if(R(e,`role`)!==`assistant`)return;let t=R(e,`provider`),n=R(e,`model`),r=R(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 qo(e){let t=R(e,`command`)??``,n=ss(e,`excludeFromContext`)===!0?[`excluded from context`,``,`$ ${t}`]:[`$ ${t}`],r=os(e,`output`);r!=null&&n.push(``,ls(r));let i=os(e,`exitCode`);i!=null&&n.push(``,`exit ${ls(i)}`),ss(e,`cancelled`)===!0&&n.push(``,`cancelled`),ss(e,`truncated`)===!0&&n.push(``,`output truncated`);let a=R(e,`fullOutputPath`);return a!==void 0&&a!==``&&n.push(``,`full output: ${a}`),{role:`bash`,parts:[{type:`text`,text:n.join(`
|
|
4
|
+
`)}]}}function Jo(e){return e===`assistant`?`assistant`:e===`user`?`user`:e===`toolResult`?`tool`:`system`}function Yo(e,t){return typeof e==`string`?e===``?[]:[{type:`text`,text:e}]:Array.isArray(e)?e.flatMap(e=>{let t=R(e,`type`),n=R(e,`text`);if(t===`text`)return n!==void 0&&n!==``?[{type:`text`,text:n}]:[];if(t===`thinking`){let t=R(e,`thinking`)??n;return t!==void 0&&t!==``?[{type:`thinking`,text:t}]:[]}if(t===`toolCall`){let t=R(e,`name`)??`tool`,n=os(e,`arguments`),r=R(e,`id`),i=t===`read`?Zo(R(n,`path`)):void 0;return i===void 0?[{type:`toolCall`,...r===void 0?{}:{toolCallId:r},toolName:t,summary:rs(n),...n===void 0?{}:{args:n}}]:[{type:`skillRead`,...i,...r===void 0?{}:{toolCallId:r}}]}if(t===`image`){let t=R(e,`data`),n=R(e,`mimeType`);return t!==void 0&&t!==``&&n!==void 0&&n!==``?[{type:`image`,mimeType:n,data:t}]:[{type:`text`,text:`[image]`}]}return ns(e)}).map(e=>e.type===`text`&&R(t,`role`)===`toolResult`?Xo(e.text,t):e):ns(e)}function Xo(e,t){let n=R(t,`toolCallId`),r=os(t,`content`),i=os(t,`details`);return{type:`toolResult`,...n===void 0?{}:{toolCallId:n},toolName:R(t,`toolName`)??`tool`,text:e,...r===void 0?{}:{content:r},...i===void 0?{}:{details:i},isError:ss(t,`isError`)===!0}}function Zo(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 Qo(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=$o(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&&es(t,e,o)){n.delete(o.toolCallId??``);continue}}e.push(o)}a()}return t}function $o(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 es(e,t,n){let r=e[t.lineIndex],i=r?.parts[t.partIndex];if(r===void 0||i?.type!==`toolExecution`)return!1;let a=ts(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 ts(e){let t=os(e,`preview`);if(!as(t))return;let n=R(t,`diff`),r=R(t,`error`),i=cs(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 ns(e){return e==null?[]:typeof e==`object`?[{type:`text`,text:rs(e)}]:[{type:`text`,text:ls(e)}]}function rs(e){if(!as(e))return ls(e);let t=R(e,`command`);if(t!==void 0)return t;let n=R(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}: ${is(t)}`).join(` · `)}function is(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 as(e){return typeof e==`object`&&!!e}function os(e,t){return as(e)?e[t]:void 0}function R(e,t){let n=os(e,t);return typeof n==`string`?n:void 0}function ss(e,t){let n=os(e,t);return typeof n==`boolean`?n:void 0}function cs(e,t){let n=os(e,t);return typeof n==`number`&&Number.isFinite(n)?n:void 0}function ls(e){return e==null?``:typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`?String(e):``}var us=`pi-web:prompt-draft:`;function ds(e){return`${us}${e}`}function fs(){try{return typeof localStorage>`u`?void 0:localStorage}catch{return}}function ps(e,t=fs()){try{return t?.getItem(ds(e))??``}catch{return``}}function ms(e,t,n=fs()){try{t?n?.setItem(ds(e),t):n?.removeItem(ds(e))}catch{}}function hs(e,t=fs()){try{t?.removeItem(ds(e))}catch{}}function gs(e,t,n=fs()){let r=ps(e,n);r!==``&&(ms(t,r,n),hs(e,n))}function _s(e,t){return Po(`bash`,`${t===!0?`不加入上下文
|
|
5
|
+
|
|
6
|
+
`:``}$ ${e}`)}function vs(e,t){let n=e.at(-1),r=n?.parts.at(-1);if(n?.role!==`bash`||r?.type!==`text`)return[...e,Po(`bash`,t)];let i=bs(r.text)?``:`
|
|
7
|
+
|
|
8
|
+
`;return[...e.slice(0,-1),{...n,parts:[...n.parts.slice(0,-1),{...r,text:r.text+i+t}]}]}function ys(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 命令失败`),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(`完整输出:${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 bs(e){return e.lastIndexOf(`
|
|
12
|
+
|
|
13
|
+
`)>e.lastIndexOf(`$ `)}function xs(e,t){if(t.type===`message.append`)return Ws(e,t.message);if(t.type===`assistant.delta`)return Io(e,`assistant`,t.text);if(t.type===`assistant.thinking.delta`)return Lo(e,t.text);if(t.type===`tool.start`)return Es(e,t);if(t.type===`tool.update`)return ks(e,t.toolCallId,e=>Ds(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:js({role:`toolResult`,content:t.content})});if(t.type===`shell.start`)return[...e,_s(t.command,t.excludeFromContext)];if(t.type===`shell.chunk`)return vs(e,t.chunk);if(t.type===`shell.end`)return ys(e,t);if(t.type===`command.output`)return[...e,Po(t.level===`error`?`system`:`tool`,t.message)];if(t.type===`session.error`)return[...e,Po(`system`,t.message)];if(t.type===`message.end`)return t.message===void 0?void 0:Ss(e,t.message)}function Ss(e,t){let n=Ms(t);if(n!==void 0)return Os(e,n);let r=Ro(t);if(r.length===0)return;let i=r.map(e=>e.role===`assistant`?ws(e):e).filter(e=>e.parts.length>0);return i.length===0?e:i.reduce((e,t)=>Cs(e,t),e)}function Cs(e,t){let n=Ps(e,t);if(n.length>0)return Fs(e,n,t);let r=e.at(-1);return r?.role===t.role&&(t.role===`assistant`||Hs(r,t))?[...e.slice(0,-1),t]:[...e,t]}function ws(e){return{...e,parts:e.parts.filter(e=>e.type!==`toolCall`)}}function Ts(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 Es(e,t){let n=t.toolName===`read`?Ts(Zs(t.args,`path`)):void 0;if(n!==void 0)return Gs(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||rs(t.args),...t.args===void 0?{}:{args:t.args},status:`running`};return[...e,{role:`tool`,parts:[r]}]}function Ds(e,t){let n=ts(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=ks(e,n,e=>{let t=ts(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=>As(e,c));if(l!==e)return l;let u=ts(s),d={type:`toolExecution`,...n===void 0||n===``?{}:{toolCallId:n},toolName:r,summary:rs(o),status:a?`error`:`success`,resultText:i,...o===void 0?{}:{content:o},...s===void 0?{}:{details:s},...u===void 0?{}:{preview:u}};return[...e,As({role:`tool`,parts:[d]},c)]}function ks(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 As(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 js(e){let t=Ro(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 Ms(e){if(Zs(e,`role`)!==`toolResult`)return;let t=Zs(e,`toolCallId`),n=Xs(e,`content`);return{...t===void 0?{}:{toolCallId:t},toolName:Zs(e,`toolName`)??`tool`,text:Ns(n),isError:Qs(e,`isError`)===!0,content:n,details:Xs(e,`details`),presentation:js(e)}}function Ns(e){if(typeof e==`string`)return e;if(Array.isArray(e))return e.map(Ns).filter(e=>e!==``).join(`
|
|
14
|
+
`);if(typeof e==`object`&&e){let t=Zs(e,`text`)??Zs(e,`content`)??Zs(e,`output`);if(t!==void 0)return t}return``}function Ps(e,t){let n=Rs(t);if(n.length===0)return[];let r=[],i=n.length,a=Js(e)+1;for(let t=e.length-1;t>=a;t--){let a=Rs(e[t]);if(a.length===0)continue;let o=i-a.length;if(!(o<0)&&zs(a,n.slice(o,i))&&(r.unshift(t),i=o,i===0))return r}return[]}function Fs(e,t,n){let r=Is(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 Is(e,t,n){let r=t[0];if(n.role!==`assistant`||r===void 0)return t;let i=r-1;return Ls(e[i])?[i,...t]:t}function Ls(e){return e?.role===`assistant`&&e.parts.length>0&&e.parts.every(e=>e.type===`text`||e.type===`thinking`)}function Rs(e){return e===void 0?[]:e.parts.filter(e=>e.type===`skillRead`)}function zs(e,t){return e.length===t.length&&e.every((e,n)=>Bs(e,t[n]))}function Bs(e,t){return t===void 0?!1:e.toolCallId!==void 0&&t.toolCallId!==void 0?e.toolCallId===t.toolCallId:Vs(e.path)===Vs(t.path)||e.name===t.name}function Vs(e){return e.replace(/\\/g,`/`)}function Hs(e,t){return Us(e)===Us(t)}function Us(e){return e.parts.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
15
|
+
|
|
16
|
+
`)}function Ws(e,t){let n=Ro(t);return n.length===0?e:[...e,...n]}function Gs(e,t){let n=e.at(-1);return Ks(e,t)?e:n?.role===t.role&&t.role!==`skill`?[...e.slice(0,-1),{...n,parts:[...n.parts,...t.parts]}]:[...e,t]}function Ks(e,t){let n=Rs(t);if(t.role!==`skill`||n.length===0)return!1;let r=Js(e)+1;return n.every(t=>qs(e,t,r))}function qs(e,t,n){for(let r=e.length-1;r>=n;r--)if(Rs(e[r]).some(e=>Bs(e,t)))return!0;return!1}function Js(e){for(let t=e.length-1;t>=0;t--)if(e[t]?.role===`user`)return t;return-1}function Ys(e){return typeof e==`object`&&!!e}function Xs(e,t){return Ys(e)?e[t]:void 0}function Zs(e,t){let n=Xs(e,t);return typeof n==`string`?n:void 0}function Qs(e,t){let n=Xs(e,t);return typeof n==`boolean`?n:void 0}var $s=`pi-web:chat-history:v2:`,ec=1800*1e3;function tc(e){try{let t=sessionStorage.getItem(cc(e));if(t===null||t===``)return;let n=JSON.parse(t);if(!lc(n))return;if(Date.now()-n.savedAt>ec){sessionStorage.removeItem(cc(e));return}return{messages:n.messages,start:n.start,total:n.total}}catch{return}}function nc(e,t){try{sessionStorage.setItem(cc(e),JSON.stringify({...t,savedAt:Date.now()}))}catch{}}function rc(e){try{sessionStorage.removeItem(cc(e))}catch{}}function ic(e,t){if(e===void 0||!uc(e))return t;if(!uc(t))return e;if(ac(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 sc(i,n,e),sc(i,n,t),oc(i)?t:{start:n,total:Math.max(e.total,t.total),messages:i}}function ac(e,t){return e.total>t.total&&e.start===0&&t.start===0&&t.messages.length===t.total}function oc(e){for(let t=0;t<e.length;t+=1)if(!(t in e)||e[t]===void 0)return!0;return!1}function sc(e,t,n){n.messages.forEach((r,i)=>{e[n.start-t+i]=r})}function cc(e){return`${$s}${e}`}function lc(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`&&uc({messages:t,start:n,total:r})}function uc(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(dc)}function dc(e){return typeof e==`object`&&!!e&&`role`in e&&`parts`in e&&!(`content`in e)&&typeof e.role==`string`&&Array.isArray(e.parts)}var fc={read:tc,write:nc,remove:rc},pc=class{constructor(e=fc){this.cache=e,this.rawHistoryPages=new Map}cachedView(e){return mc(this.rawHistoryPage(e))}mergeHistory(e,t){let n=ic(this.rawHistoryPage(e),t);return this.rawHistoryPages.set(e,n),this.cache.write(e,n),mc(n)}applyLiveEvent(e,t){return xs(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 mc(e){let t=e?.start??0;return{messages:No(e?.messages??[]),messagePageStart:t,messagePageEnd:t+(e?.messages.length??0),messagePageTotal:e?.total??0}}function hc(e,t=e.length){let n=e.slice(0,t),r=_c(n,t);if(r!==void 0)return r;let i=vc(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 gc(e,t,n){let r=n??`@`;return!t&&!e.includes(` `)?`${r}${e}`:`${r}"${e}"`}function _c(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 vc(e,t){let n=e.lastIndexOf(`
|
|
18
|
+
`)+1,r=e.slice(n),i=yc(r,`@ `),a=yc(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 yc(e,t){for(let n=e.lastIndexOf(t);n>=0;n=e.lastIndexOf(t,n-1))if(n===0||bc(e[n-1]))return n;return-1}function bc(e){return e===` `||e===` `}function xc(e){let t=e.trimStart();return t.startsWith(`!@`)?{kind:`file`}:t.startsWith(`!`)?{kind:`shell`,excludeFromContext:t.startsWith(`!!`)}:wc(e).startsWith(`/`)?{kind:`command`}:hc(e)?.kind===`file`?{kind:`file`}:{kind:`normal`}}function Sc(e){return xc(e).kind===`shell`}function Cc(e,t){return e.kind===t.kind?e.kind===`shell`&&t.kind===`shell`?e.excludeFromContext===t.excludeFromContext:!0:!1}function wc(e){let t=Math.max(e.lastIndexOf(` `),e.lastIndexOf(`
|
|
19
|
+
`))+1;return e.slice(t)}var Tc=class{constructor(e=`normal`){this.scope=e,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),Mc(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=na(this.session,this.machineId,this.scope);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 jc(e);Dc(t)&&this.onEvent?.(t)}},Ec=class{constructor(e=`normal`){this.scope=e,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),Mc(this.socket),this.socket=void 0,this.onEvent=void 0,this.onOpen=void 0,this.machineId=`local`}open(){if(!this.shouldReconnect)return;let e=ia(this.machineId,this.scope);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 jc(e);kc(t)&&this.onEvent?.(t)}};function Dc(e){let t=Ac(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=Ac(e);return t===`status.update`||t===`activity.update`||t===`session.name`||t===`session.created`}function kc(e){let t=Ac(e);return Oc(e)||t===`terminal.created`||t===`terminal.exited`||t===`terminal.closed`||t===`workspace.activity`}function Ac(e){if(typeof e!=`object`||!e||!(`type`in e))return``;let t=e.type;return typeof t==`string`?t:``}async function jc(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 Mc(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 Nc(e){return e?.ok===!0&&en(e,M.sessionsPersistedState)}function Pc(e){return{authoritative:Nc(e)}}function Fc(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||Co(e)?`transient`:n.authoritative===!0?`unknown`:`persisted`}function Ic(e,t,n){return e!==void 0&&e.archived!==!0&&Fc(e,t,n)===`persisted`}function Lc(e,t,n){return e!==void 0&&e.archived!==!0&&Fc(e,t,n)===`transient`}function Rc(){try{return typeof sessionStorage>`u`?void 0:sessionStorage}catch{return}}var zc=class{constructor(e,t,n=Rc()){this.storageKey=e,this.storage=n,this.values=new Map;for(let[r,i]of Vc(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 Bc(e){return typeof e==`string`&&e!==``?e:void 0}function Vc(e,t,n){try{let r=n?.getItem(e);if(r==null||r===``)return[];let i=JSON.parse(r);if(!Hc(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 Hc(e){return!Uc(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 Uc(e){return typeof e==`object`&&!!e}var Wc=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)}},Gc=`pi-web:session-selection:v1`,Kc=class{constructor(e=Rc()){this.sessionIdsByCwd=new zc(Gc,Bc,e)}latestSessionId(e){return this.sessionIdsByCwd.get(e)}rememberSession(e){this.sessionIdsByCwd.set(e.cwd,e.id)}forgetWorkspace(e){this.sessionIdsByCwd.delete(e)}};function qc(e,t){let n=t?.targetSessionId;if(n!==void 0&&n!==``)return Yc(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 Jc(e,t){return t?.archived===!0&&!e.some(e=>e.archived!==!0)}function Yc(e,t){return e.find(e=>e.id===t||e.id.startsWith(t))}function Xc(e,t,n){return Zc(e,[t],n)}function Zc(e,t,n){let r=new Set(t);return e.map(e=>r.has(e.id)?{...e,archived:!0,archivedAt:n}:e)}function Qc(e,t,n){return $c(e,t,[n])}function $c(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 el=100,tl=4,nl=class{constructor(e,t,n,r=new Wc,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 Pa,this.socket=i.socket??new Tc,this.api=i.api??I,this.transcripts=i.transcripts??new pc}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.catchupStreamSessionId=void 0,this.clearPendingUpdates(),this.setState({selectedSession:void 0,messages:[],messagePageStart:0,messagePageEnd:0,messagePageTotal:0,isLoadingEarlierMessages:!1,isReceivingPartialStream:!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();Jc(e.sessions,e.selectedSession)&&this.deselectSession({forgetRememberedSelection:!0})}async startSession(){let e=this.getState().selectedWorkspace;if(!e)return;let t=L(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 qc(t,{targetSessionId:n,latestSessionId:this.sessionSelection.latestSessionId(this.workspaceSelectionKey(e))})}async selectSession(e,t){if(cl(e)){this.selectClientPendingStartSession(e,t);return}this.sessionSelection.rememberSession({...e,cwd:this.workspaceSelectionKey(e.cwd)});let n=++this.selectionSeq;this.socket.close(),this.catchupStreamSessionId=void 0,this.clearPendingUpdates();let r=this.sessionCacheKey(e.id),i=this.transcripts.cachedView(r);this.setState({selectedSession:e,...i,isLoadingEarlierMessages:!1,isReceivingPartialStream:!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:el},L(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,isReceivingPartialStream:!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)},L(this.getState()));let a=L(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(Co(e)&&Tl(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:el},L(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(cl(i)){!o&&a.startsWith(`/`)?this.enqueuePendingSessionSend(i,{type:`command`,text:e}):!o&&Sc(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&&Sc(e))return this.runShell(e);await this.deliverPromptToSession(i,e,t,n,r,L(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:il(n,e)})}async runShell(e){let t=this.getState().selectedSession;if(!(!t||t.archived===!0)){if(cl(t)){this.enqueuePendingSessionSend(t,{type:`shell`,text:e});return}await this.deliverShellToSession(t,e,L(this.getState()),{optimisticLine:!0})}}async runCommand(e){let t=this.getState().selectedSession;if(!(!t||t.archived===!0)){if(cl(t)){this.enqueuePendingSessionSend(t,{type:`command`,text:e});return}await this.deliverCommandToSession(t,e,L(this.getState()),{applyResult:!0})}}async renameSession(e,t){let n=t.trim();if(!(n===``||!Ic(e,this.statusForSession(e),this.sessionPersistenceOptions())))try{let t=await this.api.runCommand(e,`/name ${n}`,L(this.getState()));if(t.type===`done`){this.applySessionName(e.id,t.session?.name??n);return}this.setState({error:t.type===`unsupported`?t.message:`重命名会话失败`})}catch(e){this.setState({error:String(e)})}}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=ll(e.id,n.queuedSends.length);this.setState({clientQueuedSessionMessages:{...i.clientQueuedSessionMessages,[e.id]:[...a,dl(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=>gc(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,Po(`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,Po(`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,Po(`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?il(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,L(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(Lc(e,t,n)){await this.deleteCachedNewSession(e);return}if(Ic(e,t,n))try{await this.api.archive(e,L(this.getState()));let t=this.getState(),n=Xc(t.sessions,e.id,new Date().toISOString()),r=Qc(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||!Ic(e,this.statusForSession(e),this.sessionPersistenceOptions())))try{let t=await this.api.archiveWithDescendants(e,L(this.getState())),n=t.sessionIds!==void 0&&t.sessionIds.length>0?t.sessionIds:[e.id],r=this.getState(),i=Zc(r.sessions,n,new Date().toISOString()),a=$c(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=ml(e).filter(e=>Ic(e,this.statusForSession(e),t));if(n.length!==0)try{let e=L(this.getState()),{succeededIds:t,failures:r,generatedAt:i}=await this.archiveSessionBatch(n,e);if(t.length>0){let e=this.getState(),n=Zc(e.sessions,t,i??new Date().toISOString()),r=$c(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: ${xl(e)}`})}}async deleteArchivedSessions(e){let t=ml(e).filter(e=>e.archived===!0);if(t.length===0)return;let n=L(this.getState()),r=this.getState().machineRuntimes[n];if(r?.ok===!0&&!en(r,M.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: ${xl(e)}`})}}async archiveSessionBatch(e,t){let n=this.getState().machineRuntimes[t];if(n?.ok===!0&&en(n,M.sessionsBulkMutations)){let n=await this.api.archiveMany(e,t);return{succeededIds:n.archivedSessionIds,failures:gl(n.failures),generatedAt:n.generatedAt}}let r=await vl(e,tl,async e=>(await this.api.archive(e,t),e.id));return{succeededIds:hl(r),failures:_l(e,r)}}async deleteArchivedSessionBatch(e,t){let n=this.getState().machineRuntimes[t];if(n?.ok===!0&&en(n,M.sessionsBulkMutations)){let n=await this.api.deleteArchivedMany(e,t);return{succeededIds:n.deletedSessionIds,failures:gl(n.failures)}}let r=await vl(e,tl,async e=>(await this.api.deleteArchived(e,t),e.id));return{succeededIds:hl(r),failures:_l(e,r)}}async applySessionCleanupResult(e,t=L(this.getState())){if(L(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=Zc(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:al(t.sessionStatuses,a),sessionActivities:al(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=$c(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=L(this.getState())){let t=this.getState().selectedWorkspace;if(t!==void 0)try{let n=So(t.path,await this.api.sessions(t.path,e),e).filter(t=>!this.isSuppressedCreatedSession(t,e));if(L(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){L(this.getState())===e&&this.getState().selectedWorkspace?.id===t.id&&this.setState({error:String(n)})}}async deleteCachedNewSession(e=this.getState().selectedSession){if(e===void 0||!Lc(e,this.statusForSession(e),this.sessionPersistenceOptions()))return;let t=cl(e)?this.pendingSessionStarts.get(e.id):void 0;t===void 0?this.api.stop(e,L(this.getState())).catch(()=>{}):(t.discarded=!0,t.queuedSends=[]),xo(e.id,L(this.getState())),hs(this.sessionCacheKey(e.id));let n=this.getState(),r=n.sessions.filter(t=>t.id!==e.id);if(this.setState({sessions:r,sessionStatuses:il(n.sessionStatuses,e.id),sessionActivities:rl(n.sessionActivities,e.id),sendingPrompts:il(n.sendingPrompts,e.id),clientQueuedSessionMessages:il(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,L(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||!Ic(e,this.statusForSession(e),this.sessionPersistenceOptions()))return;let t=L(this.getState()),n=this.getState().machineRuntimes[t];if(n?.ok!==!0||!en(n,M.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,L(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,L(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,L(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,L(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,L(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,L(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,L(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||cl(t))return;let n=L(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 stopActiveWork(){let e=this.getState().selectedSession;if(e)try{await this.api.abort(e,L(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||cl(t))return Promise.resolve();let n={session:t,machineId:L(this.getState()),selectionSeq:this.selectionSeq};return this.requestSelectedSessionRefresh(n).catch(e=>{this.isCurrentRefreshTarget(n)&&this.setState({error:String(e)})})}requestSelectedSessionRefresh(e){let t=Na(e.machineId,e.session.id);return this.selectedSessionRefreshes.request(t,async()=>{if(!this.isCurrentRefreshTarget(e))return;this.flushPendingUpdates();let[n,r]=await Promise.all([this.api.messages(e.session,{limit:el},e.machineId),this.api.status(e.session,e.machineId)]);if(!this.isCurrentRefreshTarget(e))return;let i=this.transcripts.mergeHistory(t,n);this.setState({...i,status:r,activity:this.getState().sessionActivities[e.session.id],...this.setStreamCatchup(r.isStreaming?e.session.id:void 0)}),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&&L(r)===t&&i?.id===e&&i.archived!==!0&&!cl(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 Na(L(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 Pc(e.machineRuntimes[L(e)])}workspaceSelectionKey(e){return`${L(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:ll(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.catchupStreamSessionId=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:ll(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,isReceivingPartialStream:!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){hs(Na(n.machineId,e)),this.setState({clientQueuedSessionMessages:il(this.getState().clientQueuedSessionMessages,e)}),this.applyReleasedCreatedSessions(i,n.machineId),this.api.stop(t,n.machineId).catch(()=>{});return}yo(t,n.machineId),gs(Na(n.machineId,e),Na(n.machineId,t.id));let a=bo(t,n.machineId);if(!this.isCurrentPendingStart(n)){this.setState({clientQueuedSessionMessages:il(this.getState().clientQueuedSessionMessages,e)}),await this.flushQueuedPendingSends(a,n.machineId,r);return}let o=this.getState(),s=o.selectedSession?.id===e;this.setState({sessions:sl(o.sessions,e,a),sessionActivities:rl(o.sessionActivities,e),sendingPrompts:ol(o.sendingPrompts,e,a.id),clientQueuedSessionMessages:ol(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=xl(t),s=ul(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 L(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||L(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=>cl(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=L(this.getState()),r=await this.api.startSession(e.cwd,n);yo(r,n),gs(this.sessionCacheKey(e.id),this.sessionCacheKey(r.id)),xo(e.id,n);let i=bo(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(!Co(e))return;let t=this.getState().sessions.find(t=>t.id===e.id)??e;this.replaceSession(wo(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,Po(e.type===`unsupported`?`system`:`tool`,t)]}),e.type===`done`&&e.session){e.promptDraft!==void 0&&ms(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=L(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`&&!Aa(e);this.setState({sessionStatuses:{...t.sessionStatuses,[e.sessionId]:e},...Sl(t,e.sessionId,e.messageCount),...n?{sessionActivities:rl(t.sessionActivities,e.sessionId)}:{},status:t.selectedSession?.id===e.sessionId?e:t.status,activity:t.selectedSession?.id===e.sessionId&&n?void 0:t.activity}),e.isStreaming||this.finishStreamCatchup(e.sessionId)}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){let t=this.getState().selectedSession?.id;if(this.catchupStreamSessionId!==void 0&&this.catchupStreamSessionId===t){if(e.type===`message.end`||e.type===`agent.end`){this.finishStreamCatchup(this.catchupStreamSessionId);return}if(Cl(e))return}if(e.type===`status.update`){this.queueStatusUpdate(e.status);return}if(e.type===`activity.update`){this.queueActivityUpdate(e.activity);return}if(wl(e)){this.queueTranscriptEvent(e);return}this.flushPendingUpdates();let n=this.transcripts.applyLiveEvent(this.getState().messages,e);n?this.setState({messages:n}):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)}setStreamCatchup(e){return this.catchupStreamSessionId=e,{isReceivingPartialStream:e!==void 0}}finishStreamCatchup(e){let t=this.getState().selectedSession?.id===e;(this.catchupStreamSessionId===e||t&&this.getState().isReceivingPartialStream)&&(this.catchupStreamSessionId=void 0,t&&this.setState({isReceivingPartialStream:!1}),this.refreshMessages(e))}async refreshMessages(e){try{let t=this.getState().selectedSession;if(t?.id!==e)return;let n=await this.api.messages(t,{limit:el},L(this.getState()));if(this.getState().selectedSession?.id!==e)return;this.setState(this.transcripts.mergeHistory(this.sessionCacheKey(e),n))}catch(t){this.getState().selectedSession?.id===e&&this.setState({error:String(t)})}}};function rl(e,t){return il(e,t)}function il(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>e!==t))}function al(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 ol(e,t,n){if(t===n||!(t in e))return e;let r=e[t];return r===void 0?e:{...il(e,t),[n]:r}}function sl(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 cl(e){return e!==void 0&&`clientPendingStart`in e&&e.clientPendingStart===!0}function ll(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 ul(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 dl(e){return e.type===`prompt`?{kind:e.streamingBehavior===`steer`?`steer`:`followUp`,text:fl(e.text,e.attachments)}:{kind:`followUp`,text:e.text}}function fl(e,t){let n=pl(t);return n===void 0?e:e.trim()===``?n:`${e}\n\n${n}`}function pl(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 ml(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 hl(e){return e.filter(yl).map(e=>e.value)}function gl(e){return e.map(e=>`${e.sessionId}: ${e.error}`)}function _l(e,t){return t.flatMap((t,n)=>bl(t)?[`${e[n]?.id??`unknown`}: ${xl(t.reason)}`]:[])}async function vl(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 yl(e){return e.status===`fulfilled`}function bl(e){return e.status===`rejected`}function xl(e){return e instanceof Error?e.message:String(e)}function Sl(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 Cl(e){return[`message.append`,`assistant.delta`,`assistant.thinking.delta`,`tool.start`,`tool.update`,`tool.end`,`shell.start`,`shell.chunk`,`shell.end`,`command.output`,`session.error`].includes(e.type)}function wl(e){return e.type===`assistant.delta`||e.type===`assistant.thinking.delta`||e.type===`shell.chunk`}function Tl(e){if(!(e instanceof Error))return!1;let t=e.message.toLowerCase();return t.includes(`session not found`)||t.includes(`未找到会话`)}var El=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)}},Dl=`pi-web:workspace-selection:v1`,Ol=class{constructor(e=Rc()){this.workspaceIdsByProject=new zc(Dl,Bc,e)}latestWorkspaceId(e){return this.workspaceIdsByProject.get(e)}rememberWorkspace(e){this.workspaceIdsByProject.set(e.projectId,e.id)}forgetProject(e){this.workspaceIdsByProject.delete(e)}};function kl(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 Al=class{constructor(e,t,n,r,i=new El,a={}){this.getState=e,this.setState=t,this.updateUrl=n,this.sessions=r,this.workspaceSelection=i,this.api=a.api??I}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(Ma(L(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=L(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(L(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=kl(r,{targetWorkspaceId:t?.workspaceId,latestWorkspaceId:this.workspaceSelection.latestWorkspaceId(Ma(n,e.id))});i?await this.selectWorkspace(i,{sessionId:t?.sessionId,updateUrl:t?.updateUrl}):t?.updateUrl!==!1&&this.updateUrl()}catch(t){L(this.getState())===n&&this.getState().selectedProject?.id===e.id&&this.setState({error:String(t),isLoadingWorkspaces:!1})}}async selectWorkspace(e,t){let n=L(this.getState());this.workspaceSelection.rememberWorkspace({...e,projectId:Ma(n,e.projectId)}),this.sessions.clearActiveSession(),this.setState({selectedWorkspace:e,isLoadingWorkspaces:!1,...Oa()});try{let r=So(e.path,await this.api.sessions(e.path,n),n);if(L(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){L(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,L(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=Ml(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 jl(e){return e!==void 0&&e.isGitWorktree&&!e.isMain}function Ml(e){return e.find(e=>e.isMain)??e[0]}var Nl=`pi-web:machine-navigation:v1`,Pl=class{constructor(e=Rc()){this.snapshotsByMachine=new zc(Nl,zl,e)}latest(e){let t=this.snapshotsByMachine.get(e);return t?.machineId===e?Rl(t):void 0}remember(e){this.snapshotsByMachine.set(e.machineId,Rl(e))}forget(e){this.snapshotsByMachine.delete(e)}};function Fl(e){return{machineId:e,surface:{}}}function Il(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 Ll(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 Rl(e){return{...e,surface:{...e.surface}}}function zl(e){if(!Gl(e))return;let t=Wl(e,`machineId`);if(t===void 0)return;let n=Hl(Wl(e,`tool`)),r=Vl(Wl(e,`view`));return{machineId:t,projectId:Wl(e,`projectId`),workspaceId:Wl(e,`workspaceId`),sessionId:Wl(e,`sessionId`),...n===void 0?{}:{tool:n},...r===void 0?{}:{view:r},surface:Bl(e.surface)}}function Bl(e){return Gl(e)?{selectedFilePath:Wl(e,`selectedFilePath`),selectedDiffPath:Wl(e,`selectedDiffPath`),selectedTerminalId:Wl(e,`selectedTerminalId`)}:{}}function Vl(e){return e===`navigation`||e===`chat`?e:Hl(e)}function Hl(e){return Ul(e)?e:void 0}function Ul(e){return e!==void 0&&/^[a-z][a-z0-9.-]*:[a-z][a-z0-9.-]*$/u.test(e)}function Wl(e,t){let n=e[t];return typeof n==`string`&&n!==``?n:void 0}function Gl(e){return typeof e==`object`&&!!e}var Kl=`pi-web:terminal-selection:v1`,ql=class{constructor(e=Rc()){this.terminalIdsByCwd=new zc(Kl,Bc,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 Jl(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 Yl(e){return e.find(e=>!e.exited)??e[0]}var Xl=1200,Zl=[`mod`,`alt`,`shift`],Ql=class{constructor(){this.pendingTokens=[]}handle(e,t,n={}){let r=ru(e);if(r===void 0)return!1;let i=$l(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(),!iu(r))return!1}else if(!iu(r))return!1;return this.handleSequence([r],i)}reset(){this.clearPending()}handleSequence(e,t){let n=t.find(t=>xu(t.tokens,e));return n===void 0?t.some(t=>Su(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},Xl)}clearPending(){this.pendingTokens=[],this.pendingTimer!==void 0&&(globalThis.clearTimeout(this.pendingTimer),this.pendingTimer=void 0)}};function $l(e,t,n={}){let r=e.flatMap((e,r)=>{if(n.enabledOnly===!0&&e.enabled===!1)return[];let i=au(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(lu)[0];t!==void 0&&a.set(t.key,t)}let o=[...a.values()].sort(uu),s=new Map,c=new Map;for(let e of r){let t=a.get(e.key);if(t===void 0)continue;let n=du(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:cu(t),i=n?[...s.get(e)??[]].sort(lu).map(cu):[];return{...e,active:n,shadows:i,...r===void 0?{}:{shadowedBy:r}}}).sort((e,t)=>e.order-t.order)}function eu(e){return mu(e,{requireFirstChordActivator:!0})}function tu(e){let t=mu(e,{requireFirstChordActivator:!1});return t.ok?t.tokens:[]}function nu(e){return tu(e).map(e=>e.split(`+`).map(bu).join(`+`)).join(` `)}function ru(e){if(e.isComposing)return;let t=vu(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 iu(e){return e.split(`+`).includes(`mod`)||e.split(`+`).includes(`alt`)}function au(e,t,n){let r=ou(e.id,t);if(r===null)return;let i=r??e.shortcut;if(i===void 0||i===``)return;let a=tu(i),o=a[0];if(!(o===void 0||!iu(o)))return{action:e,shortcut:a.join(` `),source:r===void 0?`default`:`custom`,tokens:a,key:su(a),order:n}}function ou(e,t){if(!(t===void 0||!Object.hasOwn(t,e)))return t[e]}function su(e){return e.join(`\0`)}function cu(e){return{action:e.action,shortcut:e.shortcut,source:e.source}}function lu(e,t){return fu(e.source)-fu(t.source)||pu(e.action.id,t.action.id)||pu(e.action.title,t.action.title)||e.order-t.order}function uu(e,t){return e.tokens.length-t.tokens.length||lu(e,t)}function du(e,t){return t.find(t=>t!==e&&t.tokens.length<e.tokens.length&&Su(e.tokens,t.tokens))}function fu(e){switch(e){case`custom`:return 0;case`default`:return 1}}function pu(e,t){return e<t?-1:+(e>t)}function mu(e,t){let n=e.trim().toLowerCase().replace(/\s*\+\s*/gu,`+`);if(n===``)return{ok:!1,message:`请输入快捷键,选择无,或重置为默认值。`};let r=[],i=n.split(/\s+/u).filter(e=>e!==``);for(let[e,n]of i.entries()){let i=hu(n);if(!i.ok)return i;if(e===0&&t.requireFirstChordActivator&&!iu(i.token))return{ok:!1,message:`快捷键必须以 Ctrl/⌘ 或 Alt 开头,避免拦截普通输入。`};r.push(i.token)}return{ok:!0,shortcut:r.join(` `),tokens:r}}function hu(e){let t=e.split(`+`).filter(e=>e!==``);if(t.length===0)return{ok:!1,message:`快捷键组合必须包含一个按键。`};let n=new Set,r;for(let e of t){let t=gu(e);if(t!==void 0){if(n.has(t))return{ok:!1,message:`快捷键包含重复的 ${bu(t)} 修饰键。`};n.add(t);continue}let i=_u(e);if(i===void 0)return{ok:!1,message:`不支持的快捷键按键:${e}`};if(r!==void 0)return{ok:!1,message:`每个快捷键组合只能包含一个非修饰键。`};r=i}return r===void 0?{ok:!1,message:`快捷键组合必须包含一个按键。`}:{ok:!0,token:[...Zl.filter(e=>n.has(e)),r].join(`+`)}}function gu(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 _u(e){let t=yu(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 vu(e){return e===` `?`space`:_u(e.toLowerCase())}function yu(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 bu(e){return e===`mod`?Cu()?`⌘`:`Ctrl`:e===`shift`?`Shift`:e===`alt`?Cu()?`⌥`:`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 xu(e,t){return e.length===t.length&&Su(e,t)}function Su(e,t){return t.every((t,n)=>e[n]===t)}function Cu(){return typeof navigator<`u`&&navigator.userAgent.toLowerCase().includes(`mac`)}var wu={archiveIdleEnabled:!0,archiveIdleDays:`30`,deleteArchivedEnabled:!1,deleteArchivedDays:`90`};function Tu(e){if(!e.archiveIdleEnabled&&!e.deleteArchivedEnabled)return{ok:!1,error:`请至少启用一项清理操作。`};let t={archiveIdleDays:null,deleteArchivedDays:null};if(e.archiveIdleEnabled){let n=Pu(e.archiveIdleDays,`归档空闲会话天数`);if(typeof n==`string`)return{ok:!1,error:n};t.archiveIdleDays=n}if(e.deleteArchivedEnabled){let n=Pu(e.deleteArchivedDays,`删除已归档会话天数`);if(typeof n==`string`)return{ok:!1,error:n};t.deleteArchivedDays=n}return{ok:!0,request:t}}function Eu(e){return JSON.stringify({archiveIdleDays:e?.archiveIdleDays??null,deleteArchivedDays:e?.deleteArchivedDays??null})}function Du(e){if(!e.canCleanup||e.loading===!0||e.running===!0||e.preview===void 0)return!1;let t=Tu(e.draft);return!t.ok||Eu(t.request)!==Eu(e.previewRequest)?!1:Ou(e.preview)}function Ou(e){return e.totals.archiveCount>0||e.totals.deleteCount>0}function ku(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 Au(e,t){let n=new Set(ku(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 ju(e,t){return t(Mu(e))}function Mu(e){let t=e.totals.archiveCount,n=e.totals.deleteCount,r=[];return t>0&&r.push(`归档 ${String(t)} 个空闲会话`),n>0&&r.push(`永久删除 ${String(n)} 个已归档会话`),`运行清理并${r.length===0?`执行清理`:r.join(`并`)}?\n\n永久删除只适用于已归档会话,且无法撤销。`}function Nu(e){return`请更新并重启 ${e??`此机器`} 上的 Pi-Web 后再清理会话。`}function Pu(e,t){let n=e.trim();if(n===``)return`${t}必须设置。`;let r=Number(n);return!Number.isInteger(r)||r<0?`${t}必须是非负整数天数。`:r}var Fu=`themes:classic`,Iu={themeId:`themes:pi-web-dark`,auto:!0},Lu=`pi-web-app-theme`,Ru=`--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(`.`),zu=/^[a-z][a-z0-9.-]*:[a-z][a-z0-9.-]*$/u;function Bu(){try{let e=window.localStorage.getItem(Lu);return e===null?void 0:Ku(e)}catch{return}}function Vu(e){try{window.localStorage.setItem(Lu,JSON.stringify(e))}catch{}}function Hu(e){let t=document.documentElement;t.dataset.piWebTheme=e.id,t.style.colorScheme=e.colorScheme;for(let n of Ru){let r=e.tokens[n];typeof r==`string`&&r!==``?t.style.setProperty(n,r):t.style.removeProperty(n)}}function Uu(e){let t=Wu(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=Gu(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 Wu(e,t=Fu){return e.find(e=>e.id===t)??e[0]}function Gu(e,t){return e.find(e=>e.light===t||e.dark===t)}function Ku(e){let t=e.trim();if(t!==``)try{let e=JSON.parse(t);return qu(e)?e:void 0}catch{return}}function qu(e){if(!Ju(e))return!1;let t=e.themeId,n=e.auto;return Yu(t)&&typeof n==`boolean`}function Ju(e){return typeof e==`object`&&!!e}function Yu(e){return typeof e==`string`&&zu.test(e)}var Xu=`workspace.delete`,Zu=`pi.operation`,Qu=`target.workspaceId`;function $u(e){return{...e===void 0?{}:{projectId:e},metadata:{[Zu]:Xu}}}function ed(e){let t={};for(let n of e){let e=rd(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 td(e){return Object.entries(e).filter(([,e])=>id(e)).map(([e])=>e)}function nd(e,t){if(t===void 0)return!1;let n=e.workspaceDeletionRuns[t.id];return n!==void 0&&id(n)}function rd(e){return e.metadata[Qu]}function id(e){return e.status===`queued`||e.status===`running`}function ad(){return[{id:`actions.show`,title:`显示操作`,description:`打开命令面板`,shortcut:`mod+k`,group:`通用`,run:e=>{e.openActionPalette()}},{id:`prompt.focus`,title:`聚焦提示词输入框`,description:`将键盘焦点移动到消息编辑器`,shortcut:`mod+g c`,group:`通用`,enabled:e=>e.state.selectedSession!==void 0,run:e=>{e.focusPrompt()}},{id:`machine.add`,title:`添加机器`,description:`注册另一个可从当前网关访问的 PI WEB 运行时`,group:`机器`,run:e=>e.addMachine()},{id:`machine.refresh`,title:`刷新所选机器`,description:`检查所选 PI WEB 运行时是否在线`,group:`机器`,run:e=>e.refreshSelectedMachine()},{id:`machine.open`,title:`打开所选机器的 PI WEB`,description:`在新标签页中直接打开所选远程 PI WEB`,group:`机器`,enabled:e=>e.state.selectedMachine?.kind===`remote`&&e.state.selectedMachine.baseUrl!==void 0,run:e=>e.openSelectedMachine()},{id:`machine.remove`,title:`移除所选机器`,description:`从当前网关移除所选远程机器`,group:`机器`,enabled:e=>e.state.selectedMachine?.kind===`remote`,run:e=>e.removeSelectedMachine()},{id:`project.add`,title:`添加项目`,group:`项目`,run:e=>e.addProject()},{id:`auth.login`,title:`配置当前项目的提供商认证`,description:`为当前项目运行 /login`,group:`通用`,run:e=>e.configureAuth()},{id:`auth.logout`,title:`移除当前项目的提供商认证`,description:`移除当前项目已保存的凭据`,group:`通用`,run:e=>e.logoutAuth()},{id:`theme.select`,title:`选择主题`,description:`选择 PI WEB 颜色主题`,group:`偏好设置`,run:e=>{e.openThemePicker()}},{id:`settings.open`,title:`打开设置`,description:`管理 PI WEB 配置和键盘快捷键`,shortcut:`mod+,`,group:`偏好设置`,run:e=>{e.piWebUnstable?.openSettings?.()}},{id:`app.reload-page`,title:`完整重载页面`,description:`重新加载 PI WEB 浏览器页面`,group:`通用`,run:e=>{e.reloadPage()}},{id:`view.chat`,title:`转到聊天`,shortcut:`mod+1`,group:`导航`,run:e=>{e.focusPrompt()}},{id:`view.files`,title:`转到文件`,shortcut:`mod+2`,group:`导航`,enabled:od,run:e=>{e.selectMainView(`core:workspace.files`)}},{id:`view.git`,title:`转到 Git`,shortcut:`mod+3`,group:`导航`,enabled:sd,run:e=>{e.selectMainView(`core:workspace.git`)}},{id:`view.terminal`,title:`转到终端`,shortcut:`mod+4`,group:`导航`,enabled:od,run:e=>{e.selectMainView(`core:workspace.terminal`)}},{id:`workspace.refresh-files`,title:`刷新文件`,shortcut:`mod+shift+f`,group:`工作区`,enabled:od,run:e=>e.refreshFiles()},{id:`workspace.refresh-git`,title:`刷新 Git`,shortcut:`mod+shift+g`,group:`工作区`,enabled:sd,run:e=>e.refreshGit()},{id:`workspace.refresh-current`,title:`刷新当前面板`,shortcut:`mod+shift+r`,group:`工作区`,enabled:od,run:e=>e.state.workspaceTool===`core:workspace.git`&&e.state.selectedWorkspace?.isGitRepo===!0?e.refreshGit():e.refreshFiles()},{id:`workspace.delete`,title:`删除工作区`,description:`移除所选 Git worktree`,group:`工作区`,enabled:cd,run:e=>e.deleteWorkspace()},{id:`session.start`,title:`启动会话`,shortcut:`mod+enter`,group:`会话`,enabled:od,run:e=>e.startSession()},{id:`session.archive`,title:`归档会话`,description:`归档所选会话`,group:`会话`,enabled:ld,run:e=>e.archiveSession()},{id:`session.reload`,title:`重新加载会话`,description:`关闭并从会话文件重新打开所选会话;如需重载 Pi 运行时资源,请在提示词中使用 /reload`,group:`会话`,enabled:dd,disabledReason:fd,run:e=>e.reloadSession()},{id:`session.delete`,title:`删除新会话`,description:`删除所选的临时新会话`,group:`会话`,enabled:ud,run:e=>e.deleteCachedNewSession()},{id:`session.stop`,title:`停止活动工作`,shortcut:`mod+.`,group:`会话`,enabled:e=>e.state.selectedSession!==void 0&&Aa(e.state.status,e.state.activity),run:e=>e.stopActiveWork()}]}function od(e){return e.state.selectedWorkspace!==void 0}function sd(e){return e.state.selectedWorkspace?.isGitRepo===!0}function cd(e){let t=e.state.selectedWorkspace;return t!==void 0&&t.isGitWorktree&&!t.isMain&&!nd(e.state,t)}function ld(e){return Ic(e.state.selectedSession,e.state.status,pd(e.state))}function ud(e){return Lc(e.state.selectedSession,e.state.status,pd(e.state))}function dd(e){return!Ic(e.state.selectedSession,e.state.status,pd(e.state))||fd(e)!==void 0?!1:!Aa(e.state.status,e.state.activity)}function fd(e){if(Ic(e.state.selectedSession,e.state.status,pd(e.state))&&!Aa(e.state.status,e.state.activity))return md(e.state,M.sessionsReload,`reload sessions from disk`)}function pd(e){return Pc(e.machineRuntimes[L(e)])}function md(e,t,n){let r=e.machineRuntimes[L(e)];if(!(r?.ok===!0&&en(r,t)))return`Update and restart Pi-Web on ${e.selectedMachine?.name??`this machine`} to ${n}.`}function hd(e){return typeof e==`string`?gd(e):g`<span class="tab-custom-icon" aria-hidden="true">${e}</span>`}function gd(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 _d=`10 MB`,vd=h`
|
|
54
|
+
: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; }
|
|
55
|
+
header { flex: 0 0 auto; min-width: 0; border-bottom: 1px solid var(--pi-border); }
|
|
56
|
+
.workspace-header-scroll-frame { position: relative; min-width: 0; background: var(--pi-bg); }
|
|
57
|
+
.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; }
|
|
58
|
+
.workspace-header-scroll-frame::before { left: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
59
|
+
.workspace-header-scroll-frame::after { right: 0; background: linear-gradient(270deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
60
|
+
.workspace-header-scroll-frame.can-scroll-left::before, .workspace-header-scroll-frame.can-scroll-right::after { opacity: 1; }
|
|
61
|
+
.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; }
|
|
62
|
+
.tabs { flex: 0 0 auto; display: flex; gap: 6px; align-items: center; }
|
|
63
|
+
.tabs button { flex: 0 0 auto; white-space: nowrap; }
|
|
64
|
+
.tabs button.icon-tab { min-width: 34px; }
|
|
65
|
+
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; }
|
|
66
|
+
button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
|
|
67
|
+
.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; }
|
|
68
|
+
.tab-custom-icon { flex: 0 0 auto; width: 16px; height: 16px; display: inline-grid; place-items: center; color: currentColor; pointer-events: none; }
|
|
69
|
+
.tab-custom-icon svg { width: 16px; height: 16px; pointer-events: none; }
|
|
70
|
+
.tab-label { min-width: 0; }
|
|
71
|
+
.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; }
|
|
72
|
+
@container (max-width: 430px) {
|
|
73
|
+
.tabs button.icon-tab { justify-content: center; padding-inline: 7px; }
|
|
74
|
+
.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; }
|
|
75
|
+
}
|
|
76
|
+
.panel-content { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: auto; }
|
|
77
|
+
.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; }
|
|
78
|
+
.empty-state h2 { margin: 0; color: var(--pi-text); font-size: 15px; line-height: 1.3; }
|
|
79
|
+
.empty-state p { margin: 0; line-height: 1.45; }
|
|
80
|
+
small, .muted { color: var(--pi-muted); }
|
|
81
|
+
@media (max-width: 1180px) { header { display: none; } }
|
|
82
|
+
.workspace-label { min-width: 0; display: inline-flex; align-items: baseline; gap: 5px; max-width: 100%; overflow: hidden; white-space: nowrap; }
|
|
83
|
+
.workspace-label-base, .workspace-label-item, .workspace-label-render { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
84
|
+
.workspace-label-item, .workspace-label-render, .workspace-label-separator { color: var(--pi-muted); }
|
|
85
|
+
.workspace-label-link { color: var(--pi-accent); text-decoration: none; }
|
|
86
|
+
.workspace-label-link:hover, .workspace-label-link:focus { text-decoration: underline; }
|
|
87
|
+
.toolbar { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; padding: 8px; border-bottom: 1px solid var(--pi-border-muted); }
|
|
88
|
+
.toolbar button { margin-left: auto; }
|
|
89
|
+
.stale { border: 1px solid var(--pi-warning-border); border-radius: 999px; color: var(--pi-warning); padding: 1px 6px; font-size: 12px; }
|
|
90
|
+
.split { flex: 1 1 auto; min-height: 0; display: grid; grid-template-rows: minmax(160px, 34%) minmax(0, 1fr); }
|
|
91
|
+
.list { min-height: 0; overflow: auto; border-bottom: 1px solid var(--pi-border); padding: 6px; }
|
|
92
|
+
.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); }
|
|
93
|
+
.row:hover, .row.selected { background: var(--pi-selection-bg); }
|
|
94
|
+
.row span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
95
|
+
.summary { margin: 4px 6px 8px; color: var(--pi-muted); }
|
|
96
|
+
.viewer { min-height: 0; overflow: auto; display: flex; flex-direction: column; }
|
|
97
|
+
.diffs { flex: 1 1 auto; min-height: 0; overflow: auto; display: grid; grid-template-rows: minmax(120px, 1fr) minmax(120px, 1fr); }
|
|
98
|
+
.diffs.single { grid-template-rows: minmax(0, 1fr); }
|
|
99
|
+
.diff-section { min-height: 0; display: flex; flex-direction: column; border-bottom: 1px solid var(--pi-border); }
|
|
100
|
+
.diff-section:last-child { border-bottom: 0; }
|
|
101
|
+
.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); }
|
|
102
|
+
.viewer-header strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
103
|
+
code-viewer, unified-diff-viewer { flex: 1 1 auto; min-height: 0; }
|
|
104
|
+
.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; }
|
|
105
|
+
.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); }
|
|
106
|
+
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; }
|
|
107
|
+
p { margin: 10px; }
|
|
108
|
+
`,yd=h`
|
|
109
|
+
:host { position: relative; z-index: 5; display: block; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
|
110
|
+
footer { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 12px; border-top: 1px solid var(--pi-border); }
|
|
111
|
+
footer.shell-mode { border-top-color: var(--pi-success); background: var(--pi-success-bg); }
|
|
112
|
+
.editor-wrap { position: relative; min-width: 0; }
|
|
113
|
+
.actions { display: flex; gap: 8px; align-items: center; justify-content: flex-end; flex-wrap: nowrap; white-space: nowrap; }
|
|
114
|
+
.compact-status { display: flex; min-width: 0; align-items: center; gap: 6px; color: var(--pi-muted); font-size: 12px; flex: 1 1 0; }
|
|
115
|
+
.compact-status > button { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
116
|
+
.select-model { max-width: min(42vw, 320px); }
|
|
117
|
+
.icon-button { flex: 0 0 auto; display: inline-grid; place-items: center; width: 36px; height: 36px; padding: 0; }
|
|
118
|
+
.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; }
|
|
119
|
+
.icon-button .prompt-action-icon-filled { fill: currentColor; stroke: none; }
|
|
120
|
+
.send-button:not(:disabled) { color: var(--pi-accent, var(--pi-text)); }
|
|
121
|
+
.stop-button:not(:disabled) { color: var(--pi-danger); }
|
|
122
|
+
.select-thinking .prompt-thinking-gauge .gauge-bar { fill: currentColor; stroke: none; opacity: .28; }
|
|
123
|
+
.select-thinking .prompt-thinking-gauge .gauge-bar-active { opacity: 1; }
|
|
124
|
+
.editor-attach { position: absolute; right: 8px; bottom: 8px; z-index: 2; width: 30px; height: 30px; }
|
|
125
|
+
.editor-attach .prompt-action-icon { width: 16px; height: 16px; }
|
|
126
|
+
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); }
|
|
127
|
+
textarea { overflow-y: auto; padding: 8px; }
|
|
128
|
+
.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; }
|
|
129
|
+
.markdown-editor .cm-content { min-height: 38px; padding: 8px 44px 8px 8px; caret-color: var(--pi-text); text-align: start; unicode-bidi: plaintext; }
|
|
130
|
+
.markdown-editor .cm-line { padding: 0; unicode-bidi: plaintext; }
|
|
131
|
+
.markdown-editor .cm-placeholder { color: var(--pi-dim); }
|
|
132
|
+
.markdown-editor .cm-focused { outline: none; }
|
|
133
|
+
.shell-mode textarea, .shell-mode .markdown-editor .cm-editor { border-color: var(--pi-success); box-shadow: 0 0 0 1px var(--pi-success-ring); }
|
|
134
|
+
.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; }
|
|
135
|
+
.attachments { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
|
|
136
|
+
.attachment-chip { position: relative; width: 56px; height: 56px; border: 1px solid var(--pi-border); border-radius: 8px; overflow: hidden; background: var(--pi-bg); }
|
|
137
|
+
.attachment-chip img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
138
|
+
.attachment-chip-file { display: grid; place-items: center; }
|
|
139
|
+
.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; }
|
|
140
|
+
.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; }
|
|
141
|
+
.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; }
|
|
142
|
+
.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); }
|
|
143
|
+
.attachment-error { flex-basis: 100%; color: var(--pi-danger); font-size: 12px; }
|
|
144
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
|
145
|
+
button:disabled, textarea:disabled, .markdown-editor-disabled .cm-editor { opacity: .5; cursor: not-allowed; }
|
|
146
|
+
@media (max-width: 640px) {
|
|
147
|
+
footer { gap: 8px; padding: 8px; }
|
|
148
|
+
.actions { gap: 6px; }
|
|
149
|
+
.compact-status { flex: 1 1 220px; gap: 4px; }
|
|
150
|
+
.select-model { max-width: min(58vw, 260px); }
|
|
151
|
+
button { padding: 6px 8px; }
|
|
152
|
+
}
|
|
153
|
+
@media (max-width: 430px) {
|
|
154
|
+
.compact-status { flex-basis: 170px; font-size: 11px; }
|
|
155
|
+
.select-model { max-width: 48vw; }
|
|
156
|
+
button { padding: 5px 7px; }
|
|
157
|
+
.icon-button { width: 34px; height: 34px; }
|
|
158
|
+
}
|
|
159
|
+
`;function z(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 bd=`modulepreload`,xd=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=xd(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`:bd,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)})},wd=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=Ld(t?.files);t!==void 0&&(t.value=``),n.length>0&&this.openUploadReview(n)},this.handleDragEnter=e=>{Rd(e)&&(e.preventDefault(),this.dragDepth+=1,this.dragActive=!0)},this.handleDragOver=e=>{Rd(e)&&(e.preventDefault(),e.dataTransfer!==null&&(e.dataTransfer.dropEffect=`copy`),this.dragActive=!0)},this.handleDragLeave=e=>{Rd(e)&&(e.preventDefault(),this.dragDepth=Math.max(0,this.dragDepth-1),this.dragDepth===0&&(this.dragActive=!1))},this.handleDrop=e=>{if(!Rd(e))return;e.preventDefault(),this.dragDepth=0,this.dragActive=!1;let t=Ld(e.dataTransfer?.files),n=this.context;t.length>0&&n!==void 0&&jd(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&&Md(t)!==Md(this.context)&&this.resetPendingUpload()}render(){let e=this.context;if(e===void 0)return g`<p class="muted">文件不可用。</p>`;let t=e.selectedFilePath,n=Od(e.fileTree,e.expandedDirs,t),r=kd(t,n),i=t!==void 0&&t!==``;return g`
|
|
160
|
+
<section
|
|
161
|
+
class=${this.dragActive?`files-panel dragging`:`files-panel`}
|
|
162
|
+
@dragenter=${this.handleDragEnter}
|
|
163
|
+
@dragover=${this.handleDragOver}
|
|
164
|
+
@dragleave=${this.handleDragLeave}
|
|
165
|
+
@drop=${this.handleDrop}
|
|
166
|
+
>
|
|
167
|
+
<section class="toolbar">
|
|
168
|
+
<strong>文件</strong>
|
|
169
|
+
${e.fileTreeStale?g`<span class="stale">过期</span>`:null}
|
|
170
|
+
<div class="toolbar-actions">
|
|
171
|
+
<button @click=${()=>{this.promptCreateFile(e,n)}}>新建文件</button>
|
|
172
|
+
<button @click=${()=>{this.promptCreateDirectory(e,n)}}>新建文件夹</button>
|
|
173
|
+
<button aria-label="上传文件" @click=${this.openFilePicker}>上传</button>
|
|
174
|
+
<button title=${r&&t!==void 0?`下载 ${t}`:`请选择要下载的文件`} ?disabled=${!r} @click=${e.onDownloadSelectedFile}>下载</button>
|
|
175
|
+
<button class="danger" title=${i?`删除 ${t}`:`请选择要删除的文件或文件夹`} ?disabled=${!i} @click=${()=>{this.confirmDeleteSelectedPath(e)}}>删除</button>
|
|
176
|
+
<button @click=${e.onRefreshFiles}>刷新</button>
|
|
177
|
+
</div>
|
|
178
|
+
<input id="workspace-upload-input" class="visually-hidden" type="file" multiple @change=${this.handleFileInputChange} />
|
|
179
|
+
</section>
|
|
180
|
+
${this.renderUploadProgress(e)}
|
|
181
|
+
<section class="split">
|
|
182
|
+
<div class="list tree">
|
|
183
|
+
${e.fileTree.length===0?g`<p class="muted">尚未加载文件。</p>`:e.fileTree.map(t=>this.renderTreeEntry(e,t,0))}
|
|
184
|
+
</div>
|
|
185
|
+
<div class="viewer">
|
|
186
|
+
${this.renderFileViewer(e)}
|
|
187
|
+
</div>
|
|
188
|
+
</section>
|
|
189
|
+
<div class="drop-overlay" aria-hidden=${this.dragActive?`false`:`true`}>
|
|
190
|
+
<div>
|
|
191
|
+
<strong>拖放文件以上传</strong>
|
|
192
|
+
<span>将立即上传到默认文件夹。</span>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
${this.pendingUpload===void 0?null:this.renderUploadDialog(e,this.pendingUpload)}
|
|
196
|
+
</section>
|
|
197
|
+
`}renderTreeEntry(e,t,n){let r=e.expandedDirs[t.path],i=r!==void 0;return g`
|
|
198
|
+
<button class=${e.selectedFilePath===t.path?`row selected`:`row`} style=${`--depth:${String(n)}`} @click=${()=>{this.selectTreeEntry(e,t)}}>
|
|
199
|
+
<span>${t.type===`directory`?i?`▾`:`▸`:`·`}</span>
|
|
200
|
+
<span>${t.name}</span>
|
|
201
|
+
</button>
|
|
202
|
+
${i?r.map(t=>this.renderTreeEntry(e,t,n+1)):null}
|
|
203
|
+
`}selectTreeEntry(e,t){if(t.type===`directory`){e.onSelectDirectory(t.path),e.onExpandDir(t.path);return}e.onSelectFile(t.path)}renderFileViewer(e){let t=e.selectedFileContent;return e.selectedFilePath===void 0||e.selectedFilePath===``?g`<p class="muted">请选择文件。</p>`:Od(e.fileTree,e.expandedDirs,e.selectedFilePath)===`directory`?g`<p class="muted">已选择文件夹:${e.selectedFilePath}</p>`:t===void 0?g`<p class="muted">正在加载 ${e.selectedFilePath}…</p>`:t.mediaType===`image`?this.renderImageViewer(e,t):t.binary?g`<p class="muted">二进制文件:${t.path} · ${qd(t.size)}</p>`:(Kd(),g`
|
|
204
|
+
<div class="viewer-header"><strong>${t.path}</strong><small>${t.language??`文本`}${t.truncated?` · 已截断`:``}</small></div>
|
|
205
|
+
<code-viewer .content=${t.content} .language=${t.language}></code-viewer>
|
|
206
|
+
`)}renderImageViewer(e,t){let n=`${t.mimeType??`image`} · ${qd(t.size)}`;if(t.size>10485760)return g`
|
|
207
|
+
<div class="viewer-header"><strong>${t.path}</strong><small>${n}</small></div>
|
|
208
|
+
<p class="muted">图片过大,无法预览:${qd(t.size)} · 限制 ${_d}</p>
|
|
209
|
+
`;let r=Si(e.workspace.projectId,e.workspace.id,t.path,{modifiedAt:t.modifiedAt,machineId:e.machine.id});return g`
|
|
210
|
+
<div class="viewer-header"><strong>${t.path}</strong><small>${n}</small></div>
|
|
211
|
+
<div class="image-preview">
|
|
212
|
+
<img src=${r} alt=${t.path} decoding="async" />
|
|
213
|
+
</div>
|
|
214
|
+
`}renderUploadProgress(e){let t=Td(e.state.workspaceUploadBatches,{projectId:e.workspace.projectId,workspaceId:e.workspace.id,machineId:e.machine.id});return t.length===0?null:g`
|
|
215
|
+
<section class="upload-progress" aria-label="工作区上传">
|
|
216
|
+
<div class="upload-progress-header">
|
|
217
|
+
<strong>上传</strong>
|
|
218
|
+
<small>${zd(t)}</small>
|
|
219
|
+
</div>
|
|
220
|
+
${t.map(t=>this.renderUploadBatch(e,t))}
|
|
221
|
+
</section>
|
|
222
|
+
`}renderUploadBatch(e,t){return g`
|
|
223
|
+
<article class=${`upload-batch ${t.status}`}>
|
|
224
|
+
<div class="upload-batch-heading">
|
|
225
|
+
<div>
|
|
226
|
+
<strong>${Bd(t)}</strong>
|
|
227
|
+
<small>${t.destinationFolder===``?`工作区根目录`:t.destinationFolder}</small>
|
|
228
|
+
</div>
|
|
229
|
+
<span>${Vd(t)}</span>
|
|
230
|
+
</div>
|
|
231
|
+
<progress max="1" .value=${Hd(t)}></progress>
|
|
232
|
+
<div class="upload-file-list">
|
|
233
|
+
${t.files.map(e=>this.renderUploadFile(e))}
|
|
234
|
+
</div>
|
|
235
|
+
<div class="upload-actions">
|
|
236
|
+
${t.status===`uploading`?g`<button @click=${()=>{e.onCancelWorkspaceUpload(t.id)}}>取消</button>`:g`<button @click=${()=>{e.onClearWorkspaceUpload(t.id)}}>关闭</button>`}
|
|
237
|
+
</div>
|
|
238
|
+
</article>
|
|
239
|
+
`}renderUploadFile(e){let t=Wd(e);return g`
|
|
240
|
+
<div class=${`upload-file ${e.status}`}>
|
|
241
|
+
<div class="upload-file-main">
|
|
242
|
+
<span>${e.name}</span>
|
|
243
|
+
<small>${t}</small>
|
|
244
|
+
</div>
|
|
245
|
+
<span class="upload-file-status">${Ud(e)}</span>
|
|
246
|
+
</div>
|
|
247
|
+
`}renderUploadDialog(e,t){let n=t.files.length;return g`
|
|
248
|
+
<div class="dialog-backdrop" @mousedown=${()=>{this.closeUploadDialog()}}>
|
|
249
|
+
<section class="upload-dialog" role="dialog" aria-modal="true" aria-label="检查文件上传" @mousedown=${e=>{e.stopPropagation()}} @keydown=${this.handleDialogKeyDown}>
|
|
250
|
+
<header>
|
|
251
|
+
<div>
|
|
252
|
+
<span class="eyebrow">上传</span>
|
|
253
|
+
<h2>检查 ${String(n)} 个文件</h2>
|
|
254
|
+
</div>
|
|
255
|
+
<button class="close-button" title="取消上传" aria-label="取消上传" @click=${()=>{this.closeUploadDialog()}}>×</button>
|
|
256
|
+
</header>
|
|
257
|
+
<form @submit=${n=>{this.submitUploadReview(n,e,t)}}>
|
|
258
|
+
<label>
|
|
259
|
+
<span>目标文件夹</span>
|
|
260
|
+
<input .value=${this.destinationFolder} placeholder=${e.workspaceUploadDefaultFolder} @input=${this.handleDestinationInput} />
|
|
261
|
+
<small>工作区相对路径。留空则上传到工作区根目录。</small>
|
|
262
|
+
</label>
|
|
263
|
+
<div class="dialog-options">
|
|
264
|
+
<label>
|
|
265
|
+
<input type="checkbox" .checked=${this.createDirs} @change=${this.handleCreateDirsChange} />
|
|
266
|
+
<span>创建上级目录</span>
|
|
267
|
+
</label>
|
|
268
|
+
<label>
|
|
269
|
+
<input type="checkbox" .checked=${this.overwrite} @change=${this.handleOverwriteChange} />
|
|
270
|
+
<span>覆盖已存在的文件</span>
|
|
271
|
+
</label>
|
|
272
|
+
</div>
|
|
273
|
+
<section class="review-files" aria-label="待上传文件">
|
|
274
|
+
<strong>文件</strong>
|
|
275
|
+
${t.files.map(e=>g`
|
|
276
|
+
<div class="review-file">
|
|
277
|
+
<span>${e.name}</span>
|
|
278
|
+
<small>${qd(e.size)}</small>
|
|
279
|
+
</div>
|
|
280
|
+
`)}
|
|
281
|
+
</section>
|
|
282
|
+
${this.formError===``?null:g`<div class="dialog-error" role="alert">${this.formError}</div>`}
|
|
283
|
+
<footer>
|
|
284
|
+
<button type="button" @click=${()=>{this.closeUploadDialog()}}>取消</button>
|
|
285
|
+
<button type="submit">上传</button>
|
|
286
|
+
</footer>
|
|
287
|
+
</form>
|
|
288
|
+
</section>
|
|
289
|
+
</div>
|
|
290
|
+
`}promptCreateFile(e,t){let n=Nd(`新建文件路径`,Ad(e.selectedFilePath,t,`new-file.txt`));n!==void 0&&e.onCreateFile(n)}promptCreateDirectory(e,t){let n=Nd(`新建文件夹路径`,Ad(e.selectedFilePath,t,`new-folder`));n!==void 0&&e.onCreateDirectory(n)}confirmDeleteSelectedPath(e){let t=e.selectedFilePath;t===void 0||t===``||window.confirm(`删除 ${t}?此操作无法撤销。`)&&e.onDeleteSelectedPath()}openUploadReview(e){let t=this.context,n=Dd(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=Ed(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=[vd,h`
|
|
291
|
+
:host { flex: 1 1 auto; }
|
|
292
|
+
.files-panel { position: relative; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
|
|
293
|
+
.toolbar-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
|
|
294
|
+
.toolbar .toolbar-actions button { margin-left: 0; }
|
|
295
|
+
.toolbar .toolbar-actions button.danger { color: var(--pi-danger); }
|
|
296
|
+
.toolbar .toolbar-actions button.danger:not(:disabled):hover { background: color-mix(in srgb, var(--pi-danger) 14%, transparent); }
|
|
297
|
+
.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; }
|
|
298
|
+
.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; }
|
|
299
|
+
.files-panel.dragging .drop-overlay { opacity: 1; }
|
|
300
|
+
.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); }
|
|
301
|
+
.drop-overlay span { color: var(--pi-muted); }
|
|
302
|
+
.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); }
|
|
303
|
+
.upload-progress-header, .upload-batch-heading, .upload-actions { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
|
|
304
|
+
.upload-batch { display: grid; gap: 6px; border: 1px solid var(--pi-border-muted); border-radius: 8px; background: var(--pi-bg); padding: 8px; }
|
|
305
|
+
.upload-batch.error { border-color: var(--pi-danger); }
|
|
306
|
+
.upload-batch.cancelled { border-color: var(--pi-warning-border); }
|
|
307
|
+
.upload-batch.completed { border-color: var(--pi-success-border); }
|
|
308
|
+
.upload-batch-heading > div { min-width: 0; display: grid; gap: 2px; }
|
|
309
|
+
.upload-batch-heading strong, .upload-batch-heading small { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
310
|
+
progress { width: 100%; accent-color: var(--pi-accent); }
|
|
311
|
+
.upload-file-list { display: grid; gap: 4px; max-height: 180px; overflow: auto; padding-right: 2px; }
|
|
312
|
+
.upload-file { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 8px; color: var(--pi-muted); }
|
|
313
|
+
.upload-file.completed .upload-file-status { color: var(--pi-success); }
|
|
314
|
+
.upload-file.error { color: var(--pi-danger); }
|
|
315
|
+
.upload-file.cancelled .upload-file-status { color: var(--pi-warning); }
|
|
316
|
+
.upload-file-main { min-width: 0; display: grid; gap: 1px; }
|
|
317
|
+
.upload-file-main span, .upload-file-main small { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
318
|
+
.upload-file-status { font-size: 12px; white-space: nowrap; }
|
|
319
|
+
.upload-actions { justify-content: end; }
|
|
320
|
+
.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); }
|
|
321
|
+
.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); }
|
|
322
|
+
.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); }
|
|
323
|
+
.upload-dialog h2 { margin: 2px 0 0; font-size: 18px; line-height: 1.2; }
|
|
324
|
+
.eyebrow { color: var(--pi-muted); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; }
|
|
325
|
+
.close-button { font-size: 20px; line-height: 1; padding: 4px 9px; }
|
|
326
|
+
form { min-height: 0; display: flex; flex-direction: column; gap: 12px; overflow: auto; padding: 16px; }
|
|
327
|
+
form > label { display: grid; gap: 6px; }
|
|
328
|
+
form > label > span, .review-files > strong { font-weight: 600; }
|
|
329
|
+
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); }
|
|
330
|
+
input:focus-visible { outline: 2px solid var(--pi-accent); outline-offset: 1px; }
|
|
331
|
+
.dialog-options { display: grid; gap: 8px; }
|
|
332
|
+
.dialog-options label { display: flex; align-items: center; gap: 8px; color: var(--pi-text); }
|
|
333
|
+
.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; }
|
|
334
|
+
.review-file { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: baseline; }
|
|
335
|
+
.review-file span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
336
|
+
.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; }
|
|
337
|
+
footer { display: flex; justify-content: flex-end; gap: 8px; padding-top: 4px; }
|
|
338
|
+
`]}};z([b({attribute:!1})],wd.prototype,`context`,void 0),z([S(`#workspace-upload-input`)],wd.prototype,`uploadInput`,void 0),z([x()],wd.prototype,`pendingUpload`,void 0),z([x()],wd.prototype,`destinationFolder`,void 0),z([x()],wd.prototype,`overwrite`,void 0),z([x()],wd.prototype,`createDirs`,void 0),z([x()],wd.prototype,`formError`,void 0),z([x()],wd.prototype,`dragActive`,void 0),wd=z([y(`workspace-files-panel`)],wd);function Td(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 Ed(e,t){if(e.length===0)return`请至少选择一个要上传的文件。`;for(let n of e)try{da(t,n.name)}catch(e){return e instanceof Error?e.message:String(e)}}function Dd(e){return{destinationFolder:e,createDirs:!0,overwrite:!1}}function Od(e,t,n){if(n!==void 0)return Pd(e,t,n)?.type}function kd(e,t){return e!==void 0&&e!==``&&t===`file`}function Ad(e,t,n){if(e===void 0||e===``)return n;if(t===`directory`)return Id(e,n);let r=Fd(e);return r===``?n:Id(r,n)}function jd(e,t){if(t.length!==0)return e.onStartWorkspaceUpload(t,{destinationFolder:e.workspaceUploadDefaultFolder,createDirs:!0,overwrite:!1,selectUploadedFile:!0})}function Md(e){return`${e.machine.id}:${e.workspace.projectId}:${e.workspace.id}`}function Nd(e,t){let n=window.prompt(e,t);if(n===null)return;let r=n.trim();return r===``?void 0:r}function Pd(e,t,n){let r=e.find(e=>e.path===n);if(r!==void 0)return r;for(let e of Object.values(t)){let t=e.find(e=>e.path===n);if(t!==void 0)return t}}function Fd(e){let t=e.lastIndexOf(`/`);return t<0?``:e.slice(0,t)}function Id(e,t){return e===``?t:`${e.replace(/\/+$/u,``)}/${t.replace(/^\/+/u,``)}`}function Ld(e){return e==null?[]:Array.from(e)}function Rd(e){return Array.from(e.dataTransfer?.types??[]).includes(`Files`)}function zd(e){let t=e.filter(e=>e.status===`uploading`).length;return t===0?`${String(e.length)} 个最近`:`${String(t)} 个上传中`}function Bd(e){let t=String(e.files.length);switch(e.status){case`completed`:return`已上传 ${t} 个文件`;case`error`:return`${t} 个文件上传失败`;case`cancelled`:return`已取消 ${t} 个文件的上传`;case`uploading`:return`正在上传 ${t} 个文件`}}function Vd(e){switch(e.status){case`completed`:return`完成`;case`error`:return`失败`;case`cancelled`:return`已取消`;case`uploading`:return Gd(e.percent)}}function Hd(e){return e.status===`uploading`?e.percent:1}function Ud(e){switch(e.status){case`pending`:return`待处理`;case`uploading`:return Gd(e.percent);case`completed`:return`完成`;case`error`:return`错误`;case`cancelled`:return`已取消`}}function Wd(e){return e.error===void 0?e.response===void 0?`${e.path} · ${qd(e.loaded)} / ${qd(e.total)}`:`已写入 ${e.response.path}`:e.error}function Gd(e){return`${String(Math.round(Math.max(0,Math.min(1,e))*100))}%`}function Kd(){Cd(()=>import(`./CodeViewer-DxWBEGHy.js`),__vite__mapDeps([0,1,2,3]),import.meta.url)}function qd(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`${Jd(t)} KB`;let n=t/1024;return n<1024?`${Jd(n)} MB`:`${Jd(n/1024)} GB`}function Jd(e){return e>=10?String(Math.round(e)):e.toFixed(1)}function Yd(){return[{id:`workspace.files`,title:`文件`,icon:gd(`files`),order:10,render:Xd},{id:`workspace.git`,title:`Git`,icon:gd(`git`),order:20,visible:({workspace:e})=>e.isGitRepo,render:Qd},{id:`workspace.terminal`,title:`终端`,icon:gd(`terminal`),order:30,badge:e=>e.activeTerminalCount>0?e.activeTerminalCount:void 0,render:Zd}]}function Xd(e){return g`<workspace-files-panel .context=${e}></workspace-files-panel>`}function Zd(e){return nf(),g`<terminal-panel .workspace=${e.workspace} .machineId=${e.machine.id} .selectedTerminalId=${e.selectedTerminalId} .autoStart=${e.terminalAutoStart} .onSelectTerminal=${e.onSelectTerminal}></terminal-panel>`}function Qd(e){let t=e.gitStatus;return g`
|
|
339
|
+
<section class="toolbar">
|
|
340
|
+
<strong>Git</strong>
|
|
341
|
+
${e.gitStale?g`<span class="stale">过期</span>`:null}
|
|
342
|
+
<button @click=${e.onRefreshGit}>刷新</button>
|
|
343
|
+
</section>
|
|
344
|
+
<section class="split">
|
|
345
|
+
<div class="list">
|
|
346
|
+
${t===void 0?g`<p class="muted">尚未加载状态。</p>`:t.isGitRepo?g`
|
|
347
|
+
<p class="summary">${rf(t)}</p>
|
|
348
|
+
${t.files.length===0?g`<p class="muted">没有变更。</p>`:t.files.map(t=>g`
|
|
349
|
+
<button class="row ${e.selectedDiffPath===t.path?`selected`:``}" @click=${()=>{e.onSelectDiff(t.path)}}>
|
|
350
|
+
<span>${af(t.index,t.workingTree)}</span>
|
|
351
|
+
<span>${t.path}</span>
|
|
352
|
+
</button>
|
|
353
|
+
`)}
|
|
354
|
+
`:g`<p class="muted">不是 Git 仓库。</p>`}
|
|
355
|
+
</div>
|
|
356
|
+
<div class="viewer">
|
|
357
|
+
${$d(e)}
|
|
358
|
+
</div>
|
|
359
|
+
</section>
|
|
360
|
+
`}function $d(e){if(e.selectedDiffPath===void 0||e.selectedDiffPath===``)return g`<p class="muted">请选择一个已变更文件。</p>`;let t=e.selectedDiff,n=e.selectedStagedDiff;if(t===void 0||n===void 0)return g`<p class="muted">正在加载 diff…</p>`;let r=[n,t].filter(e=>e.diff!==``);return r.length===0?g`<p class="muted">没有 staged 或 unstaged diff。</p>`:g`
|
|
361
|
+
<div class=${r.length===1?`diffs single`:`diffs`}>
|
|
362
|
+
${r.map(e=>ef(e))}
|
|
363
|
+
</div>
|
|
364
|
+
`}function ef(e){return tf(),g`
|
|
365
|
+
<section class="diff-section">
|
|
366
|
+
<div class="viewer-header"><strong>${e.path??`diff`}</strong><small>${e.staged?`已暂存`:`未暂存`}${e.truncated?` · 已截断`:``}</small></div>
|
|
367
|
+
<unified-diff-viewer .diff=${e.diff}></unified-diff-viewer>
|
|
368
|
+
</section>
|
|
369
|
+
`}function tf(){Cd(()=>import(`./UnifiedDiffViewer-CvVtrOUV.js`),[],import.meta.url)}function nf(){Cd(()=>import(`./TerminalPanel-CLBbwrSg.js`),__vite__mapDeps([4,5,6]),import.meta.url)}function rf(e){let t=e.branch??`分离 HEAD`,n=e.ahead??0,r=e.behind??0;return n===0&&r===0?t:`${t} · ↑${String(n)} ↓${String(r)}`}function af(e,t){return(t===`unmodified`?e:t).slice(0,1).toUpperCase()}var of={apiVersion:1,name:`PI WEB 核心`,activate:()=>{let e=!vt();return{contributions:{actions:e?ad():ad().filter(e=>e.id!==`view.terminal`),workspacePanels:e?Yd():Yd().filter(e=>e.id!==`workspace.terminal`)}}}},sf={"--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`},cf={"--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`},lf={"--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`},uf={apiVersion:1,name:`PI WEB 主题`,activate:()=>({contributions:{themes:[{id:`pi-web-dark`,name:`PI WEB 深色`,description:`PI WEB 深色配色。`,order:10,colorScheme:`dark`,tokens:cf},{id:`pi-web-light`,name:`PI WEB 浅色`,description:`PI WEB 浅色配色。`,order:20,colorScheme:`light`,tokens:lf},{id:`classic`,name:`PI WEB 经典`,description:`原始 PI WEB 深色配色。`,order:30,colorScheme:`dark`,tokens:sf}],themePairs:[{id:`pi-web`,name:`PI WEB`,description:`跟随系统浅色/深色偏好使用 PI WEB 主题。`,order:10,light:`pi-web-light`,dark:`pi-web-dark`}]}})},df=/^[a-z][a-z0-9.-]*$/u;function ff(e){return df.test(e)}var pf=`machine.`;function mf(e,t){if(e===``)throw Error(`Machine id is required`);if(!ff(t))throw Error(`Invalid PI WEB plugin id: ${t}`);return`${pf}${hf(e)}.${t}`}function hf(e){return[...new TextEncoder().encode(e)].map(e=>e.toString(16).padStart(2,`0`)).join(``)}async function gf(e=`pi-web-plugins/manifest.json`,t={}){let n=Dt(e),r=await yf(n);if(r===void 0)return[];let i=[];for(let e of r.plugins)if(t.shouldLoadPlugin?.(e)!==!1)try{let r=_f(e.module,n),a=Sf(await(t.moduleLoader??vf)(r),r);i.push({id:t.machineId===void 0?e.id:mf(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 _f(e,t,n){return e.startsWith(`/`)?n===void 0?Dt(e):Dt(e,n):new URL(e,t).toString()}async function vf(e){return Cd(()=>import(e),[],import.meta.url)}async function yf(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 bf(await t.json())}}function bf(e){if(!wf(e)||!Array.isArray(e.plugins))throw Error(`Invalid plugin manifest`);return{plugins:e.plugins.map(e=>{if(!wf(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:xf(e.machineSpecific)}})}}function xf(e){if(e===void 0)return!1;if(typeof e!=`boolean`)throw Error(`Invalid plugin manifest entry`);return e}function Sf(e,t){if(!wf(e))throw Error(`Plugin module ${t} did not export an object`);let n=e.default;if(!Cf(n))throw Error(`Plugin module ${t} default export is not a PiWebPlugin`);return n}function Cf(e){return wf(e)&&e.apiVersion===1&&typeof e.name==`string`&&typeof e.activate==`function`}function wf(e){return typeof e==`object`&&!!e}var Tf=/^[a-z][a-z0-9.-]*$/u,Ef=/^[a-z][a-z0-9.-]*$/u,Df=new WeakMap,Of=new WeakMap,kf=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=If(e);return this.actions.filter(e=>this.isContributionActive(e.pluginId,e.machineId,t,e.sourcePluginId)).map(t=>{let n=Af(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?.(jf(t,e))??!0),...a===void 0?{}:{badge:t=>this.isContributionActive(e,n,t.machine.id,r)?a(jf(t,e)):void 0},render:n=>t.render(jf(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(!Tf.test(e))throw Error(`Invalid plugin id: ${e}`)}validateLocalId(e){if(!Ef.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}: ${Ff(t)}`);return t}};function Af(e,t){return Df.get(e)?.(t)??e}function jf(e,t){return Of.get(e)?.(t)??e}function Mf(e,t){return Df.set(e,t),e}function Nf(e,t){return Of.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 Ff(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 If(e){return e.state.selectedMachine?.id??`local`}var Lf=[`(display-mode: standalone)`,`(display-mode: fullscreen)`,`(display-mode: minimal-ui)`];function Rf(){return typeof window>`u`||!(`matchMedia`in window)?[]:Lf.map(e=>window.matchMedia(e))}function zf(e,t=Bf()){return e.some(e=>e.matches)||Vf(t)}function Bf(){return typeof navigator>`u`?void 0:navigator}function Vf(e){return e!==void 0&&`standalone`in e&&e.standalone===!0}var Hf=class{constructor(e=Uf()){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 Uf(){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 Wf=`(max-width: 760px)`,Gf=`(max-width: 1180px)`,Kf=class{constructor(e,t={}){this.host=e,this.onMobileNavigationMediaChange=e=>{this.isMobileNavigationLayout!==e.matches&&(this.isMobileNavigationLayout=e.matches,this.host.requestUpdate())},this.onStackedWorkspaceMediaChange=e=>{this.isStackedWorkspaceLayout!==e.matches&&(this.isStackedWorkspaceLayout=e.matches,this.host.requestUpdate())},this.onPwaDisplayModeChange=()=>{let e=zf(this.pwaDisplayModeMedia);this.isPwaDisplayMode!==e&&(this.isPwaDisplayMode=e,this.host.requestUpdate())},e.addController(this),this.mobileNavigationMedia=t.mobileNavigationMedia??qf(),this.stackedWorkspaceMedia=t.stackedWorkspaceMedia??Jf(),this.pwaDisplayModeMedia=t.pwaDisplayModeMedia??Rf(),this.viewportPositionRepairer=t.viewportPositionRepairer??new Hf,this.isMobileNavigationLayout=this.mobileNavigationMedia?.matches??!1,this.isStackedWorkspaceLayout=this.stackedWorkspaceMedia?.matches??!1,this.isPwaDisplayMode=zf(this.pwaDisplayModeMedia)}hostConnected(){this.mobileNavigationMedia?.addEventListener(`change`,this.onMobileNavigationMediaChange),this.stackedWorkspaceMedia?.addEventListener(`change`,this.onStackedWorkspaceMediaChange);for(let e of this.pwaDisplayModeMedia)e.addEventListener(`change`,this.onPwaDisplayModeChange)}hostDisconnected(){this.mobileNavigationMedia?.removeEventListener(`change`,this.onMobileNavigationMediaChange),this.stackedWorkspaceMedia?.removeEventListener(`change`,this.onStackedWorkspaceMediaChange);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.normalizedMainView(void 0,!1)}normalizedMainView(e,t){return Yf(e,{isMobileNavigationLayout:this.isMobileNavigationLayout,isStackedWorkspaceLayout:this.isStackedWorkspaceLayout,hasSelectedSession:t})}repairViewportPosition(){this.viewportPositionRepairer.repair(this.shouldRepairViewportPosition())}shouldRepairViewportPosition(){return this.isMobileNavigationLayout||this.isPwaDisplayMode}};function qf(){if(!(typeof window>`u`||!(`matchMedia`in window)))return window.matchMedia(Wf)}function Jf(){if(!(typeof window>`u`||!(`matchMedia`in window)))return window.matchMedia(Gf)}function Yf(e,t){let n=e??(t.isMobileNavigationLayout?`navigation`:`chat`);return t.isMobileNavigationLayout||!t.isStackedWorkspaceLayout||!t.hasSelectedSession||n===`navigation`||n===`chat`?n:`chat`}var Xf=class{constructor(e,t={}){this.callbacks=e,this.refreshes=new Pa,this.connected=!1,this.onFocus=()=>{this.handleResumeSignal()},this.onVisibilityChange=()=>{this.isDocumentVisible()&&this.handleResumeSignal()},this.windowTarget=t.windowTarget??Zf(),this.documentTarget=t.documentTarget??Qf(),this.isDocumentVisible=t.isDocumentVisible??$f,this.scheduleFrame=t.scheduleFrame??ep}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 Zf(){return typeof window>`u`?void 0:window}function Qf(){return typeof document>`u`?void 0:document}function $f(){return typeof document>`u`||document.visibilityState===`visible`}function ep(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 tp=[`machines`,`projects`,`workspaces`,`sessions`];function np(e){return e.selectedProject===void 0?`projects`:e.selectedWorkspace===void 0?`workspaces`:`sessions`}function rp(e,t){if(e!==`none`)return e??np(t)}function ip(e,t){return t.isMobileLayout?rp(t.expanded,t.state)!==e:t.collapsedSections?.includes(e)??!1}function ap(e,t,n){return n.isMobileLayout?rp(e,n.state)===t?`none`:t:e}function op(e,t,n){return n?t:e}function sp(e,t){let n=new Set(e);return n.has(t)?n.delete(t):n.add(t),up(n)}function cp(e){return tp[tp.indexOf(e)+1]}var lp=class{hostConnected(){}constructor(e,t,n){this.host=e,this.getState=t,this.isMobileLayout=n,this.collapsedSections=[],e.addController(this)}expandedSection(){return rp(this.expanded,this.getState())}isCollapsed(e){return ip(e,{isMobileLayout:this.isMobileLayout(),expanded:this.expanded,state:this.getState(),collapsedSections:this.collapsedSections})}toggle(e){if(this.isMobileLayout()){this.setExpanded(ap(this.expanded,e,{isMobileLayout:!0,state:this.getState()}));return}this.setCollapsedSections(sp(this.collapsedSections,e))}expand(e){if(this.isMobileLayout()){this.setExpanded(op(this.expanded,e,!0));return}this.setCollapsedSections(this.collapsedSections.filter(t=>t!==e))}advanceAfterSelection(e){if(!this.isMobileLayout())return;let t=cp(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){dp(this.collapsedSections,e)||(this.collapsedSections=e,this.host.requestUpdate())}};function up(e){let t=new Set(e);return tp.filter(e=>t.has(e))}function dp(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}var fp=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`,pp(e),...this.navigationPanelCollapsed?[`navigation-panel-collapsed`]:[],...this.workspacePanelCollapsed?[`workspace-panel-collapsed`]:[]].join(` `)}};function pp(e){return e===`navigation`?`navigation-view`:e===`chat`?`chat-view`:`workspace-view`}var mp=`pi-web:panel-sizes:v1`,hp={navigation:{minWidth:180,maxWidth:4096,defaultWidth:340,keyboardStep:24,largeKeyboardStep:72},workspace:{minWidth:240,maxWidth:4096,defaultWidth:480,keyboardStep:24,largeKeyboardStep:72}},gp=class{constructor(e,t={}){this.host=e,e.addController(this),this.storage=t.storage??Ap(),this.panelSizes=Sp(this.storage)}hostConnected(){}constraints(e){return _p(e)}panelWidth(e,t){return xp(e,t??this.storedPanelWidth(e)??this.constraints(e).defaultWidth)}resizePanel(e,t,n={}){let r=xp(e,t);this.storedPanelWidth(e)!==r&&(this.panelSizes=Ep(this.panelSizes,e,r),n.persist!==!1&&this.persistPanelSizes(),this.host.requestUpdate())}resetPanel(e,t={}){this.storedPanelWidth(e)!==void 0&&(this.panelSizes=Dp(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(){Cp(this.panelSizes,this.storage)}shellStyle(e={}){let t=[];return this.panelSizes.navigationPanelWidth!==void 0&&t.push(`--navigation-panel-size: ${kp(xp(`navigation`,this.panelSizes.navigationPanelWidth,e.navigation))};`),this.panelSizes.workspacePanelWidth!==void 0&&t.push(`--workspace-panel-size: ${kp(xp(`workspace`,this.panelSizes.workspacePanelWidth,e.workspace))};`),t.join(` `)}storedPanelWidth(e){return e===`navigation`?this.panelSizes.navigationPanelWidth:this.panelSizes.workspacePanelWidth}};function _p(e){return hp[e]}function vp(e,t,n){return e===`navigation`?n-t:t-n}function yp(e,t,n,r,i=_p(e)){return xp(e,t+vp(e,n,r),i)}function bp(e,t,n,r={}){let i=r.constraints??_p(e);if(n===`Home`)return i.minWidth;if(n===`End`)return i.maxWidth;let a=Op(e,n,r.largeStep===!0?i.largeKeyboardStep:i.keyboardStep);if(a!==void 0)return xp(e,t+a,i)}function xp(e,t,n=_p(e)){return Number.isFinite(t)?Math.round(Math.min(Math.max(t,n.minWidth),n.maxWidth)):n.defaultWidth}function Sp(e=Ap()){try{let t=e?.getItem(mp);return t==null||t===``?{}:wp(JSON.parse(t))}catch{return{}}}function Cp(e,t=Ap()){if(t!==void 0)try{if(e.navigationPanelWidth===void 0&&e.workspacePanelWidth===void 0){t.removeItem(mp);return}let n={version:1};e.navigationPanelWidth!==void 0&&(n.navigationPanelWidth=xp(`navigation`,e.navigationPanelWidth)),e.workspacePanelWidth!==void 0&&(n.workspacePanelWidth=xp(`workspace`,e.workspacePanelWidth)),t.setItem(mp,JSON.stringify(n))}catch{}}function wp(e){if(!jp(e)||e.version!==1)return{};let t={},n=Tp(e.navigationPanelWidth),r=Tp(e.workspacePanelWidth);return n!==void 0&&(t.navigationPanelWidth=xp(`navigation`,n)),r!==void 0&&(t.workspacePanelWidth=xp(`workspace`,r)),t}function Tp(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function Ep(e,t,n){return t===`navigation`?{...e,navigationPanelWidth:n}:{...e,workspacePanelWidth:n}}function Dp(e,t){return t===`navigation`?e.workspacePanelWidth===void 0?{}:{workspacePanelWidth:e.workspacePanelWidth}:e.navigationPanelWidth===void 0?{}:{navigationPanelWidth:e.navigationPanelWidth}}function Op(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 kp(e){return`${String(Math.round(e))}px`}function Ap(){try{return typeof window>`u`?void 0:window.localStorage}catch{return}}function jp(e){return typeof e==`object`&&!!e}function Mp(){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:Pp(e.get(`tool`)),view:Fp(e.get(`view`))}}function Np(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 Pp(e){return e===`files`?`core:workspace.files`:e===`git`?`core:workspace.git`:Ip(e)?e:void 0}function Fp(e){return e===`chat`?`chat`:e===`files`?`core:workspace.files`:e===`git`?`core:workspace.git`:Ip(e)?e:void 0}function Ip(e){return e!==null&&/^[a-z][a-z0-9.-]*:[a-z][a-z0-9.-]*$/u.test(e)}function Lp(){return zp(new URLSearchParams(window.location.search).get(`settings`))}function Rp(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 zp(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 Bp(e,t){return t===void 0?e:e.map(e=>Hp(e,t))}function Vp(e,t){let n=new Set($l(e,t,{enabledOnly:!0}).filter(e=>e.active).map(e=>e.action.id));return Bp(e,t).map(e=>e.shortcut!==void 0&&!n.has(e.id)?Up(e):e)}function Hp(e,t){if(!Object.hasOwn(t,e.id))return e;let n=t[e.id];return n===void 0?e:n===null?Up(e):{...e,shortcut:n}}function Up(e){let t={...e};return delete t.shortcut,t}function Wp(e,t){let n=t.api??Ji,r=t.pollIntervalMs??1e3,i=t.setTimeout??qp(),a=t.clearTimeout??Jp();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:Gp(s,n,r,i,a)}},listCommandRuns:e=>n.listCommandRuns(e),getCommandRun:e=>n.getCommandRun(e),open:e=>{t.openTerminal(void 0,e)}}}function Gp(e,t,n,r,i){return Kp(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&&Kp(e)){l(e);return}s=r(d,n)}).catch(u)};s=r(d,n)})}function Kp(e){return e.status===`succeeded`||e.status===`failed`}function qp(){return(e,t)=>globalThis.setTimeout(e,t)}function Jp(){return e=>{globalThis.clearTimeout(e)}}function Yp(e,t){return t[e.path]}function Xp(e){if(e?.hasSessionActivity===!0)return`session`;if(e?.hasTerminalActivity===!0)return`terminal`}function Zp(e,t,n){return $p(em(e,t,n))}function Qp(e){return $p(Object.values(e??{}))}function $p(e){if(e.some(e=>e.hasSessionActivity))return`session`;if(e.some(e=>e.hasTerminalActivity))return`terminal`}function em(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()]}function tm(e,t=`活跃`){if(e!==void 0)return g`<span class=${`activity-indicator ${e}`} role="img" aria-label=${t} title=${t}></span>`}function nm(e,t=`活跃`){let n=tm(e,t);if(n!==void 0)return g`<span class="action-activity">${n}</span>`}var rm=0,im=120;function am(e,t={}){if(typeof HTMLElement>`u`||typeof window>`u`||!(e instanceof HTMLElement))return``;let n=e.getBoundingClientRect(),r=t.constrainTo===`viewport`?sm():om(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-rm,f=n.top-c-rm;return[...d<im&&f>d?[`bottom: ${cm(a-n.top+rm)};`,`max-height: ${cm(Math.max(0,f))};`]:[`top: ${cm(n.bottom+rm)};`,`max-height: ${cm(Math.max(0,d))};`],`right: ${cm(Math.max(0,i-u))};`,`max-width: ${cm(Math.max(0,u-o))};`].join(` `)}function om(e){let t=e.getRootNode();return typeof ShadowRoot<`u`&&t instanceof ShadowRoot&&t.host instanceof HTMLElement?t.host.getBoundingClientRect():sm()}function sm(){return{top:0,right:window.innerWidth,bottom:window.innerHeight,left:0}}function cm(e){return`${String(Math.round(e))}px`}var lm=class{constructor(e){this.host=e,this.menuStyle=``,this.onDocumentClick=e=>{e.composedPath().includes(this.host)||this.close()},e.addController(this)}hostConnected(){document.addEventListener(`click`,this.onDocumentClick)}hostDisconnected(){document.removeEventListener(`click`,this.onDocumentClick)}isOpen(e){return this.openId===e}toggle(e,t){if(this.openId===e){this.close();return}this.menuStyle=am(t,{constrainTo:`viewport`}),this.openId=e,this.host.requestUpdate()}close(){this.openId===void 0&&this.menuStyle===``||(this.openId=void 0,this.menuStyle=``,this.host.requestUpdate())}closeIfOpenIdMissing(e){this.openId!==void 0&&!e(this.openId)&&this.close()}closeIf(e){e&&this.close()}closeForEscape(e,t){return e.key!==`Escape`||this.openId!==t?!1:(e.preventDefault(),e.stopPropagation(),this.close(),!0)}},um=[`a[href]`,`button`,`input`,`select`,`textarea`,`summary`,`[role='button']`,`[role='link']`,`[contenteditable='true']`].join(`,`);function dm(e){return e.composedPath().some(e=>fm(e,um))}function fm(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 pm(e,t){dm(e)||t()}function mm(e,t){return dm(e)?!1:e.key===`Enter`||e.key===` `?(e.preventDefault(),t.activate(),!0):e.key===`ArrowUp`?gm(e,()=>{_m(e.currentTarget,-1)}):e.key===`ArrowDown`?gm(e,()=>{_m(e.currentTarget,1)}):e.key===`Home`?gm(e,()=>{vm(e.currentTarget,0)}):e.key===`End`?gm(e,()=>{vm(e.currentTarget,-1)}):e.key===`ArrowLeft`&&t.previousSection!==void 0?gm(e,t.previousSection):e.key===`ArrowRight`&&t.nextSection!==void 0?gm(e,t.nextSection):e.key===`Escape`&&t.cancel!==void 0&&gm(e,t.cancel)}function hm(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 gm(e,t){return e.preventDefault(),e.stopPropagation?.(),t(),!0}function _m(e,t){let n=bm(e),r=Sm(e);if(r===void 0||n.length===0)return;let i=n.indexOf(r);i<0||ym(n,i+t)}function vm(e,t){let n=bm(e);n.length!==0&&ym(n,t<0?n.length-1:t)}function ym(e,t){let n=e[Math.min(Math.max(t,0),e.length-1)];n?.focus(),n?.scrollIntoView({block:`nearest`})}function bm(e){let t=Sm(e)?.getRootNode();return t===void 0||!xm(t)?[]:Array.from(t.querySelectorAll(`.action-row`))}function xm(e){return typeof Document<`u`&&e instanceof Document||typeof DocumentFragment<`u`&&e instanceof DocumentFragment}function Sm(e){if(!(typeof HTMLElement>`u`||!(e instanceof HTMLElement)))return e.closest(`.action-row`)??void 0}var Cm=h`
|
|
370
|
+
:host { display: flex; flex-direction: column; min-height: 0; overflow: hidden; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
|
371
|
+
:host([collapsed]) { flex: 0 0 auto; min-height: auto; overflow: hidden; }
|
|
372
|
+
section { box-sizing: border-box; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding: 10px; }
|
|
373
|
+
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; }
|
|
374
|
+
.list-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
|
|
375
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
|
376
|
+
section > button { display: block; width: 100%; text-align: left; margin: 6px 0; }
|
|
377
|
+
.subheading { margin-top: 14px; }
|
|
378
|
+
.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; }
|
|
379
|
+
.section-toggle span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
380
|
+
.section-title { display: grid; gap: 2px; min-width: 0; }
|
|
381
|
+
.section-toggle .section-selected { display: block; color: var(--pi-text); font-size: 12px; font-weight: 600; line-height: 1.25; text-transform: none; }
|
|
382
|
+
.section-toggle .section-count { flex: 0 0 auto; display: inline; color: var(--pi-muted); font-size: inherit; }
|
|
383
|
+
.section-toggle small { display: inline; color: inherit; font-size: inherit; }
|
|
384
|
+
.action-row { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; margin: 6px 0; cursor: pointer; }
|
|
385
|
+
.action-row:focus-visible { outline: 2px solid var(--pi-accent); outline-offset: 2px; border-radius: 8px; }
|
|
386
|
+
.action-row.selected .action-main, .action-row.selected .action-menu-toggle { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
|
|
387
|
+
.action-row.archived .action-main { color: var(--pi-muted); }
|
|
388
|
+
.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; }
|
|
389
|
+
.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; }
|
|
390
|
+
.action-row:not(.selected):hover .action-main { background: var(--pi-surface-hover); }
|
|
391
|
+
.workspace-row .action-main { border-radius: 8px 0 0 8px; }
|
|
392
|
+
.workspace-primary { min-width: 0; display: flex; align-items: baseline; gap: 6px; }
|
|
393
|
+
.workspace-primary-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
394
|
+
.workspace-status { flex: 0 0 auto; color: var(--pi-warning); font-size: 12px; }
|
|
395
|
+
.workspace-secondary { margin-top: 3px; }
|
|
396
|
+
.workspace-menu-panel { width: max-content; min-width: min(120px, calc(100vw - 16px)); padding: 8px; }
|
|
397
|
+
.workspace-menu-actions { margin: 0 0 8px; padding-bottom: 8px; border-bottom: 1px solid var(--pi-border-muted); }
|
|
398
|
+
.workspace-menu-actions button.danger { color: var(--pi-danger); }
|
|
399
|
+
.workspace-menu-actions button.danger:hover, .workspace-menu-actions button.danger:focus { background: color-mix(in srgb, var(--pi-danger) 14%, transparent); }
|
|
400
|
+
.workspace-menu-details { display: grid; gap: 6px; margin: 0; }
|
|
401
|
+
.workspace-detail-row { display: grid; grid-template-columns: minmax(58px, max-content) minmax(0, 1fr); gap: 8px; align-items: baseline; }
|
|
402
|
+
.workspace-detail-row dt { color: var(--pi-muted); font-size: 12px; white-space: normal; }
|
|
403
|
+
.workspace-detail-row dd { min-width: 0; margin: 0; overflow-wrap: anywhere; white-space: normal; }
|
|
404
|
+
.tree-marker { color: var(--pi-dim); margin-right: 5px; }
|
|
405
|
+
.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; }
|
|
406
|
+
.action-activity { position: absolute; top: 5px; right: 6px; z-index: 1; display: grid; place-items: center; width: 10px; height: 10px; }
|
|
407
|
+
.action-activity .activity-indicator { margin: 0; vertical-align: 0; }
|
|
408
|
+
.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; }
|
|
409
|
+
.activity-indicator.session { border-radius: 50%; background: var(--pi-success); }
|
|
410
|
+
.activity-indicator.terminal { border-radius: 2px; background: var(--pi-accent); }
|
|
411
|
+
/* Client-side sending (upload in flight); distinct from server activity, which propagates to workspace/machine rows. */
|
|
412
|
+
.activity-indicator.sending { border-radius: 50%; background: var(--pi-warning); }
|
|
413
|
+
.action-menu { position: relative; align-self: stretch; }
|
|
414
|
+
.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; }
|
|
415
|
+
.action-menu-toggle:hover { color: var(--pi-text); background: var(--pi-surface-hover); }
|
|
416
|
+
.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; }
|
|
417
|
+
.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); }
|
|
418
|
+
.action-menu-panel button:hover { background: var(--pi-selection-bg); }
|
|
419
|
+
button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
|
|
420
|
+
button:disabled { opacity: .5; cursor: not-allowed; }
|
|
421
|
+
small { display: block; color: var(--pi-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
422
|
+
.workspace-label { min-width: 0; display: inline-flex; align-items: baseline; gap: 5px; max-width: 100%; overflow: hidden; white-space: nowrap; }
|
|
423
|
+
.workspace-label-base, .workspace-label-item, .workspace-label-render { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
424
|
+
.workspace-label-item, .workspace-label-render, .workspace-label-separator { color: var(--pi-muted); }
|
|
425
|
+
.workspace-label-link { color: var(--pi-accent); text-decoration: none; }
|
|
426
|
+
.workspace-label-link:hover, .workspace-label-link:focus { text-decoration: underline; }
|
|
427
|
+
.workspace-detail-row .workspace-label { overflow: visible; white-space: normal; flex-wrap: wrap; }
|
|
428
|
+
.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; }
|
|
429
|
+
@keyframes pulse { 0%, 100% { transform: scale(.75); opacity: .55; } 50% { transform: scale(1.2); opacity: 1; } }
|
|
430
|
+
`,wm=class extends v{constructor(...e){super(...e),this.machines=[],this.statuses={},this.activities={},this.collapsible=!1,this.collapsed=!1,this.menu=new lm(this)}updated(e){e.has(`machines`)&&this.menu.closeIfOpenIdMissing(e=>this.machines.some(t=>t.id===e)),e.has(`collapsed`)&&this.menu.closeIf(this.collapsed)}async focusSelectedOrFirst(){return await this.updateComplete,hm(this.renderRoot,{fallbackSelector:`.section-toggle`})}render(){return g`
|
|
431
|
+
<section>
|
|
432
|
+
<h2>${this.renderHeading()}</h2>
|
|
433
|
+
${this.collapsed?null:g`
|
|
434
|
+
<div class="list-body">
|
|
435
|
+
${this.machines.map(e=>this.renderMachine(e))}
|
|
436
|
+
</div>
|
|
437
|
+
`}
|
|
438
|
+
</section>
|
|
439
|
+
`}renderMachine(e){let t=this.statuses[e.id]?.status??e.status??`unknown`,n=t===`online`?`在线`:t===`offline`?`离线`:t===`error`?`错误`:`未知`,r=Tm(e)&&this.onRemove!==void 0;return g`
|
|
440
|
+
<div
|
|
441
|
+
class=${`action-row machine-row ${this.selected?.id===e.id?`selected`:``} ${r?``:`no-actions`}`}
|
|
442
|
+
tabindex="0"
|
|
443
|
+
title=${e.baseUrl??e.name}
|
|
444
|
+
@click=${t=>{pm(t,()=>this.onSelect?.(e))}}
|
|
445
|
+
@keydown=${t=>{this.handleMachineKeydown(t,e)}}
|
|
446
|
+
>
|
|
447
|
+
<div class="action-main">
|
|
448
|
+
<span class="action-name machine-primary">${this.renderActivity(e)}<span class="machine-primary-label">${e.name}</span></span><small>${e.kind===`local`?`本机 Pi Web`:e.baseUrl??`远程 Pi Web`} · ${n}</small>
|
|
449
|
+
</div>
|
|
450
|
+
${r?this.renderMachineMenu(e):null}
|
|
451
|
+
</div>
|
|
452
|
+
`}renderActivity(e){let t=this.statuses[e.id]?.status??e.status;if(t===`offline`||t===`error`)return;let n=Qp(this.activities[e.id]);return nm(n,n===`terminal`?`机器终端活跃`:`机器活跃`)}renderMachineMenu(e){let t=this.menu.isOpen(e.id),n=Em(e.id);return g`
|
|
453
|
+
<div class="action-menu">
|
|
454
|
+
<button
|
|
455
|
+
class="action-menu-toggle"
|
|
456
|
+
title="机器操作"
|
|
457
|
+
aria-label=${`${e.name} 的操作`}
|
|
458
|
+
aria-expanded=${String(t)}
|
|
459
|
+
aria-controls=${n}
|
|
460
|
+
@click=${t=>{t.stopPropagation(),this.menu.toggle(e.id,t.currentTarget)}}
|
|
461
|
+
>⋯</button>
|
|
462
|
+
${t?g`
|
|
463
|
+
<div class="action-menu-panel machine-menu-panel" id=${n} style=${this.menu.menuStyle} @click=${e=>{e.stopPropagation()}}>
|
|
464
|
+
<button class="danger" title=${`移除 ${e.name}`} @click=${()=>{this.removeMachine(e)}}>移除</button>
|
|
465
|
+
</div>
|
|
466
|
+
`:null}
|
|
467
|
+
</div>
|
|
468
|
+
`}renderHeading(){if(!this.collapsible)return`机器`;let e=this.selected?.name??`未选择机器`,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?`▸`:`▾`} 机器</span>${this.collapsed?g`<small class="section-selected" title=${t}>${e}</small>`:null}</span><small class="section-count">${this.machines.length}</small></button>`}removeMachine(e){this.menu.close(),this.onRemove?.(e)}handleMachineKeydown(e,t){this.menu.closeForEscape(e,t.id)||mm(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=[Cm,h`
|
|
469
|
+
.machine-row.no-actions .action-main { border-radius: 8px; }
|
|
470
|
+
.machine-primary { display: flex; align-items: baseline; gap: 6px; }
|
|
471
|
+
.machine-primary-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
472
|
+
.machine-menu-panel button.danger { color: var(--pi-danger); }
|
|
473
|
+
.machine-menu-panel button.danger:hover, .machine-menu-panel button.danger:focus { background: color-mix(in srgb, var(--pi-danger) 14%, transparent); }
|
|
474
|
+
`]}};z([b({attribute:!1})],wm.prototype,`machines`,void 0),z([b({attribute:!1})],wm.prototype,`selected`,void 0),z([b({attribute:!1})],wm.prototype,`statuses`,void 0),z([b({attribute:!1})],wm.prototype,`activities`,void 0),z([b({type:Boolean,reflect:!0})],wm.prototype,`collapsible`,void 0),z([b({type:Boolean,reflect:!0})],wm.prototype,`collapsed`,void 0),z([b({attribute:!1})],wm.prototype,`onSelect`,void 0),z([b({attribute:!1})],wm.prototype,`onRemove`,void 0),z([b({attribute:!1})],wm.prototype,`onToggleCollapsed`,void 0),z([b({attribute:!1})],wm.prototype,`onFocusNextSection`,void 0),z([b({attribute:!1})],wm.prototype,`onCancelKeyboardNavigation`,void 0),wm=z([y(`machine-list`)],wm);function Tm(e){return e.kind===`remote`}function Em(e){return`machine-menu-${e.replace(/[^a-zA-Z0-9_-]/g,`-`)}`}var Dm=class extends v{constructor(...e){super(...e),this.projects=[],this.activities={},this.workspacesByProjectId={},this.collapsible=!1,this.collapsed=!1,this.menu=new lm(this)}updated(e){e.has(`projects`)&&this.menu.closeIfOpenIdMissing(e=>this.projects.some(t=>t.id===e)),e.has(`collapsed`)&&this.menu.closeIf(this.collapsed)}async focusSelectedOrFirst(){return await this.updateComplete,hm(this.renderRoot,{fallbackSelector:`.section-toggle`})}render(){return g`
|
|
475
|
+
<section>
|
|
476
|
+
<h2>${this.renderHeading()}</h2>
|
|
477
|
+
${this.collapsed?null:g`
|
|
478
|
+
<div class="list-body">
|
|
479
|
+
${this.projects.length===0?g`
|
|
480
|
+
<div class="empty-list" role="status">
|
|
481
|
+
<strong>暂无可访问项目</strong>
|
|
482
|
+
<small>请先在 AI 平台手动创建项目,然后刷新此页面。</small>
|
|
483
|
+
</div>
|
|
484
|
+
`:this.projects.map(e=>g`
|
|
485
|
+
<div
|
|
486
|
+
class=${`action-row ${this.selected?.id===e.id?`selected`:``}`}
|
|
487
|
+
tabindex="0"
|
|
488
|
+
title=${e.path}
|
|
489
|
+
@click=${t=>{pm(t,()=>this.onSelect?.(e))}}
|
|
490
|
+
@keydown=${t=>{this.handleProjectKeydown(t,e)}}
|
|
491
|
+
>
|
|
492
|
+
<div class="action-main">
|
|
493
|
+
<span class="action-name">${e.name}</span><small>${e.path}</small>
|
|
494
|
+
${this.renderActivity(e)}
|
|
495
|
+
</div>
|
|
496
|
+
<div class="action-menu">
|
|
497
|
+
<button class="action-menu-toggle" title="项目操作" aria-label=${`${e.name} 的操作`} @click=${t=>{t.stopPropagation(),this.menu.toggle(e.id,t.currentTarget)}}>⋯</button>
|
|
498
|
+
${this.menu.isOpen(e.id)?g`
|
|
499
|
+
<div class="action-menu-panel" style=${this.menu.menuStyle}>
|
|
500
|
+
<button title="关闭项目" @click=${()=>{this.close(e)}}>关闭</button>
|
|
501
|
+
</div>
|
|
502
|
+
`:null}
|
|
503
|
+
</div>
|
|
504
|
+
</div>
|
|
505
|
+
`)}
|
|
506
|
+
</div>
|
|
507
|
+
`}
|
|
508
|
+
</section>
|
|
509
|
+
`}handleProjectKeydown(e,t){mm(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`项目`;let e=this.selected?.name??`未选择项目`,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?`▸`:`▾`} 项目</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=Zp(e,this.workspacesByProjectId[e.id]??[],this.activities);return nm(t,t===`terminal`?`项目终端活跃`:`项目活跃`)}close(e){this.menu.close(),confirm(`关闭 ${e.name}?\n\n这只会从 PI WEB 中移除它,不会修改项目文件夹。`)&&this.onClose?.(e)}static{this.styles=Cm}};z([b({attribute:!1})],Dm.prototype,`projects`,void 0),z([b({attribute:!1})],Dm.prototype,`selected`,void 0),z([b({attribute:!1})],Dm.prototype,`activities`,void 0),z([b({attribute:!1})],Dm.prototype,`workspacesByProjectId`,void 0),z([b({type:Boolean,reflect:!0})],Dm.prototype,`collapsible`,void 0),z([b({type:Boolean,reflect:!0})],Dm.prototype,`collapsed`,void 0),z([b({attribute:!1})],Dm.prototype,`onSelect`,void 0),z([b({attribute:!1})],Dm.prototype,`onClose`,void 0),z([b({attribute:!1})],Dm.prototype,`onToggleCollapsed`,void 0),z([b({attribute:!1})],Dm.prototype,`onFocusPreviousSection`,void 0),z([b({attribute:!1})],Dm.prototype,`onFocusNextSection`,void 0),z([b({attribute:!1})],Dm.prototype,`onCancelKeyboardNavigation`,void 0),Dm=z([y(`project-list`)],Dm);function Om(e=[]){return e.map((e,t)=>g`${t===0?null:g`<span class="workspace-label-separator">·</span>`}${km(e)}`)}function km(e){if(e.type===`render`)return g`<span class="workspace-label-render">${e.render()}</span>`;if(e.type===`link`&&Am(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 Am(e){let t=e.trim().toLowerCase();return t!==``&&!t.startsWith(`javascript:`)&&!t.startsWith(`data:`)}var B=class extends v{constructor(...e){super(...e),this.workspaces=[],this.collapsible=!1,this.collapsed=!1,this.workspaceLabelItems=()=>[],this.activities={},this.deletingWorkspaceIds=[],this.menu=new lm(this)}updated(e){e.has(`workspaces`)&&this.menu.closeIfOpenIdMissing(e=>this.workspaces.some(t=>t.id===e)),e.has(`collapsed`)&&this.menu.closeIf(this.collapsed),(e.has(`selected`)||e.has(`workspaces`)||e.has(`collapsed`))&&!this.collapsed&&this.scrollSelectedIntoView()}async focusSelectedOrFirst(){return await this.updateComplete,hm(this.renderRoot,{fallbackSelector:`.section-toggle`})}render(){return g`
|
|
510
|
+
<section>
|
|
511
|
+
<h2>${this.renderHeading()}</h2>
|
|
512
|
+
${this.collapsed?null:g`
|
|
513
|
+
<div class="list-body">
|
|
514
|
+
${this.workspaces.map(e=>{let t=jm(e),n=this.workspaceLabelItems(e);return g`
|
|
515
|
+
<div
|
|
516
|
+
class=${`action-row workspace-row ${this.selected?.id===e.id?`selected`:``}`}
|
|
517
|
+
tabindex="0"
|
|
518
|
+
title=${t}
|
|
519
|
+
@click=${t=>{pm(t,()=>this.onSelect?.(e))}}
|
|
520
|
+
@keydown=${t=>{this.handleWorkspaceKeydown(t,e)}}
|
|
521
|
+
>
|
|
522
|
+
<div class="action-main">
|
|
523
|
+
${this.renderWorkspaceMain(t,n,e)}
|
|
524
|
+
</div>
|
|
525
|
+
${this.renderWorkspaceMenu(t,n,e)}
|
|
526
|
+
</div>
|
|
527
|
+
`})}
|
|
528
|
+
</div>
|
|
529
|
+
`}
|
|
530
|
+
</section>
|
|
531
|
+
`}renderHeading(){if(!this.collapsible)return`工作区`;let e=this.selected===void 0?`未选择工作区`:`${this.selected.label}${this.selected.isMain?` · 主工作区`:``} · ${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?`▸`:`▾`} 工作区</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=Xp(Yp(e,this.activities));return nm(t,t===`terminal`?`工作区终端活跃`:`工作区活跃`)}renderWorkspaceMain(e,t,n){return g`
|
|
532
|
+
<span class="workspace-primary">
|
|
533
|
+
<span class="workspace-primary-label">${e}</span>
|
|
534
|
+
${this.isDeleting(n)?g`<span class="workspace-status">正在删除…</span>`:null}
|
|
535
|
+
</span>
|
|
536
|
+
${t.length===0?null:g`
|
|
537
|
+
<small class="workspace-secondary">
|
|
538
|
+
<span class="workspace-label">${Om(t)}</span>
|
|
539
|
+
</small>
|
|
540
|
+
`}
|
|
541
|
+
${this.renderActivity(n)}
|
|
542
|
+
`}renderWorkspaceMenu(e,t,n){let r=this.menu.isOpen(n.id),i=Nm(n.id);return g`
|
|
543
|
+
<div class="action-menu">
|
|
544
|
+
<button
|
|
545
|
+
class="action-menu-toggle"
|
|
546
|
+
title="工作区操作和详情"
|
|
547
|
+
aria-label=${`${e} 的操作和详情`}
|
|
548
|
+
aria-expanded=${String(r)}
|
|
549
|
+
aria-controls=${i}
|
|
550
|
+
@click=${e=>{e.stopPropagation(),this.menu.toggle(n.id,e.currentTarget)}}
|
|
551
|
+
>⋯</button>
|
|
552
|
+
${r?g`
|
|
553
|
+
<div class="action-menu-panel workspace-menu-panel" id=${i} style=${this.menu.menuStyle} @click=${e=>{e.stopPropagation()}}>
|
|
554
|
+
${this.renderWorkspaceActions(n)}
|
|
555
|
+
${this.renderWorkspaceDetails(e,t,n)}
|
|
556
|
+
</div>
|
|
557
|
+
`:null}
|
|
558
|
+
</div>
|
|
559
|
+
`}renderWorkspaceActions(e){if(!Mm(e))return;let t=this.isDeleting(e);return g`
|
|
560
|
+
<div class="workspace-menu-actions">
|
|
561
|
+
<button class="danger" title=${t?`正在删除工作区`:`删除工作区`} ?disabled=${t} @click=${()=>{this.delete(e)}}>${t?`正在删除…`:`删除工作区`}</button>
|
|
562
|
+
</div>
|
|
563
|
+
`}renderWorkspaceDetails(e,t,n){return g`
|
|
564
|
+
<dl class="workspace-menu-details">
|
|
565
|
+
<div class="workspace-detail-row">
|
|
566
|
+
<dt>${n.branch===void 0?`工作区`:`分支`}</dt>
|
|
567
|
+
<dd>${e}</dd>
|
|
568
|
+
</div>
|
|
569
|
+
<div class="workspace-detail-row">
|
|
570
|
+
<dt>路径</dt>
|
|
571
|
+
<dd title=${n.path}>${n.path}</dd>
|
|
572
|
+
</div>
|
|
573
|
+
${t.length===0?null:g`
|
|
574
|
+
<div class="workspace-detail-row">
|
|
575
|
+
<dt>详情</dt>
|
|
576
|
+
<dd><span class="workspace-label">${Om(t)}</span></dd>
|
|
577
|
+
</div>
|
|
578
|
+
`}
|
|
579
|
+
</dl>
|
|
580
|
+
`}delete(e){this.isDeleting(e)||(this.menu.close(),this.onDelete?.(e))}isDeleting(e){return this.deletingWorkspaceIds.includes(e.id)}handleWorkspaceKeydown(e,t){this.menu.closeForEscape(e,t.id)||mm(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=Cm}};z([b({attribute:!1})],B.prototype,`workspaces`,void 0),z([b({attribute:!1})],B.prototype,`selected`,void 0),z([b({type:Boolean,reflect:!0})],B.prototype,`collapsible`,void 0),z([b({type:Boolean,reflect:!0})],B.prototype,`collapsed`,void 0),z([b({attribute:!1})],B.prototype,`workspaceLabelItems`,void 0),z([b({attribute:!1})],B.prototype,`activities`,void 0),z([b({attribute:!1})],B.prototype,`deletingWorkspaceIds`,void 0),z([b({attribute:!1})],B.prototype,`onSelect`,void 0),z([b({attribute:!1})],B.prototype,`onDelete`,void 0),z([b({attribute:!1})],B.prototype,`onToggleCollapsed`,void 0),z([b({attribute:!1})],B.prototype,`onFocusPreviousSection`,void 0),z([b({attribute:!1})],B.prototype,`onFocusNextSection`,void 0),z([b({attribute:!1})],B.prototype,`onCancelKeyboardNavigation`,void 0),B=z([y(`workspace-list`)],B);function jm(e){return`${e.branch??e.label}${e.isMain?` · 主工作区`:``}`}function Mm(e){return e.isGitWorktree&&!e.isMain}function Nm(e){return`workspace-menu-${e.replace(/[^a-zA-Z0-9_-]/g,`-`)}`}function Pm(e){return e.slice(-8)}function Fm(e){return e.name!==void 0&&e.name!==``?e.name:e.firstMessage===``?Pm(e.id):e.firstMessage}var V=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=`请更新并重启此机器上的 Pi-Web 后再删除已归档会话。`,this.cleanupUnavailableMessage=`请更新并重启此机器上的 Pi-Web 后再清理会话。`,this.collapsible=!1,this.collapsed=!1,this.menu=new lm(this),this.archivedExpanded=!1,this.selectionScopes=new Set,this.selectedSessionIds=new Set}updated(e){e.has(`sessions`)&&(this.menu.closeIfOpenIdMissing(e=>this.sessions.some(t=>t.id===e)),this.sessions.some(e=>e.archived===!0)||(this.archivedExpanded=!1),this.pruneSelectedSessionIds()),e.has(`collapsed`)&&this.menu.closeIf(this.collapsed);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,hm(this.renderRoot,{fallbackSelector:`.section-toggle, h2 button:not([disabled])`})}render(){let e=Hm(this.sessions),t=new Set(e.map(e=>e.session.id)),n=e.map(e=>e.session).filter(e=>Rm(e)===`current`),r=Um(this.sessions.filter(e=>e.archived===!0&&!t.has(e.id))),i=Bm(this.sessions);return g`
|
|
581
|
+
<section>
|
|
582
|
+
${this.renderHeading(e.length+r.length,n)}
|
|
583
|
+
${this.collapsed?null:g`
|
|
584
|
+
<div class="list-body">
|
|
585
|
+
${this.renderCurrentSelectionToolbar(n)}
|
|
586
|
+
${this.startingCount>0?this.renderStartingSession():null}
|
|
587
|
+
${e.map(e=>this.renderSession(e,i.get(e.session.id)??0,`current`))}
|
|
588
|
+
${r.length>0?g`
|
|
589
|
+
${this.renderArchivedHeading(r.map(e=>e.session))}
|
|
590
|
+
${this.archivedExpanded?g`
|
|
591
|
+
${this.renderArchivedSelectionToolbar(r.map(e=>e.session))}
|
|
592
|
+
${r.map(e=>this.renderSession(e,i.get(e.session.id)??0,`archived`))}
|
|
593
|
+
`:null}
|
|
594
|
+
`:null}
|
|
595
|
+
</div>
|
|
596
|
+
`}
|
|
597
|
+
</section>
|
|
598
|
+
`}renderHeading(e,t){if(!this.collapsible)return g`
|
|
599
|
+
<h2>
|
|
600
|
+
会话
|
|
601
|
+
${this.renderCurrentSelectionButton(t)}
|
|
602
|
+
${this.renderCleanupButton()}
|
|
603
|
+
${this.renderStartButton()}
|
|
604
|
+
</h2>
|
|
605
|
+
`;let n=this.selected===void 0?`未选择会话`:Fm(this.selected),r=this.selected?.path??n;return g`
|
|
606
|
+
<h2>
|
|
607
|
+
<button class="section-toggle" aria-expanded=${String(!this.collapsed)} @click=${()=>{this.onToggleCollapsed?.()}}><span class="section-title"><span class="section-name">${this.collapsed?`▸`:`▾`} 会话</span>${this.collapsed?g`<small class="section-selected" dir="auto" title=${r}>${n}</small>`:null}</span></button>
|
|
608
|
+
${this.renderCurrentSelectionButton(t)}
|
|
609
|
+
<small class="section-count">${e}</small>
|
|
610
|
+
${this.renderCleanupButton()}
|
|
611
|
+
${this.renderStartButton()}
|
|
612
|
+
</h2>
|
|
613
|
+
`}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?`关闭当前会话选择`:`选择当前会话`} aria-label=${t?`关闭当前会话选择`:`选择当前会话`} 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?`预览会话清理`:this.cleanupUnavailableMessage} @click=${e=>{e.stopPropagation(),this.onCleanup?.()}}>清理</button>`}renderStartButton(){let e=this.startingCount>0?`再启动一个会话`:`启动新会话`;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`
|
|
614
|
+
<div class="pending-session-row starting-session" role="status" aria-live="polite">
|
|
615
|
+
<div class="action-main">
|
|
616
|
+
<span class="action-name"><span class="activity-indicator sending" aria-hidden="true"></span>${e?`Starting ${String(this.startingCount)} sessions…`:`Starting session…`}</span>
|
|
617
|
+
<small>Waiting for ${e?`new sessions`:`the new session`} to be created</small>
|
|
618
|
+
</div>
|
|
619
|
+
</div>
|
|
620
|
+
`}renderArchivedHeading(e){let t=this.selectionScopes.has(`archived`);return g`
|
|
621
|
+
<h2 class="subheading">
|
|
622
|
+
<button class="section-toggle" aria-expanded=${String(this.archivedExpanded)} @click=${()=>{this.toggleArchived()}}><span>${this.archivedExpanded?`▾`:`▸`} 已归档</span></button>
|
|
623
|
+
${this.archivedExpanded?g`<button class="bulk-select-entry ${t?`selected`:``}" title=${t?`关闭已归档会话选择`:`选择已归档会话`} aria-label=${t?`关闭已归档会话选择`:`选择已归档会话`} aria-expanded=${String(t)} aria-pressed=${String(t)} @click=${()=>{this.toggleSelection(`archived`,e)}}>☑</button>`:null}
|
|
624
|
+
<small class="section-count">${e.length}</small>
|
|
625
|
+
</h2>
|
|
626
|
+
`}renderCurrentSelectionToolbar(e){if(e.length===0||!this.selectionScopes.has(`current`))return null;let t=this.selectedSessions(`current`),n=t.filter(e=>Ic(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`
|
|
627
|
+
<div class="bulk-row selecting">
|
|
628
|
+
<button ?disabled=${e.length===0} @click=${()=>{this.toggleVisibleSelection(e,!r)}}>${r?`清除可见`:`选择可见`}</button>
|
|
629
|
+
<small>${t.length} 已选${i===t.length?null:g` · ${i} 可见`}</small>
|
|
630
|
+
<button ?disabled=${n.length===0} @click=${()=>{this.archiveSelectedCurrent()}}>归档所选</button>
|
|
631
|
+
<button @click=${()=>{this.clearSelection(`current`)}}>清除</button>
|
|
632
|
+
<button @click=${()=>{this.closeSelection(`current`)}}>完成</button>
|
|
633
|
+
</div>
|
|
634
|
+
`}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`
|
|
635
|
+
<div class="bulk-row selecting">
|
|
636
|
+
<button ?disabled=${e.length===0} @click=${()=>{this.toggleVisibleSelection(e,!n)}}>${n?`清除可见`:`选择可见`}</button>
|
|
637
|
+
<small>${t.length} 已选${r===t.length?null:g` · ${r} 可见`}</small>
|
|
638
|
+
<button class="danger" title=${this.canDeleteArchived?`永久删除所选已归档会话`:this.archivedDeleteUnavailableMessage} ?disabled=${t.length===0||!this.canDeleteArchived} @click=${()=>{this.confirmDeleteSelectedArchived()}}>删除所选</button>
|
|
639
|
+
<button @click=${()=>{this.clearSelection(`archived`)}}>清除</button>
|
|
640
|
+
<button @click=${()=>{this.closeSelection(`archived`)}}>完成</button>
|
|
641
|
+
${this.canDeleteArchived?null:g`<small class="capability-hint">${this.archivedDeleteUnavailableMessage}</small>`}
|
|
642
|
+
</div>
|
|
643
|
+
`}renderSession(e,t,n){let{session:r}=e,i=Math.min(e.depth,2),a=Rm(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=Ic(r,l,d),p=Lm(r,l,d),m=Lc(r,l,d),ee=f&&this.canReload;return g`
|
|
644
|
+
<div
|
|
645
|
+
class="action-row ${this.selected?.id===r.id?`selected`:``} ${c?`bulk-selected`:``} ${r.archived===!0?`archived`:``} ${o?`selecting`:``}"
|
|
646
|
+
style=${`--depth:${String(i)}`}
|
|
647
|
+
tabindex="0"
|
|
648
|
+
title=${r.path}
|
|
649
|
+
@click=${e=>{pm(e,()=>{this.activateSessionRow(r,n)})}}
|
|
650
|
+
@keydown=${e=>{this.handleSessionKeydown(e,r,n)}}
|
|
651
|
+
>
|
|
652
|
+
<div class="action-main ${o?`selecting`:``}">
|
|
653
|
+
${s?g`<input class="session-checkbox" type="checkbox" aria-label=${`选择 ${Fm(r)}`} .checked=${c} @click=${e=>{e.stopPropagation()}} @change=${()=>{this.toggleSelected(r.id)}}>`:null}
|
|
654
|
+
<span class="action-name" dir="auto">${e.depth>0?g`<span class="tree-marker">↳</span>`:null}${Fm(r)}${e.depth>2?g` <span class="badge">深度 ${e.depth}</span>`:null}${e.hasMissingParent?g` <span class="badge">父会话不可用</span>`:null}</span><small>${this.renderSessionMetaPrefix(r,l,u)}${String(r.messageCount)} 条消息</small>
|
|
655
|
+
${this.renderActivity(r)}
|
|
656
|
+
</div>
|
|
657
|
+
<div class="action-menu">
|
|
658
|
+
<button class="action-menu-toggle" title="会话操作" @click=${e=>{e.stopPropagation(),this.menu.toggle(r.id,e.currentTarget)}}>⋯</button>
|
|
659
|
+
${this.menu.isOpen(r.id)?g`
|
|
660
|
+
<div class="action-menu-panel" style=${this.menu.menuStyle}>
|
|
661
|
+
${r.archived===!0?g`
|
|
662
|
+
<button title="恢复会话" @click=${()=>{this.menu.close(),this.onRestore?.(r)}}>恢复</button>
|
|
663
|
+
<button class="danger" title=${this.canDeleteArchived?`永久删除已归档会话`:this.archivedDeleteUnavailableMessage} ?disabled=${!this.canDeleteArchived} @click=${()=>{this.menu.close(),this.confirmDeleteArchived(r)}}>删除已归档会话</button>
|
|
664
|
+
`:m?g`<button title="删除临时新会话" @click=${()=>{this.menu.close(),this.onDelete?.(r)}}>删除</button>`:g`
|
|
665
|
+
${p?g`<button title="重命名会话" @click=${()=>{this.renameSession(r)}}>重命名</button>`:null}
|
|
666
|
+
${f?g`
|
|
667
|
+
<button title="归档会话" @click=${()=>{this.menu.close(),this.onArchive?.(r)}}>归档</button>
|
|
668
|
+
${t>0?g`<button title="归档此会话及其后代会话" @click=${()=>{this.menu.close(),this.confirmArchiveWithDescendants(r,t)}}>连同后代归档(${t})</button>`:null}
|
|
669
|
+
`:null}
|
|
670
|
+
${r.parentSessionPath===void 0?null:g`<button title="从父会话分离" @click=${()=>{this.menu.close(),this.onDetachParent?.(r)}}>从父会话分离</button>`}
|
|
671
|
+
${ee?g`<button title=${Aa(this.statuses[r.id],this.activities[r.id])?`当前会话活动结束后才能从磁盘重新加载`:`从磁盘重新加载会话,不刷新 Pi 运行时资源`} ?disabled=${Aa(this.statuses[r.id],this.activities[r.id])} @click=${()=>{this.menu.close(),this.onReload?.(r)}}>从磁盘重新加载</button>`:null}
|
|
672
|
+
`}
|
|
673
|
+
</div>
|
|
674
|
+
`:null}
|
|
675
|
+
</div>
|
|
676
|
+
</div>
|
|
677
|
+
`}handleSessionKeydown(e,t,n){mm(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)&&Rm(e)===t){this.toggleSelected(e.id);return}this.onSelect?.(e)}confirmArchiveWithDescendants(e,t){confirm(`归档“${Fm(e)}”及其 ${String(t)} 个后代会话?`)&&this.onArchiveWithDescendants?.(e)}renameSession(e){this.menu.close();let t=Im(e);t!==void 0&&this.onRename?.(e,t)}confirmDeleteArchived(e){this.canDeleteArchived&&confirm(`永久删除已归档会话“${Fm(e)}”?此操作无法撤销。`)&&this.onDeleteArchived?.(e)}confirmDeleteSelectedArchived(){if(!this.canDeleteArchived)return;let e=this.selectedSessions(`archived`);e.length!==0&&confirm(`永久删除 ${String(e.length)} 个所选已归档会话?此操作无法撤销。`)&&(this.selectedSessionIds=zm(this.selectedSessionIds,e.map(e=>e.id)),this.onDeleteArchivedMany?.(e))}archiveSelectedCurrent(){let e=this.selectedSessions(`current`).filter(e=>Ic(e,this.statuses[e.id],this.sessionPersistenceOptions()));this.selectedSessionIds=zm(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=>Rm(t)===e).map(e=>e.id);this.selectedSessionIds=zm(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)&&Rm(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`)}toggleArchived(){this.archivedExpanded=!this.archivedExpanded,this.archivedExpanded||(this.menu.close(),this.selectionScopes.has(`archived`)&&this.closeSelection(`archived`),this.onArchivedCollapsed?.())}scrollSelectedIntoView(){this.renderRoot.querySelector(`.action-row.selected`)?.scrollIntoView({block:`nearest`})}renderSessionMetaPrefix(e,t,n){return Lc(e,t,this.sessionPersistenceOptions())?n?.phase===`active`?`创建中 · `:n?.phase===`error`?`错误 · `:`新建 · `:e.archived===!0?`只读 · `:``}sessionPersistenceOptions(){return{authoritative:this.authoritativeSessionPersistence}}renderActivity(e){let t=Vm(e,this.statuses[e.id],this.activities[e.id],this.sending[e.id]===!0);return nm(t,t===`sending`?`正在发送消息`:`会话活跃`)}static{this.styles=[Cm,h`
|
|
678
|
+
h2 { min-height: 30px; }
|
|
679
|
+
h2 > .section-count { flex: 0 0 auto; display: inline; color: var(--pi-muted); font-size: inherit; }
|
|
680
|
+
.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; }
|
|
681
|
+
.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; }
|
|
682
|
+
.cleanup-entry { flex: 0 0 auto; padding: 5px 7px; font-size: 12px; text-transform: none; }
|
|
683
|
+
.bulk-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 6px; }
|
|
684
|
+
.bulk-row button { padding: 5px 7px; font-size: 12px; }
|
|
685
|
+
.bulk-row small { display: inline; min-width: 0; color: var(--pi-muted); }
|
|
686
|
+
.action-name, .section-selected { text-align: start; unicode-bidi: plaintext; }
|
|
687
|
+
.bulk-row .capability-hint { flex: 1 0 100%; color: var(--pi-warning); }
|
|
688
|
+
.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); }
|
|
689
|
+
button.danger, .action-menu-panel button.danger { color: var(--pi-danger); }
|
|
690
|
+
button.danger:hover, .action-menu-panel button.danger:hover { background: color-mix(in srgb, var(--pi-danger) 14%, transparent); }
|
|
691
|
+
.action-row.bulk-selected .action-main { border-color: var(--pi-accent); box-shadow: inset 3px 0 0 var(--pi-accent); }
|
|
692
|
+
.pending-session-row { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); margin: 6px 0; cursor: default; }
|
|
693
|
+
.pending-session-row.starting-session .action-main { border-radius: 8px; border-style: dashed; color: var(--pi-muted); }
|
|
694
|
+
.pending-session-row.starting-session .action-name { display: flex; align-items: center; gap: 6px; max-height: none; -webkit-line-clamp: 1; }
|
|
695
|
+
.pending-session-row.starting-session .activity-indicator { flex: 0 0 auto; margin: 0; }
|
|
696
|
+
.action-main.selecting { padding-left: calc(32px + var(--depth, 0) * 16px); }
|
|
697
|
+
.session-checkbox { position: absolute; top: 9px; left: calc(8px + var(--depth, 0) * 16px); z-index: 2; margin: 0; }
|
|
698
|
+
`]}};z([b({attribute:!1})],V.prototype,`sessions`,void 0),z([b({attribute:!1})],V.prototype,`statuses`,void 0),z([b({attribute:!1})],V.prototype,`activities`,void 0),z([b({attribute:!1})],V.prototype,`sending`,void 0),z([b({attribute:!1})],V.prototype,`selected`,void 0),z([b({type:Number})],V.prototype,`startingCount`,void 0),z([b({type:Boolean})],V.prototype,`canStart`,void 0),z([b({type:Boolean})],V.prototype,`canDeleteArchived`,void 0),z([b({type:Boolean})],V.prototype,`canReload`,void 0),z([b({type:Boolean})],V.prototype,`canCleanup`,void 0),z([b({type:Boolean})],V.prototype,`authoritativeSessionPersistence`,void 0),z([b({type:String})],V.prototype,`archivedDeleteUnavailableMessage`,void 0),z([b({type:String})],V.prototype,`cleanupUnavailableMessage`,void 0),z([b({type:Boolean,reflect:!0})],V.prototype,`collapsible`,void 0),z([b({type:Boolean,reflect:!0})],V.prototype,`collapsed`,void 0),z([b({attribute:!1})],V.prototype,`onSelect`,void 0),z([b({attribute:!1})],V.prototype,`onStart`,void 0),z([b({attribute:!1})],V.prototype,`onToggleCollapsed`,void 0),z([b({attribute:!1})],V.prototype,`onArchivedCollapsed`,void 0),z([b({attribute:!1})],V.prototype,`onFocusPreviousSection`,void 0),z([b({attribute:!1})],V.prototype,`onFocusNextSection`,void 0),z([b({attribute:!1})],V.prototype,`onCancelKeyboardNavigation`,void 0),z([b({attribute:!1})],V.prototype,`onArchive`,void 0),z([b({attribute:!1})],V.prototype,`onArchiveWithDescendants`,void 0),z([b({attribute:!1})],V.prototype,`onArchiveMany`,void 0),z([b({attribute:!1})],V.prototype,`onRestore`,void 0),z([b({attribute:!1})],V.prototype,`onDelete`,void 0),z([b({attribute:!1})],V.prototype,`onDeleteArchived`,void 0),z([b({attribute:!1})],V.prototype,`onDeleteArchivedMany`,void 0),z([b({attribute:!1})],V.prototype,`onRename`,void 0),z([b({attribute:!1})],V.prototype,`onDetachParent`,void 0),z([b({attribute:!1})],V.prototype,`onReload`,void 0),z([b({attribute:!1})],V.prototype,`onCleanup`,void 0),z([x()],V.prototype,`archivedExpanded`,void 0),z([x()],V.prototype,`selectionScopes`,void 0),z([x()],V.prototype,`selectedSessionIds`,void 0),V=z([y(`session-list`)],V);function Im(e){let t=globalThis.prompt(`重命名会话`,Fm(e))?.trim();return t===void 0||t===``?void 0:t}function Lm(e,t,n){return Ic(e,t,n)}function Rm(e){return e.archived===!0?`archived`:`current`}function zm(e,t){let n=new Set(t);return new Set([...e].filter(e=>!n.has(e)))}function Bm(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 Vm(e,t,n,r){if(!(Co(e)||e.archived===!0))return r?`sending`:Aa(t,n)?`session`:void 0}function Hm(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 Um(e.filter(e=>n.has(e.id)))}function Um(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 H=class extends v{constructor(...e){super(...e),this.canCleanup=!0,this.unavailableMessage=`请更新并重启此机器上的 Pi-Web 后再清理会话。`,this.loading=!1,this.running=!1,this.error=``,this.draft={...wu},this.formError=``}willUpdate(e){e.has(`preview`)&&(this.selectedProjectCwds=this.preview?.projects.map(e=>e.cwd))}render(){let e=Tu(this.draft),t=this.selectedPreview(),n=Du({canCleanup:this.canCleanup,draft:this.draft,preview:t,previewRequest:this.previewRequest,loading:this.loading,running:this.running}),r=n?`运行清理`:t!==void 0&&!Ou(t)?`至少选择一个项目才能运行清理`:`运行清理前请先预览`;return g`
|
|
699
|
+
<div class="backdrop" @mousedown=${()=>{this.onClose?.()}}>
|
|
700
|
+
<section role="dialog" aria-modal="true" aria-label="清理会话" @mousedown=${e=>{e.stopPropagation()}} @keydown=${e=>{this.handleKeyDown(e)}}>
|
|
701
|
+
<header>
|
|
702
|
+
<div>
|
|
703
|
+
<span class="eyebrow">会话</span>
|
|
704
|
+
<h1>清理会话</h1>
|
|
705
|
+
</div>
|
|
706
|
+
<button class="close-button" title="关闭清理" aria-label="关闭清理" @click=${()=>{this.onClose?.()}}>×</button>
|
|
707
|
+
</header>
|
|
708
|
+
<div class="body">
|
|
709
|
+
<p class="intro">归档空闲会话或永久删除旧的已归档会话前,先预览此机器的手动清理结果。</p>
|
|
710
|
+
${this.canCleanup?this.renderForm(e.ok?``:e.error):this.renderUnavailable()}
|
|
711
|
+
${this.renderMessage()}
|
|
712
|
+
${this.preview===void 0?null:this.renderPreview(this.preview)}
|
|
713
|
+
${this.result===void 0?null:this.renderResult(this.result)}
|
|
714
|
+
</div>
|
|
715
|
+
<footer>
|
|
716
|
+
<button @click=${()=>{this.onClose?.()}}>${this.result===void 0?`取消`:`关闭`}</button>
|
|
717
|
+
<button ?disabled=${!this.canCleanup||this.loading||this.running} @click=${()=>{this.previewCleanup()}}>${this.loading?`正在预览…`:`预览`}</button>
|
|
718
|
+
<button class="danger" ?disabled=${!n} title=${r} @click=${()=>{this.runCleanup()}}>${this.running?`正在运行…`:`运行清理`}</button>
|
|
719
|
+
</footer>
|
|
720
|
+
</section>
|
|
721
|
+
</div>
|
|
722
|
+
`}renderForm(e){let t=this.loading||this.running,n=Tu(this.draft),r=this.preview!==void 0&&n.ok&&Eu(n.request)!==Eu(this.previewRequest)&&Ou(this.preview);return g`
|
|
723
|
+
<fieldset ?disabled=${t}>
|
|
724
|
+
<label class="toggle-row">
|
|
725
|
+
<input type="checkbox" .checked=${this.draft.archiveIdleEnabled} @change=${e=>{this.updateDraft({archiveIdleEnabled:Wm(e)})}}>
|
|
726
|
+
<span>归档空闲超过</span>
|
|
727
|
+
<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:Gm(e)})}}>
|
|
728
|
+
<span>天的未归档会话</span>
|
|
729
|
+
</label>
|
|
730
|
+
<label class="toggle-row delete-row">
|
|
731
|
+
<input type="checkbox" .checked=${this.draft.deleteArchivedEnabled} @change=${e=>{this.updateDraft({deleteArchivedEnabled:Wm(e)})}}>
|
|
732
|
+
<span>删除已归档超过</span>
|
|
733
|
+
<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:Gm(e)})}}>
|
|
734
|
+
<span>天的已归档会话</span>
|
|
735
|
+
</label>
|
|
736
|
+
</fieldset>
|
|
737
|
+
<p class="warning"><strong>删除是永久操作。</strong>清理只会删除已经归档的会话。</p>
|
|
738
|
+
${e===``?null:g`<div class="dialog-error" role="alert">${e}</div>`}
|
|
739
|
+
${r?g`<div class="hint" role="status">阈值已更改。运行清理前请重新预览。</div>`:null}
|
|
740
|
+
`}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=Au(e,t);return g`
|
|
741
|
+
<section class="preview" aria-label="清理预览">
|
|
742
|
+
<h2>预览</h2>
|
|
743
|
+
${e.projects.length===0?g`<p class="empty">没有会话匹配这些阈值。</p>`:g`
|
|
744
|
+
${this.renderSelectionControls(e,t)}
|
|
745
|
+
<div class="table-scroll" tabindex="0" aria-label="清理项目表">
|
|
746
|
+
<table>
|
|
747
|
+
<thead>
|
|
748
|
+
<tr><th>清理</th><th>项目/工作区路径</th><th>归档</th><th>删除已归档</th></tr>
|
|
749
|
+
</thead>
|
|
750
|
+
<tbody>
|
|
751
|
+
${e.projects.map(e=>this.renderProjectRow(e,n.has(e.cwd)))}
|
|
752
|
+
</tbody>
|
|
753
|
+
<tfoot>
|
|
754
|
+
<tr><th colspan="2">已选合计</th><td>${r.totals.archiveCount}</td><td>${r.totals.deleteCount}</td></tr>
|
|
755
|
+
</tfoot>
|
|
756
|
+
</table>
|
|
757
|
+
</div>
|
|
758
|
+
`}
|
|
759
|
+
${e.skippedBusySessionIds===void 0||e.skippedBusySessionIds.length===0?null:g`<p class="hint">已跳过 ${e.skippedBusySessionIds.length} 个忙碌会话。</p>`}
|
|
760
|
+
</section>
|
|
761
|
+
`}renderSelectionControls(e,t){let n=this.loading||this.running;return g`
|
|
762
|
+
<div class="selection-controls" role="group" aria-label="项目选择">
|
|
763
|
+
<span>已选择 ${t.length} / ${e.projects.length} 个项目</span>
|
|
764
|
+
<button ?disabled=${n||t.length===e.projects.length} @click=${()=>{this.selectAllProjects()}}>全选</button>
|
|
765
|
+
<button ?disabled=${n||t.length===0} @click=${()=>{this.deselectAllProjects()}}>取消全选</button>
|
|
766
|
+
</div>
|
|
767
|
+
${t.length===0?g`<p class="hint" role="status">至少选择一个项目才能运行清理。</p>`:null}
|
|
768
|
+
`}renderProjectRow(e,t){return g`
|
|
769
|
+
<tr class=${t?``:`unselected`}>
|
|
770
|
+
<td class="select-cell"><input type="checkbox" aria-label=${`清理 ${e.cwd}`} .checked=${t} ?disabled=${this.running} @change=${t=>{this.setProjectSelected(e.cwd,Wm(t))}}></td>
|
|
771
|
+
<th title=${e.cwd} dir="auto">${e.cwd}</th>
|
|
772
|
+
<td>${e.archiveCount}</td>
|
|
773
|
+
<td>${e.deleteCount}</td>
|
|
774
|
+
</tr>
|
|
775
|
+
`}renderResult(e){return g`
|
|
776
|
+
<section class="result" aria-label="清理结果">
|
|
777
|
+
<h2>清理完成</h2>
|
|
778
|
+
<p>已归档 ${e.archivedSessionIds.length} 个会话;已永久删除 ${e.deletedSessionIds.length} 个已归档会话。</p>
|
|
779
|
+
</section>
|
|
780
|
+
`}updateDraft(e){this.draft={...this.draft,...e},this.formError=``}selectedPreview(){return this.preview===void 0?void 0:Au(this.preview,this.selectedProjectCwdsForPreview())}selectedProjectCwdsForPreview(){return this.preview===void 0?[]:ku(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=Tu(this.draft);if(!e.ok){this.formError=e.error;return}this.formError=``,this.onPreview?.(e.request)}runCleanup(){let e=Tu(this.draft);if(!e.ok){this.formError=e.error;return}let t=this.selectedPreview(),n=this.selectedProjectCwdsForPreview();if(!Du({canCleanup:this.canCleanup,draft:this.draft,preview:t,previewRequest:this.previewRequest})){this.formError=t!==void 0&&!Ou(t)?`至少选择一个项目才能运行清理。`:`运行清理前请先预览。`;return}t===void 0||!ju(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`
|
|
781
|
+
:host { position: fixed; inset: 0; z-index: 30; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
|
782
|
+
.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; }
|
|
783
|
+
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; }
|
|
784
|
+
header, footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--pi-border); }
|
|
785
|
+
footer { border-top: 1px solid var(--pi-border); border-bottom: 0; justify-content: end; }
|
|
786
|
+
.body { min-height: 0; overflow: auto; display: grid; gap: 14px; padding: 16px; }
|
|
787
|
+
.eyebrow { display: block; color: var(--pi-muted); font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
|
|
788
|
+
h1, h2, p { margin: 0; }
|
|
789
|
+
h1 { font-size: 20px; line-height: 1.2; }
|
|
790
|
+
h2 { font-size: 15px; }
|
|
791
|
+
.intro, .hint, .empty { color: var(--pi-muted); }
|
|
792
|
+
fieldset { margin: 0; padding: 0; border: 0; display: grid; gap: 10px; }
|
|
793
|
+
.toggle-row { display: grid; grid-template-columns: auto minmax(0, max-content) 88px auto; align-items: center; gap: 8px; color: var(--pi-text); }
|
|
794
|
+
input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--pi-accent); }
|
|
795
|
+
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); }
|
|
796
|
+
input.days:disabled { opacity: .55; }
|
|
797
|
+
.warning, .unavailable, .dialog-error, .result { border: 1px solid var(--pi-border); border-radius: 10px; padding: 10px 12px; }
|
|
798
|
+
.warning { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); color: var(--pi-text); }
|
|
799
|
+
.unavailable { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); color: var(--pi-warning); }
|
|
800
|
+
.dialog-error { border-color: var(--pi-danger); background: color-mix(in srgb, var(--pi-danger) 10%, var(--pi-bg)); color: var(--pi-danger); }
|
|
801
|
+
.result { border-color: var(--pi-success-border); background: var(--pi-success-bg); }
|
|
802
|
+
.preview { display: grid; gap: 10px; min-width: 0; }
|
|
803
|
+
.selection-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
|
804
|
+
.selection-controls span { color: var(--pi-muted); }
|
|
805
|
+
.selection-controls button { padding: 5px 7px; font-size: 12px; }
|
|
806
|
+
.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; }
|
|
807
|
+
table { width: 100%; min-width: 620px; border-collapse: collapse; }
|
|
808
|
+
th, td { border-bottom: 1px solid var(--pi-border-muted); padding: 8px 10px; text-align: right; }
|
|
809
|
+
thead th:first-child, td.select-cell { width: 72px; text-align: center; }
|
|
810
|
+
th:nth-child(2), td:nth-child(2) { text-align: left; }
|
|
811
|
+
tbody tr.unselected { opacity: .58; }
|
|
812
|
+
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; }
|
|
813
|
+
tfoot th, tfoot td { border-bottom: 0; font-weight: 700; }
|
|
814
|
+
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; }
|
|
815
|
+
button:disabled { opacity: .5; cursor: not-allowed; }
|
|
816
|
+
button.danger { color: var(--pi-danger); }
|
|
817
|
+
button.danger:not(:disabled):hover { background: color-mix(in srgb, var(--pi-danger) 14%, transparent); }
|
|
818
|
+
.close-button { width: 34px; height: 34px; display: grid; place-items: center; border: 0; background: transparent; color: var(--pi-muted); padding: 0; font-size: 24px; }
|
|
819
|
+
.close-button:hover, .close-button:focus { color: var(--pi-text); background: var(--pi-surface-hover); }
|
|
820
|
+
|
|
821
|
+
@media (max-width: 680px) {
|
|
822
|
+
.backdrop { padding: 0; place-items: stretch; }
|
|
823
|
+
section[role="dialog"] { width: 100%; height: 100dvh; max-height: none; border: 0; border-radius: 0; }
|
|
824
|
+
.toggle-row { grid-template-columns: auto minmax(0, 1fr); }
|
|
825
|
+
.toggle-row input.days { grid-column: 2; }
|
|
826
|
+
.toggle-row span:last-child { grid-column: 2; }
|
|
827
|
+
table { min-width: 560px; }
|
|
828
|
+
thead th:first-child, td.select-cell { width: 58px; }
|
|
829
|
+
}
|
|
830
|
+
`}};z([b({type:Boolean})],H.prototype,`canCleanup`,void 0),z([b({type:String})],H.prototype,`unavailableMessage`,void 0),z([b({attribute:!1})],H.prototype,`preview`,void 0),z([b({attribute:!1})],H.prototype,`previewRequest`,void 0),z([b({attribute:!1})],H.prototype,`result`,void 0),z([b({type:Boolean})],H.prototype,`loading`,void 0),z([b({type:Boolean})],H.prototype,`running`,void 0),z([b({type:String})],H.prototype,`error`,void 0),z([b({attribute:!1})],H.prototype,`onPreview`,void 0),z([b({attribute:!1})],H.prototype,`onRun`,void 0),z([b({attribute:!1})],H.prototype,`onClose`,void 0),z([x()],H.prototype,`draft`,void 0),z([x()],H.prototype,`formError`,void 0),z([x()],H.prototype,`selectedProjectCwds`,void 0),H=z([y(`session-cleanup-dialog`)],H);function Wm(e){return e.target instanceof HTMLInputElement&&e.target.checked}function Gm(e){return e.target instanceof HTMLInputElement?e.target.value:``}var Km={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},qm=e=>(...t)=>({_$litDirective$:e,values:t}),Jm=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,Xm=e=>e,Zm=()=>document.createComment(``),Qm=(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(Zm(),i),r.insertBefore(Zm(),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=Xm(e).nextSibling;Xm(r).insertBefore(e,i),e=t}}}return n},$m=(e,t,n=e)=>(e._$AI(t,n),e),eh={},th=(e,t=eh)=>e._$AH=t,nh=e=>e._$AH,rh=e=>{e._$AR(),e._$AA.remove()},ih=(e,t,n)=>{let r=new Map;for(let i=t;i<=n;i++)r.set(e[i],i);return r},ah=qm(class extends Jm{constructor(e){if(super(e),e.type!==Km.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=nh(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]=$m(i[d],a[p]),d++,p++;else if(s[f]===o[m])c[m]=$m(i[f],a[m]),f--,m--;else if(s[d]===o[m])c[m]=$m(i[d],a[m]),Qm(e,c[m+1],i[d]),d++,m--;else if(s[f]===o[p])c[p]=$m(i[f],a[p]),Qm(e,i[d],i[f]),f--,p++;else if(l===void 0&&(l=ih(o,p,m),u=ih(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=Qm(e,i[d]);$m(t,a[p]),c[p]=t}else c[p]=$m(n,a[p]),Qm(e,i[d],n),i[t]=null;p++}else rh(i[f]),f--;else rh(i[d]),d++;for(;p<=m;){let t=Qm(e,c[m+1]);$m(t,a[p]),c[p++]=t}for(;d<=f;){let e=i[d++];e!==null&&rh(e)}return this.ut=o,th(e,c),Ye}}),oh=`pi-web:chat-groups:`,sh={read(e){try{if(typeof localStorage>`u`)return;let t=localStorage.getItem(lh(e));return t===null||t===``?void 0:uh(JSON.parse(t))}catch{return}},write(e,t){try{if(typeof localStorage>`u`)return;localStorage.setItem(lh(e),JSON.stringify(t))}catch{}}},ch=class{constructor(e=sh){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&&fh(i,this.openGroupKeys)&&fh(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 lh(e){return`${oh}${e}`}function uh(e){if(Array.isArray(e))return{open:dh(e),closedDefaultOpen:[]};if(ph(e))return{open:Array.isArray(e.open)?dh(e.open):[],closedDefaultOpen:Array.isArray(e.closedDefaultOpen)?dh(e.closedDefaultOpen):[]}}function dh(e){return e.filter(e=>typeof e==`string`)}function fh(e,t){if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0}function ph(e){return typeof e==`object`&&!!e}function mh(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=>yh(e,t)),s=e.parts.filter(t=>!yh(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(_h(t)){let e=vh(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 hh(e){if(e.every(e=>e.source===`compaction`))return`${String(e.length)} 条历史压缩摘要`;if(e.every(e=>e.source===`branch_summary`))return`${String(e.length)} 条分支摘要`;let t=e.reduce((e,t)=>(e[t.role]=(e[t.role]??0)+1,e),{}),n=Object.entries(t).map(([e,t])=>`${String(t)} ${gh(e)}`).join(` · `);return`${String(e.length)} 个事件${n===``?``:` · ${n}`}`}function gh(e){return e===`user`?`用户`:e===`assistant`?`助手`:e===`system`?`系统`:e===`tool`?`工具`:e===`toolResult`?`工具结果`:e===`bash`?`Shell`:e===`skill`?`技能`:e}function _h(e){return e.role===`tool`&&e.parts.length>0&&e.parts.every(e=>e.type===`image`)}function vh(e){for(let t of e)if((t.type===`toolCall`||t.type===`toolExecution`||t.type===`toolResult`)&&t.toolName!==``)return t.toolName}function yh(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 bh(e,t=xh()){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 xh(){let e=e=>wh(e),t=Ch();return t===void 0?{isSecureContext:Sh(),fallbackWriteText:e}:{isSecureContext:Sh(),writeText:t,fallbackWriteText:e}}function Sh(){return typeof window<`u`&&window.isSecureContext}function Ch(){if(!(typeof navigator>`u`||!(`clipboard`in navigator)))return navigator.clipboard.writeText.bind(navigator.clipboard)}function wh(e){if(typeof document>`u`)return!1;let t=document.activeElement,n=document.getSelection(),r=n===null?[]:Th(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(),Eh(n,r),Dh(t)}}function Th(e){let t=[];for(let n=0;n<e.rangeCount;n+=1)t.push(e.getRangeAt(n));return t}function Eh(e,t){if(e!==null)try{e.removeAllRanges();for(let n of t)e.addRange(n)}catch{}}function Dh(e){if(!(typeof HTMLElement>`u`||!(e instanceof HTMLElement)))try{e.focus({preventScroll:!0})}catch{e.focus()}}function Oh(e,t){let n=Ah(Nh(e,t)),r={distanceFromBottom:e.scrollHeight-e.scrollTop};return n===void 0?r:{...r,markerId:n.id,markerOffset:n.offset}}function kh(e,t,n){if(n!==void 0&&t.markerOffset!==void 0){let r=n.getBoundingClientRect().top-e.getBoundingClientRect().top;e.scrollTop+=jh(r,t.markerOffset);return}e.scrollTop=Mh(e.scrollHeight,t.distanceFromBottom)}function Ah(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 jh(e,t){return e-t}function Mh(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 Ph=600,Fh=1;function Ih(e){return!e.hasMore||e.loadingMore||!e.canRequest||e.clientHeight<=0?!1:Lh(e)||Rh(e)}function Lh(e){return e.scrollTop<(e.topThreshold??Math.max(Ph,e.clientHeight))}function Rh(e){return e.scrollHeight<=e.clientHeight+Fh}var zh=`pi-web:chat-scroll:`,Bh=180,Vh=48,Hh=2,Uh={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)}},Wh={setTimeout(e,t){return window.setTimeout(e,t)},clearTimeout(e){window.clearTimeout(e)}},Gh=class{constructor(e=Uh,t=Wh){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=Bh){this.clearScheduledSave(),this.saveTimer=this.scheduler.setTimeout(()=>{this.saveTimer=void 0,t(e)},n)}savePosition(e,t,n,r=Hh){if(e===``||t===void 0||!Jh(t))return`skipped`;try{if(Xh(t,r))return this.storage.setItem(Kh(e),JSON.stringify({mode:`bottom`})),`saved`;let i=Qh(t,n);if(i===void 0)return`skipped`;let a=Zh(t,i);return this.storage.setItem(Kh(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||!Jh(t))return{status:`skipped`};let i=eg(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(Kh(e));if(t===null||t===``)return;let n=JSON.parse(t);return qh(n)?n:void 0}catch{return}}scrollToBottom(e){return e===void 0||!Jh(e)?{status:`skipped`}:(e.scrollTop=e.scrollHeight,{status:`bottom`})}};function Kh(e){return`${zh}${e}`}function qh(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 Jh(e){return e.clientHeight>0&&e.scrollHeight>0}function Yh(e){return e.scrollHeight-e.scrollTop-e.clientHeight}function Xh(e,t=Vh){return Yh(e)<t}function Zh(e,t){let n=e.getBoundingClientRect().top;return{mode:`anchor`,anchorId:tg(t)??``,offset:t.getBoundingClientRect().top-n}}function Qh(e,t){let n=e.getBoundingClientRect(),r,i=-1/0,a,o=1/0;for(let e of t){if(tg(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 $h(e,t){let n=e.getBoundingClientRect();return t.find(e=>{let t=e.getBoundingClientRect();return t.bottom>=n.top&&t.top<=n.bottom})}function eg(e,t){return e.find(e=>tg(e)===t)}function tg(e){return e.dataset.scrollAnchorId!==void 0&&e.dataset.scrollAnchorId!==``?e.dataset.scrollAnchorId:void 0}var ng=h`
|
|
831
|
+
:host { position: relative; z-index: 0; display: flex; flex: 1 1 0; flex-direction: column; min-height: 0; max-height: 100%; overflow: hidden; contain: size layout; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
|
832
|
+
.chat-wrap { position: relative; flex: 1 1 0; min-height: 0; max-height: 100%; overflow: hidden; }
|
|
833
|
+
.chat { position: absolute; inset: 0; min-height: 0; overflow: auto; overflow-anchor: none; padding: 26px 16px 64px; box-sizing: border-box; }
|
|
834
|
+
.scroll-marker { display: block; height: 0; overflow: hidden; pointer-events: none; }
|
|
835
|
+
.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); }
|
|
836
|
+
.activity-dock.active { border-color: var(--pi-success-border); color: var(--pi-success); background: var(--pi-success-bg-overlay); }
|
|
837
|
+
.activity-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
838
|
+
.dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; opacity: .45; flex: 0 0 auto; }
|
|
839
|
+
.activity-dock.active .dot { animation: pulse 1s ease-in-out infinite; opacity: 1; }
|
|
840
|
+
.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; }
|
|
841
|
+
.msg.assistant { background: var(--pi-surface); }
|
|
842
|
+
.msg.user { border-color: var(--pi-accent-border); background: var(--pi-selection-bg); }
|
|
843
|
+
.msg.tool { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); color: var(--pi-warning); }
|
|
844
|
+
.msg.tool-execution-shell { padding: 0; border: 0; background: transparent; color: var(--pi-text); }
|
|
845
|
+
.msg.system { color: var(--pi-danger); }
|
|
846
|
+
.msg.bash { border-color: var(--pi-success); background: var(--pi-success-bg); }
|
|
847
|
+
.msg.skill { border-color: var(--pi-purple-border); background: var(--pi-purple-surface); }
|
|
848
|
+
.msg.event-group { padding: 0; border-color: var(--pi-border); background: var(--pi-bg); color: var(--pi-muted); }
|
|
849
|
+
.msg.event-group.live { border-color: var(--pi-success-border); background: var(--pi-success-bg); }
|
|
850
|
+
.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); }
|
|
851
|
+
.msg.event-group.live > summary { border-bottom-color: var(--pi-success-border); background: var(--pi-success-bg); color: var(--pi-success); }
|
|
852
|
+
.msg.event-group > summary .label { margin: 0; }
|
|
853
|
+
.group-body { padding: 0 12px 12px; }
|
|
854
|
+
.chat-image { margin: 0; }
|
|
855
|
+
.chat-image img { display: block; max-width: min(100%, 420px); max-height: 320px; object-fit: contain; border: 1px solid var(--pi-border-muted); border-radius: 8px; background: var(--pi-bg); }
|
|
856
|
+
.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; }
|
|
857
|
+
.group-msg.tool { color: var(--pi-warning); }
|
|
858
|
+
.group-msg.tool-execution-shell { color: var(--pi-text); }
|
|
859
|
+
.group-msg.system { color: var(--pi-danger); }
|
|
860
|
+
.group-msg.bash { color: var(--pi-success); }
|
|
861
|
+
.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; }
|
|
862
|
+
.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; }
|
|
863
|
+
.history-load-button:hover, .history-load-button:focus { border-color: var(--pi-accent); color: var(--pi-text-bright); }
|
|
864
|
+
.history-load-button:disabled { cursor: default; opacity: .55; }
|
|
865
|
+
.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; }
|
|
866
|
+
.queued-header { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
|
|
867
|
+
.queued-header strong { color: var(--pi-warning); }
|
|
868
|
+
.queued-header small { color: var(--pi-muted); }
|
|
869
|
+
.queued-message { display: grid; gap: 4px; padding-top: 8px; border-top: 1px solid var(--pi-border); }
|
|
870
|
+
.queued-message:first-of-type { padding-top: 0; border-top: 0; }
|
|
871
|
+
.queued-kind { color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
|
|
872
|
+
.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; }
|
|
873
|
+
.session-activity.compacting { border-color: var(--pi-purple-border); background: var(--pi-purple-surface); }
|
|
874
|
+
.session-activity.receiving { border-color: var(--pi-success-border); background: var(--pi-success-bg); }
|
|
875
|
+
.session-activity strong { color: var(--pi-purple); }
|
|
876
|
+
.session-activity.receiving strong { color: var(--pi-success); }
|
|
877
|
+
.session-activity span, .session-activity small { color: var(--pi-muted); }
|
|
878
|
+
.history-boundary small { color: var(--pi-dim); }
|
|
879
|
+
.msg-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 22px; margin-bottom: 8px; }
|
|
880
|
+
.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); }
|
|
881
|
+
.msg.user > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-accent-border) 35%, transparent); background: var(--pi-selection-bg); }
|
|
882
|
+
.msg.assistant > .msg-header .label { color: var(--pi-text-secondary); }
|
|
883
|
+
.msg.user > .msg-header .label { color: var(--pi-accent); }
|
|
884
|
+
.msg.tool > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-warning-border) 35%, transparent); background: var(--pi-warning-surface); }
|
|
885
|
+
.msg.bash > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-success) 35%, transparent); background: var(--pi-success-bg); }
|
|
886
|
+
.msg.skill > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-purple-border) 35%, transparent); background: var(--pi-purple-surface); }
|
|
887
|
+
.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); }
|
|
888
|
+
.msg-header-trailing { min-width: 0; display: inline-flex; align-items: baseline; justify-content: flex-end; gap: 8px; }
|
|
889
|
+
.msg-actions { display: inline-flex; gap: 6px; opacity: 0; transition: opacity .12s ease; }
|
|
890
|
+
.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; }
|
|
891
|
+
.msg-action:hover, .msg-action:focus { color: var(--pi-text); border-color: var(--pi-accent); }
|
|
892
|
+
.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; }
|
|
893
|
+
.label { display: block; color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
|
|
894
|
+
.msg-header .label { margin: 0; }
|
|
895
|
+
.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, max-width .12s ease; cursor: pointer; user-select: text; -webkit-user-select: text; }
|
|
896
|
+
.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; }
|
|
897
|
+
.msg-meta:focus { outline: 1px solid var(--pi-border); outline-offset: 3px; border-radius: 4px; }
|
|
898
|
+
@media (hover: none) {
|
|
899
|
+
.msg-actions { opacity: 1; }
|
|
900
|
+
.msg-meta { opacity: .75; max-width: 26px; }
|
|
901
|
+
.msg-meta::before { content: "ⓘ"; font-size: 13px; }
|
|
902
|
+
.msg-meta:focus, .msg-meta.expanded { opacity: 1; max-width: 75%; }
|
|
903
|
+
.msg-meta:focus::before, .msg-meta.expanded::before { content: ""; }
|
|
904
|
+
}
|
|
905
|
+
formatted-text.part { display: block; }
|
|
906
|
+
.part { max-width: 100%; min-width: 0; box-sizing: border-box; overflow: visible; }
|
|
907
|
+
.part + .part { margin-top: 10px; }
|
|
908
|
+
.tool-line { color: var(--pi-warning); }
|
|
909
|
+
.summary { color: var(--pi-muted); margin-left: 6px; }
|
|
910
|
+
.part:is(details) { border-top: 1px solid var(--pi-border); padding-top: 8px; }
|
|
911
|
+
.part > formatted-text { display: block; max-width: 100%; min-width: 0; overflow: visible; }
|
|
912
|
+
.skill-invocation, .skill-read { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); padding: 8px 10px; }
|
|
913
|
+
.skill-invocation > summary, .skill-read > strong { color: var(--pi-purple); }
|
|
914
|
+
.skill-invocation > small, .skill-read > small { display: block; margin: 6px 0 0; color: var(--pi-muted); }
|
|
915
|
+
summary { cursor: pointer; color: var(--pi-muted); }
|
|
916
|
+
pre { margin: 6px 0 0; white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; }
|
|
917
|
+
.shell-output { color: var(--pi-text); font: 13px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; line-height: 1.45; }
|
|
918
|
+
@keyframes pulse { 0%, 100% { transform: scale(.75); opacity: .55; } 50% { transform: scale(1.2); opacity: 1; } }
|
|
919
|
+
`,rg=class extends v{constructor(...e){super(...e),this.positionPercent=0,this.loadedPercent=100}render(){let e=ig(this.positionPercent),t=ig(this.loadedPercent),n=`消息位置:约在会话 ${String(Math.round(e))}% 处。已加载 ${String(Math.round(t))}% 的消息。`;return g`
|
|
920
|
+
<div
|
|
921
|
+
class="meter"
|
|
922
|
+
style=${`--position:${e.toFixed(2)}%;`}
|
|
923
|
+
role="meter"
|
|
924
|
+
aria-label=${n}
|
|
925
|
+
aria-valuemin="0"
|
|
926
|
+
aria-valuemax="100"
|
|
927
|
+
aria-valuenow=${String(Math.round(e))}
|
|
928
|
+
title=${n}
|
|
929
|
+
>
|
|
930
|
+
<div class="track" aria-hidden="true">
|
|
931
|
+
<div class="progress"></div>
|
|
932
|
+
<div class="marker"></div>
|
|
933
|
+
</div>
|
|
934
|
+
</div>
|
|
935
|
+
`}static{this.styles=h`
|
|
936
|
+
:host { position: absolute; top: -4px; left: 16px; right: 16px; z-index: 6; display: block; height: 12px; opacity: .58; transition: opacity .15s ease; }
|
|
937
|
+
:host(:hover), :host(:focus-within) { opacity: .92; }
|
|
938
|
+
.meter { height: 100%; }
|
|
939
|
+
.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); }
|
|
940
|
+
.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)); }
|
|
941
|
+
.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%); }
|
|
942
|
+
`}};z([b({type:Number})],rg.prototype,`positionPercent`,void 0),z([b({type:Number})],rg.prototype,`loadedPercent`,void 0),rg=z([y(`conversation-meter`)],rg);function ig(e){return Number.isFinite(e)?Math.min(100,Math.max(0,e)):0}var ag=class extends Jm{constructor(e){if(super(e),this.it=_,e.type!==Km.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:[]}}};ag.directiveName=`unsafeHTML`,ag.resultType=1;var og=qm(ag);function sg(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var cg=sg();function lg(e){cg=e}var ug={exec:()=>null};function dg(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 U(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(W.caret,`$1`),n=n.replace(e,i),r},getRegex:()=>new RegExp(n,t)};return r}var fg=((e=``)=>{try{return!!RegExp(`(?<=1)(?<!1)`+e)}catch{return!1}})(),W={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:dg(e=>RegExp(`^ {0,${e}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`)),hrRegex:dg(e=>RegExp(`^ {0,${e}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)),fencesBeginRegex:dg(e=>RegExp(`^ {0,${e}}(?:\`\`\`|~~~)`)),headingBeginRegex:dg(e=>RegExp(`^ {0,${e}}#`)),htmlBeginRegex:dg(e=>RegExp(`^ {0,${e}}<(?:[a-z].*>|!--)`,`i`)),blockquoteBeginRegex:dg(e=>RegExp(`^ {0,${e}}>`))},pg=/^(?:[ \t]*(?:\n|$))+/,mg=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,hg=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,gg=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,_g=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,vg=/ {0,3}(?:[*+-]|\d{1,9}[.)])/,yg=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,bg=U(yg).replace(/bull/g,vg).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(),xg=U(yg).replace(/bull/g,vg).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(),Sg=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,Cg=/^[^\n]+/,wg=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,Tg=U(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace(`label`,wg).replace(`title`,/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),Eg=U(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g,vg).getRegex(),Dg=`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`,Og=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,kg=U(`^ {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`,Og).replace(`tag`,Dg).replace(`attribute`,/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Ag=e=>U(Sg).replace(`hr`,gg).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`,Dg).getRegex(),jg=Ag(/ {0,3}(?:[*+-]|1[.)])[ \t]+[^ \t\n]/),Mg=Ag(/ {0,3}(?:[*+-]|\d{1,9}[.)])[ \t]+[^ \t\n]/),Ng={blockquote:U(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace(`paragraph`,Mg).getRegex(),code:mg,def:Tg,fences:hg,heading:_g,hr:gg,html:kg,lheading:bg,list:Eg,newline:pg,paragraph:jg,table:ug,text:Cg},Pg=U(`^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)`).replace(`hr`,gg).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`,Dg).getRegex(),Fg={...Ng,lheading:xg,table:Pg,paragraph:U(Sg).replace(`hr`,gg).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`|lheading`,``).replace(`table`,Pg).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`,Dg).getRegex()},Ig={...Ng,html:U(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace(`comment`,Og).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:ug,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:U(Sg).replace(`hr`,gg).replace(`heading`,` *#{1,6} *[^
|
|
943
|
+
]`).replace(`lheading`,bg).replace(`|table`,``).replace(`blockquote`,` {0,3}>`).replace(`|fences`,``).replace(`|list`,``).replace(`|html`,``).replace(`|tag`,``).getRegex()},Lg=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,Rg=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,zg=/^( {2,}|\\)\n(?!\s*$)/,Bg=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,Vg=/[\p{P}\p{S}]/u,Hg=/[\s\p{P}\p{S}]/u,Ug=/[^\s\p{P}\p{S}]/u,Wg=U(/^((?![*_])punctSpace)/,`u`).replace(/punctSpace/g,Hg).getRegex(),Gg=/(?!~)[\p{P}\p{S}]/u,Kg=/(?!~)[\s\p{P}\p{S}]/u,qg=/(?:[^\s\p{P}\p{S}]|~)/u,Jg=U(/link|precode-code|html/,`g`).replace(`link`,/\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace(`precode-`,fg?"(?<!`)()":"(^^|[^`])").replace(`code`,/(?<b>`+)[^`]+\k<b>(?!`)/).replace(`html`,/<(?! )[^<>]*?>/).getRegex(),Yg=/^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/,Xg=U(Yg,`u`).replace(/punct/g,Vg).getRegex(),Zg=U(Yg,`u`).replace(/punct/g,Gg).getRegex(),Qg=`^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)`,$g=U(Qg,`gu`).replace(/notPunctSpace/g,Ug).replace(/punctSpace/g,Hg).replace(/punct/g,Vg).getRegex(),e_=U(Qg,`gu`).replace(/notPunctSpace/g,qg).replace(/punctSpace/g,Kg).replace(/punct/g,Gg).getRegex(),t_=U(`^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)`,`gu`).replace(/notPunctSpace/g,Ug).replace(/punctSpace/g,Hg).replace(/punct/g,Vg).getRegex(),n_=U(/^~~?(?:((?!~)punct)|[^\s~])/,`u`).replace(/punct/g,Vg).getRegex(),r_=U(`^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)`,`gu`).replace(/notPunctSpace/g,Ug).replace(/punctSpace/g,Hg).replace(/punct/g,Vg).getRegex(),i_=U(/\\(punct)/,`gu`).replace(/punct/g,Vg).getRegex(),a_=U(/^<(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(),o_=U(Og).replace(`(?:-->|$)`,`-->`).getRegex(),s_=U(`^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`,o_).replace(`attribute`,/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),c_=/(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/,l_=U(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace(`label`,c_).replace(`href`,/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]+|(?=\))/).replace(`title`,/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),u_=U(/^!?\[(label)\]\[(ref)\]/).replace(`label`,c_).replace(`ref`,wg).getRegex(),d_=U(/^!?\[(ref)\](?:\[\])?/).replace(`ref`,wg).getRegex(),f_=U(`reflink|nolink(?!\\()`,`g`).replace(`reflink`,u_).replace(`nolink`,d_).getRegex(),p_=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,m_={_backpedal:ug,anyPunctuation:i_,autolink:a_,blockSkip:Jg,br:zg,code:Rg,del:ug,delLDelim:ug,delRDelim:ug,emStrongLDelim:Xg,emStrongRDelimAst:$g,emStrongRDelimUnd:t_,escape:Lg,link:l_,nolink:d_,punctuation:Wg,reflink:u_,reflinkSearch:f_,tag:s_,text:Bg,url:ug},h_={...m_,link:U(/^!?\[(label)\]\((.*?)\)/).replace(`label`,c_).getRegex(),reflink:U(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace(`label`,c_).getRegex()},g_={...m_,emStrongRDelimAst:e_,emStrongLDelim:Zg,delLDelim:n_,delRDelim:r_,url:U(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace(`protocol`,p_).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:U(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace(`protocol`,p_).getRegex()},__={...g_,br:U(zg).replace(`{2,}`,`*`).getRegex(),text:U(g_.text).replace(`\\b_`,`\\b_| {2,}\\n`).replace(/\{2,\}/g,`*`).getRegex()},v_={normal:Ng,gfm:Fg,pedantic:Ig},y_={normal:m_,gfm:g_,breaks:__,pedantic:h_},b_={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`},x_=e=>b_[e];function S_(e,t){if(t){if(W.escapeTest.test(e))return e.replace(W.escapeReplace,x_)}else if(W.escapeTestNoEncode.test(e))return e.replace(W.escapeReplaceNoEncode,x_);return e}function C_(e){try{e=encodeURI(e).replace(W.percentDecode,`%`)}catch{return null}return e}function w_(e,t){let n=e.replace(W.findPipe,(e,t,n)=>{let r=!1,i=t;for(;--i>=0&&n[i]===`\\`;)r=!r;return r?`|`:` |`}).split(W.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(W.slashPipe,`|`);return n}function T_(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 E_(e){let t=e.split(`
|
|
944
|
+
`),n=t.length-1;for(;n>=0&&W.blankLine.test(t[n]);)n--;return t.length-n<=2?e:t.slice(0,n+1).join(`
|
|
945
|
+
`)}function D_(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 O_(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 k_(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 A_(e,t,n){let r=e.match(n.other.indentCodeCompensation);if(r===null)return t;let i=r[1];return t.split(`
|
|
946
|
+
`).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(`
|
|
947
|
+
`)}var j_=class{options;rules;lexer;constructor(e){this.options=e||cg}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]:E_(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=A_(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=T_(e,`#`);(this.options.pedantic||!t||this.rules.other.endingSpaceChar.test(t))&&(e=t.trim())}return{type:`heading`,raw:T_(t[0],`
|
|
948
|
+
`),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:T_(t[0],`
|
|
949
|
+
`)}}blockquote(e){let t=this.rules.block.blockquote.exec(e);if(t){let e=T_(t[0],`
|
|
950
|
+
`).split(`
|
|
951
|
+
`),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(`
|
|
952
|
+
`),c=s.replace(this.rules.other.blockquoteSetextReplace,`
|
|
953
|
+
$1`).replace(this.rules.other.blockquoteSetextReplace2,``);n=n?`${n}
|
|
954
|
+
${s}`:s,r=r?`${r}
|
|
955
|
+
${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+`
|
|
956
|
+
`+e.join(`
|
|
957
|
+
`),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+`
|
|
958
|
+
`+e.join(`
|
|
959
|
+
`),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(`
|
|
960
|
+
`);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=O_(t[2].split(`
|
|
961
|
+
`,1)[0],t[1].length),l=e.split(`
|
|
962
|
+
`,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+`
|
|
963
|
+
`,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(`
|
|
964
|
+
`,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+=`
|
|
965
|
+
`+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+=`
|
|
966
|
+
`+l}u=!l.trim(),r+=p+`
|
|
967
|
+
`,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=E_(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:T_(t[0],`
|
|
968
|
+
`),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=w_(t[1]),r=t[2].replace(this.rules.other.tableAlignChars,``).split(`|`),i=t[3]?.trim()?t[3].replace(this.rules.other.tableRowBlankLine,``).split(`
|
|
969
|
+
`):[],a={type:`table`,raw:T_(t[0],`
|
|
970
|
+
`),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(w_(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:T_(t[0],`
|
|
971
|
+
`),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)===`
|
|
972
|
+
`?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=T_(e.slice(0,-1),`\\`);if((e.length-t.length)%2==0)return}else{let e=D_(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)),k_(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 k_(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}}}},M_=class e{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||cg,this.options.tokenizer=this.options.tokenizer||new j_,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:W,block:v_.normal,inline:y_.normal};this.options.pedantic?(t.block=v_.pedantic,t.inline=y_.pedantic):this.options.gfm&&(t.block=v_.gfm,this.options.breaks?t.inline=y_.breaks:t.inline=y_.gfm),this.tokenizer.rules=t}static get rules(){return{block:v_,inline:y_}}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(W.carriageReturn,`
|
|
973
|
+
`),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(W.tabCharGlobal,` `).replace(W.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+=`
|
|
974
|
+
`: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(`
|
|
975
|
+
`)?``:`
|
|
976
|
+
`)+i.raw,n.text+=`
|
|
977
|
+
`+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(`
|
|
978
|
+
`)?``:`
|
|
979
|
+
`)+i.raw,n.text+=`
|
|
980
|
+
`+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(`
|
|
981
|
+
`)?``:`
|
|
982
|
+
`)+i.raw,r.text+=`
|
|
983
|
+
`+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(`
|
|
984
|
+
`)?``:`
|
|
985
|
+
`)+i.raw,n.text+=`
|
|
986
|
+
`+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)}},N_=class{options;parser;constructor(e){this.options=e||cg}space(e){return``}code({text:e,lang:t,escaped:n}){let r=(t||``).match(W.notSpaceStart)?.[0],i=e.replace(W.endingNewline,``)+`
|
|
987
|
+
`;return r?`<pre><code class="language-`+S_(r)+`">`+(n?i:S_(i,!0))+`</code></pre>
|
|
988
|
+
`:`<pre><code>`+(n?i:S_(i,!0))+`</code></pre>
|
|
989
|
+
`}blockquote({tokens:e}){return`<blockquote>
|
|
990
|
+
${this.parser.parse(e)}</blockquote>
|
|
991
|
+
`}html({text:e}){return e}def(e){return``}heading({tokens:e,depth:t}){return`<h${t}>${this.parser.parseInline(e)}</h${t}>
|
|
992
|
+
`}hr(e){return`<hr>
|
|
993
|
+
`}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+`>
|
|
994
|
+
`+r+`</`+i+`>
|
|
995
|
+
`}listitem(e){return`<li>${this.parser.parse(e.tokens)}</li>
|
|
996
|
+
`}checkbox({checked:e}){return`<input `+(e?`checked="" `:``)+`disabled="" type="checkbox"> `}paragraph({tokens:e}){return`<p>${this.parser.parseInline(e)}</p>
|
|
997
|
+
`}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>
|
|
998
|
+
<thead>
|
|
999
|
+
`+t+`</thead>
|
|
1000
|
+
`+r+`</table>
|
|
1001
|
+
`}tablerow({text:e}){return`<tr>
|
|
1002
|
+
${e}</tr>
|
|
1003
|
+
`}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?`th`:`td`;return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`</${n}>
|
|
1004
|
+
`}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>${S_(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=C_(e);if(i===null)return r;e=i;let a=`<a href="`+e+`"`;return t&&(a+=` title="`+S_(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=C_(e);if(i===null)return S_(n);e=i;let a=`<img src="${e}" alt="${S_(n)}"`;return t&&(a+=` title="${S_(t)}"`),a+=`>`,a}text(e){return`tokens`in e&&e.tokens?this.parser.parseInline(e.tokens):`escaped`in e&&e.escaped?e.text:S_(e.text)}},P_=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}},F_=class e{options;renderer;textRenderer;constructor(e){this.options=e||cg,this.options.renderer=this.options.renderer||new N_,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new P_}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||cg}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?M_.lex:M_.lexInline}provideParser(e=this.block){return e?F_.parse:F_.parseInline}},L_=new class{defaults=sg();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=F_;Renderer=N_;TextRenderer=P_;Lexer=M_;Tokenizer=j_;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 N_(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 j_(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 M_.lex(e,t??this.defaults)}parser(e,t){return F_.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?M_.lex:M_.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?F_.parse:F_.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?M_.lex:M_.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?F_.parse:F_.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+=`
|
|
1005
|
+
Please report this to https://github.com/markedjs/marked.`,e){let e=`<p>An error occurred:</p><pre>`+S_(n.message+``,!0)+`</pre>`;return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}};function G(e,t){return L_.parse(e,t)}G.options=G.setOptions=function(e){return L_.setOptions(e),G.defaults=L_.defaults,lg(G.defaults),G},G.getDefaults=sg,G.defaults=cg,G.use=function(...e){return L_.use(...e),G.defaults=L_.defaults,lg(G.defaults),G},G.walkTokens=function(e,t){return L_.walkTokens(e,t)},G.parseInline=L_.parseInline,G.Parser=F_,G.parser=F_.parse,G.Renderer=N_,G.TextRenderer=P_,G.Lexer=M_,G.lexer=M_.lex,G.Tokenizer=j_,G.Hooks=I_,G.parse=G,G.options,G.setOptions,G.use,G.walkTokens,G.parseInline,F_.parse,M_.lex;var R_=new G.Renderer;R_.html=({text:e})=>H_(e);var z_=300,B_=new Map;function V_(e){let t=B_.get(e);if(t!==void 0)return t;let n=U_(G.parse(e,{async:!1,breaks:!0,gfm:!0,renderer:R_}));if(B_.set(e,n),B_.size>z_){let e=B_.keys().next().value;e!==void 0&&B_.delete(e)}return n}function H_(e){return e.replaceAll(`&`,`&`).replaceAll(`<`,`<`).replaceAll(`>`,`>`)}function U_(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`)&&!W_(t.value)&&e.removeAttribute(t.name)}e.tagName===`A`&&(e.setAttribute(`target`,`_blank`),e.setAttribute(`rel`,`noreferrer noopener`))}),t.innerHTML}function W_(e){if(e.startsWith(`#`)||e.startsWith(`/`))return!0;try{return[`http:`,`https:`,`mailto:`].includes(new URL(e).protocol)}catch{return!1}}var G_=h`
|
|
1006
|
+
:host { display: block; }
|
|
1007
|
+
.formatted { white-space: normal; overflow-wrap: anywhere; line-height: 1.45; }
|
|
1008
|
+
p, ul, ol, pre, blockquote, table, .code-block-wrapper { margin: 0 0 10px; }
|
|
1009
|
+
:is(p, ul, ol, pre, blockquote, table, .code-block-wrapper):last-child { margin-bottom: 0; }
|
|
1010
|
+
ul, ol { padding-left: 22px; }
|
|
1011
|
+
li + li { margin-top: 3px; }
|
|
1012
|
+
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; }
|
|
1013
|
+
.code-block-wrapper { position: relative; }
|
|
1014
|
+
.code-block-wrapper pre { margin: 0; padding-right: 40px; }
|
|
1015
|
+
pre { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); padding: 10px; overflow-x: auto; overflow-y: hidden; }
|
|
1016
|
+
pre code { border: 0; padding: 0; background: transparent; }
|
|
1017
|
+
.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; }
|
|
1018
|
+
.code-copy-button:hover, .code-copy-button:focus { color: var(--pi-text); border-color: var(--pi-accent); }
|
|
1019
|
+
blockquote { border-left: 3px solid var(--pi-border); padding-left: 10px; color: var(--pi-muted); }
|
|
1020
|
+
a { color: var(--pi-accent); }
|
|
1021
|
+
h1, h2, h3, h4 { margin: 14px 0 8px; line-height: 1.2; }
|
|
1022
|
+
h1:first-child, h2:first-child, h3:first-child, h4:first-child { margin-top: 0; }
|
|
1023
|
+
h1 { font-size: 20px; }
|
|
1024
|
+
h2 { font-size: 17px; }
|
|
1025
|
+
h3 { font-size: 15px; }
|
|
1026
|
+
h4 { font-size: 14px; }
|
|
1027
|
+
table { border-collapse: collapse; display: block; overflow-x: auto; overflow-y: hidden; }
|
|
1028
|
+
th, td { border: 1px solid var(--pi-border); padding: 4px 8px; }
|
|
1029
|
+
th { background: var(--pi-surface); }
|
|
1030
|
+
`,K_=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}>${og(V_(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=`复制代码块`,n.setAttribute(`aria-label`,`复制代码块`);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 bh(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`?`已复制代码块`:t===`failed`?`复制代码块失败`:`复制代码块`;e.title=r,e.setAttribute(`aria-label`,r)}static{this.styles=G_}};z([b()],K_.prototype,`text`,void 0),K_=z([y(`formatted-text`)],K_);var q_=180,J_=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=X_(e.args),n=Q_(e.details),r=e.preview,i=n??r?.diff,a=i===void 0?void 0:$_(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=Y_(e,t);return g`
|
|
1031
|
+
<section class=${`tool-card ${e.status}`}>
|
|
1032
|
+
<div class="tool-header">
|
|
1033
|
+
<div class="tool-title">
|
|
1034
|
+
<span class="status-icon" aria-hidden="true">${rv(e.status)}</span>
|
|
1035
|
+
<strong>${e.toolName}</strong>
|
|
1036
|
+
${this.renderHeaderTarget(l)}
|
|
1037
|
+
</div>
|
|
1038
|
+
<div class="tool-meta">
|
|
1039
|
+
${Z_(e)===void 0?null:g`<span>${Z_(e)}</span>`}
|
|
1040
|
+
${a===void 0?null:g`<span class="diff-stats"><b class="added">+${a.added}</b><span>/</span><b class="removed">-${a.removed}</b></span>`}
|
|
1041
|
+
<span class="status-label">${iv(e.status)}</span>
|
|
1042
|
+
</div>
|
|
1043
|
+
</div>
|
|
1044
|
+
|
|
1045
|
+
${o?g`<p class="notice">实际应用的 diff 与预览不同。</p>`:null}
|
|
1046
|
+
${s===void 0||s===``?null:g`<pre class="error-text">${s}</pre>`}
|
|
1047
|
+
${i===void 0?this.renderTextBody(c,e.status===`error`,l):this.renderDiffBody(i,n===void 0?`预览 diff`:`已应用 diff`,l)}
|
|
1048
|
+
</section>
|
|
1049
|
+
`}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`
|
|
1050
|
+
<div class="detail-target">
|
|
1051
|
+
<span class="detail-label">${e.label}</span>
|
|
1052
|
+
<pre class="detail-target-value">${e.text}</pre>
|
|
1053
|
+
</div>
|
|
1054
|
+
`}renderTextBody(e,t,n){return(e===void 0||e===``)&&n===void 0?null:g`
|
|
1055
|
+
<details class="text-body" ?open=${t}>
|
|
1056
|
+
<summary>详情</summary>
|
|
1057
|
+
${this.renderExpandedTarget(n)}
|
|
1058
|
+
${e===void 0||e===``?null:g`
|
|
1059
|
+
<div class="detail-result">
|
|
1060
|
+
<span class="detail-label">结果</span>
|
|
1061
|
+
<pre>${e}</pre>
|
|
1062
|
+
</div>
|
|
1063
|
+
`}
|
|
1064
|
+
</details>
|
|
1065
|
+
`}renderDiffBody(e,t,n){let r=e.split(`
|
|
1066
|
+
`),i=!this.showFullDiff&&r.length>q_,a=i?r.slice(0,q_):r;return g`
|
|
1067
|
+
<details class="diff-details" ?open=${this.diffOpen} @toggle=${e=>{this.onDiffToggle(e)}}>
|
|
1068
|
+
<summary>
|
|
1069
|
+
<span>${t}</span>
|
|
1070
|
+
<small>${String(r.length)} 行</small>
|
|
1071
|
+
</summary>
|
|
1072
|
+
${this.renderExpandedTarget(n)}
|
|
1073
|
+
<div class="diff-toolbar">
|
|
1074
|
+
<span>${i?`显示 ${String(a.length)} / ${String(r.length)} 行`:`完整 diff`}</span>
|
|
1075
|
+
<button type="button" @click=${()=>{this.copyDiff(e)}}>${this.copied?`已复制`:`复制 diff`}</button>
|
|
1076
|
+
</div>
|
|
1077
|
+
<pre class="diff" aria-label=${t}><code class="diff-content">${a.map(e=>g`<span class=${ev(e)}>${e}</span>`)}</code></pre>
|
|
1078
|
+
${i?g`
|
|
1079
|
+
<button class="show-more" type="button" @click=${()=>{this.showFullDiff=!0}}>
|
|
1080
|
+
显示全部 ${String(r.length)} 行 diff
|
|
1081
|
+
</button>
|
|
1082
|
+
`:null}
|
|
1083
|
+
</details>
|
|
1084
|
+
`}onDiffToggle(e){let t=e.currentTarget;t instanceof HTMLDetailsElement&&(this.diffOpen=t.open)}async copyDiff(e){if(!await bh(e)){this.copied=!1;return}this.copied=!0,window.setTimeout(()=>{this.copied=!1},1200)}static{this.styles=h`
|
|
1085
|
+
:host { display: block; width: 100%; max-width: 100%; min-width: 0; color: var(--pi-text); }
|
|
1086
|
+
.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); }
|
|
1087
|
+
.tool-card.running, .tool-card.pending { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); }
|
|
1088
|
+
.tool-card.success { border-color: var(--pi-success-border); background: var(--pi-success-bg); }
|
|
1089
|
+
.tool-card.error { border-color: var(--pi-danger); background: color-mix(in srgb, var(--pi-danger) 10%, var(--pi-bg)); }
|
|
1090
|
+
.tool-header { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; min-width: 0; }
|
|
1091
|
+
.tool-title { flex: 1 1 auto; display: inline-flex; align-items: baseline; gap: 7px; min-width: 0; }
|
|
1092
|
+
.status-icon { flex: 0 0 auto; color: var(--pi-muted); }
|
|
1093
|
+
strong { flex: 0 0 auto; color: var(--pi-text); }
|
|
1094
|
+
.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; }
|
|
1095
|
+
.summary { color: var(--pi-muted); font-family: inherit; }
|
|
1096
|
+
.tool-meta { flex: 0 0 auto; display: inline-flex; align-items: baseline; gap: 8px; color: var(--pi-muted); font-size: 12px; }
|
|
1097
|
+
.diff-stats { display: inline-flex; gap: 3px; }
|
|
1098
|
+
.added, .diff .added { color: var(--pi-success); }
|
|
1099
|
+
.removed, .diff .removed { color: var(--pi-danger); }
|
|
1100
|
+
.status-label { text-transform: uppercase; letter-spacing: .04em; color: var(--pi-muted); }
|
|
1101
|
+
.notice { margin: 0; color: var(--pi-warning); }
|
|
1102
|
+
.muted { margin: 0; color: var(--pi-muted); }
|
|
1103
|
+
.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; }
|
|
1104
|
+
.text-body { border-top: 1px solid var(--pi-border-muted); padding-top: 6px; }
|
|
1105
|
+
.detail-target, .detail-result { display: grid; gap: 4px; margin-top: 8px; min-width: 0; }
|
|
1106
|
+
.detail-label { color: var(--pi-muted); font-size: 12px; text-transform: uppercase; letter-spacing: .04em; }
|
|
1107
|
+
.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); }
|
|
1108
|
+
.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; }
|
|
1109
|
+
.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; }
|
|
1110
|
+
.diff-details { min-width: 0; max-width: 100%; border-top: 1px solid var(--pi-border-muted); padding-top: 6px; }
|
|
1111
|
+
.diff-details > summary { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; min-width: 0; color: var(--pi-muted); cursor: pointer; }
|
|
1112
|
+
.diff-details > summary span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1113
|
+
.diff-details > summary small { flex: 0 0 auto; color: var(--pi-dim); }
|
|
1114
|
+
.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; }
|
|
1115
|
+
.diff-toolbar span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1116
|
+
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; }
|
|
1117
|
+
button:hover, button:focus { border-color: var(--pi-accent); }
|
|
1118
|
+
.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; }
|
|
1119
|
+
.diff-content { display: block; width: max-content; min-width: 100%; }
|
|
1120
|
+
.diff span { display: block; min-height: 1.45em; padding: 0 8px; white-space: pre; }
|
|
1121
|
+
.diff .context { color: var(--pi-muted); }
|
|
1122
|
+
.diff .hunk { color: var(--pi-accent); }
|
|
1123
|
+
.diff .file { color: var(--pi-dim); }
|
|
1124
|
+
.diff .meta { color: var(--pi-dim); }
|
|
1125
|
+
.diff .added { background: color-mix(in srgb, var(--pi-success) 12%, transparent); }
|
|
1126
|
+
.diff .removed { background: color-mix(in srgb, var(--pi-danger) 12%, transparent); }
|
|
1127
|
+
.show-more { justify-self: start; }
|
|
1128
|
+
`}};z([b({attribute:!1})],J_.prototype,`execution`,void 0),z([x()],J_.prototype,`showFullDiff`,void 0),z([x()],J_.prototype,`copied`,void 0),z([x()],J_.prototype,`diffOpen`,void 0),J_=z([y(`tool-execution-view`)],J_);function Y_(e,t){if(t!==void 0&&t!==``)return{label:`File`,text:t};let n=sv(e.args,`command`);if(n!==void 0&&n!==``)return{label:`Command`,text:n};if(e.summary!==``)return{label:`Input`,text:e.summary}}function X_(e){return sv(e,`path`)??sv(e,`file_path`)}function Z_(e){if(e.toolName!==`edit`)return;let t=ov(e.args,`edits`);if(Array.isArray(t))return`${String(t.length)} 处编辑`;if(typeof ov(e.args,`oldText`)==`string`&&typeof ov(e.args,`newText`)==`string`)return`1 处编辑`}function Q_(e){return sv(e,`diff`)}function $_(e){let t=0,n=0;for(let r of e.split(`
|
|
1129
|
+
`))tv(r)?t++:nv(r)&&n++;return{added:t,removed:n}}function ev(e){return tv(e)?`added`:nv(e)?`removed`:e.startsWith(`@@`)?`hunk`:e.startsWith(`+++`)||e.startsWith(`---`)?`file`:e.startsWith(`diff `)||e.startsWith(`index `)?`meta`:`context`}function tv(e){return e.startsWith(`+`)&&!e.startsWith(`+++`)}function nv(e){return e.startsWith(`-`)&&!e.startsWith(`---`)}function rv(e){return e===`success`?`✓`:e===`error`?`✖`:e===`running`?`●`:`○`}function iv(e){return e===`success`?`完成`:e===`error`?`失败`:e===`running`?`运行中`:`等待中`}function av(e){return typeof e==`object`&&!!e}function ov(e,t){return av(e)?e[t]:void 0}function sv(e,t){let n=ov(e,t);return typeof n==`string`?n:void 0}var cv=new Intl.DateTimeFormat(void 0,{dateStyle:`medium`,timeStyle:`medium`}),lv=[`你打开此会话时助手已经在回复。完整答案很快会显示。`,`当前标签页接入得稍晚,完整回复准备好后会显示。`,`助手已先开始回复,完整答案到达后会显示。`,`正在等待完整回复,避免显示不完整内容。`,`回复仍在生成中,完整答案即将显示。`,`正在同步这次回复,稍后会显示完整版本。`],uv={active:`活跃`,"agent running":`助手运行中`,"bash complete":`Shell 已完成`,"bash failed":`Shell 失败`,"compaction complete":`压缩已完成`,"compaction failed":`压缩失败`,compacting:`正在压缩`,"duplicate queued message ignored":`已忽略重复排队消息`,error:`错误`,idle:`空闲`,"message complete":`消息已完成`,"message queued":`消息已排队`,"message queued during compaction":`压缩期间消息已排队`,"message started":`消息已开始`,"prompt accepted":`提示已接受`,queued:`已排队`,"receiving response":`正在接收回复`,"running bash":`Shell 运行中`,"running tool":`工具运行中`,"steering queued":`引导已排队`,stopped:`已停止`,"tool complete":`工具已完成`,"tool failed":`工具失败`,"turn complete":`回合已完成`};function dv(){return lv[Math.floor(Math.random()*lv.length)]??lv[0]}function fv(e){return pv(e,0,100)}function pv(e,t,n){return Number.isFinite(e)?Math.min(n,Math.max(t,e)):t}function mv(e,t){return[e.length===0?void 0:{source:`client`,heading:`等待会话启动`,detail:`后端会话准备好后将自动发送`,messages:e},t.length===0?void 0:{source:`server`,heading:`排队消息`,detail:`${String(t.length)} 条待处理 · 停止会清空队列`,messages:t}].filter(e=>e!==void 0)}function hv(e){let t=e.meta?.timestamp,n=[t===void 0?void 0:gv(t),_v(e)].filter(e=>e!==void 0&&e!==``);return n.length===0?`没有可用的 Pi 消息元数据`:n.join(` · `)}function gv(e){let t=new Date(e);if(Number.isFinite(t.getTime()))return cv.format(t)}function _v(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 K=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.isReceivingPartialStream=!1,this.isSendingPrompt=!1,this.isCompacting=!1,this.pendingMessageCount=0,this.clientQueuedMessages=[],this.canClearServerQueue=!1,this.pinnedToBottom=!0,this.disclosures=new ch,this.scrollController=new Gh,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.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(`isReceivingPartialStream`)||e.has(`sessionId`)&&this.isReceivingPartialStream)&&this.syncPartialStreamNoticeBody(),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()}render(){let e=this.groupedMessages();return g`
|
|
1130
|
+
<div class="chat-wrap">
|
|
1131
|
+
${this.renderConversationRail()}
|
|
1132
|
+
<div class="chat" @scroll=${()=>{this.onScroll()}} @wheel=${e=>{this.onWheel(e)}} @touchstart=${e=>{this.onTouchStart(e)}} @touchmove=${e=>{this.onTouchMove(e)}}>
|
|
1133
|
+
${this.renderHistoryBoundary()}
|
|
1134
|
+
${ah(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))}
|
|
1135
|
+
${this.renderQueuedMessages()}
|
|
1136
|
+
${this.renderSessionActivity()}
|
|
1137
|
+
</div>
|
|
1138
|
+
${this.renderActivityDock()}
|
|
1139
|
+
</div>
|
|
1140
|
+
`}groupedMessages(){return this.groupedMessagesInput===this.messages&&this.groupedMessagesStart===this.messageStart?this.groupedMessagesCache:(this.groupedMessagesInput=this.messages,this.groupedMessagesStart=this.messageStart,this.groupedMessagesCache=mh(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`
|
|
1141
|
+
<div class="activity-dock active" aria-live="polite">
|
|
1142
|
+
<span class="dot"></span>
|
|
1143
|
+
<span class="activity-text">正在发送你的消息…</span>
|
|
1144
|
+
</div>
|
|
1145
|
+
`;let e=this.activityState();return e===void 0?null:g`
|
|
1146
|
+
<div class=${e!==`idle`||this.activity?.phase===`active`?`activity-dock active`:`activity-dock`} aria-live="polite">
|
|
1147
|
+
<span class="dot"></span>
|
|
1148
|
+
<span class="activity-text">${this.activityText(e)}</span>
|
|
1149
|
+
</div>
|
|
1150
|
+
`}renderQueuedMessages(){let e=this.status?.queuedMessages??[];return g`${mv(this.clientQueuedMessages,e).map(e=>this.renderQueuedMessageList(e))}`}renderQueuedMessageList(e){let t=e.source===`server`&&this.canClearServerQueue&&this.onClearServerQueue!==void 0;return g`
|
|
1151
|
+
<aside class="queued-messages" aria-live="polite">
|
|
1152
|
+
<div class="queued-header">
|
|
1153
|
+
<div class="queued-heading">
|
|
1154
|
+
<strong>${e.heading}</strong>
|
|
1155
|
+
<small>${e.detail}</small>
|
|
1156
|
+
</div>
|
|
1157
|
+
${t?g`
|
|
1158
|
+
<button type="button" class="queued-clear-button" title="清空排队消息,不停止正在进行的工作" @click=${this.handleClearServerQueue}>清空队列</button>
|
|
1159
|
+
`:null}
|
|
1160
|
+
</div>
|
|
1161
|
+
${e.messages.map((e,t)=>g`
|
|
1162
|
+
<div class="queued-message">
|
|
1163
|
+
<span class="queued-kind">${e.kind===`steer`?`引导`:`跟进`} ${String(t+1)}</span>
|
|
1164
|
+
<formatted-text .text=${e.text}></formatted-text>
|
|
1165
|
+
</div>
|
|
1166
|
+
`)}
|
|
1167
|
+
</aside>
|
|
1168
|
+
`}renderSessionActivity(){return this.isReceivingPartialStream?g`
|
|
1169
|
+
<aside class="session-activity receiving" aria-live="polite">
|
|
1170
|
+
<strong>正在同步…</strong>
|
|
1171
|
+
<span>${this.currentPartialStreamNoticeBody()}</span>
|
|
1172
|
+
</aside>
|
|
1173
|
+
`:this.isCompacting?g`
|
|
1174
|
+
<aside class="session-activity compacting" aria-live="polite">
|
|
1175
|
+
<strong>正在压缩历史…</strong>
|
|
1176
|
+
<span>助手正在总结早前上下文。压缩完成前,新提示会排队等待。</span>
|
|
1177
|
+
${this.pendingMessageCount>0?g`<small>${this.pendingMessageCount} 条消息已排队</small>`:null}
|
|
1178
|
+
</aside>
|
|
1179
|
+
`:null}syncPartialStreamNoticeBody(){this.partialStreamNoticeBody=this.isReceivingPartialStream?dv():void 0}currentPartialStreamNoticeBody(){return this.partialStreamNoticeBody??=dv(),this.partialStreamNoticeBody}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;if(t===void 0||e!==`idle`&&t.phase===`idle`)return yv(e);let n=yv(t.label);return t.detail!==void 0&&t.detail!==``?`${n}: ${t.detail}`:n}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?fv(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 fv(pv(this.currentConversationIndex??t,0,e-1)/(e-1)*100)}renderHistoryBoundary(){let e=this.historyRangeLabel();return this.loadingMore?g`<div class="history-boundary"><span>正在加载更早的消息…</span>${e}</div>`:this.hasMore?g`
|
|
1180
|
+
<div class="history-boundary">
|
|
1181
|
+
<button type="button" class="history-load-button" ?disabled=${this.loadMoreRequested} @click=${()=>{this.requestLoadMore()}}>加载更早的消息</button>
|
|
1182
|
+
<span>向上滚动加载更早的消息</span>
|
|
1183
|
+
${e}
|
|
1184
|
+
</div>
|
|
1185
|
+
`:this.messages.length?g`<div class="history-boundary"><span>会话开始</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>显示消息 ${e}–${t} / ${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`
|
|
1186
|
+
${this.renderScrollMarker(this.messageScrollMarkerId(t))}
|
|
1187
|
+
<article class=${n?`msg tool-execution-shell`:`msg ${e.role}`} data-index=${t} data-scroll-anchor-id=${this.messageAnchorKey(t)}>
|
|
1188
|
+
${n?null:this.renderMessageHeader(e,String(t))}
|
|
1189
|
+
${e.parts.map(t=>this.renderPart(t,e))}
|
|
1190
|
+
</article>
|
|
1191
|
+
`}renderToolImageOutput(e,t,n){let r=n===void 0||n===``?`工具输出`:`${n} 输出`;return g`
|
|
1192
|
+
${this.renderScrollMarker(this.messageScrollMarkerId(t))}
|
|
1193
|
+
<article class="msg tool-image-output" data-index=${t} data-scroll-anchor-id=${this.messageAnchorKey(t)}>
|
|
1194
|
+
${this.renderMessageHeader(e,String(t),r)}
|
|
1195
|
+
${e.parts.map(t=>this.renderPart(t,e))}
|
|
1196
|
+
</article>
|
|
1197
|
+
`}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`
|
|
1198
|
+
${this.renderScrollMarker(this.groupScrollMarkerId(n))}
|
|
1199
|
+
<details class=${r?`msg event-group live`:`msg event-group`} data-index=${t} data-scroll-anchor-id=${this.groupAnchorKey(t)} ?open=${a} @toggle=${e=>{this.onGroupToggle(i,e,r)}}>
|
|
1200
|
+
<summary>
|
|
1201
|
+
<b class="label">${r?`实时事件`:`事件`}</b>
|
|
1202
|
+
<span>${hh(e)}</span>
|
|
1203
|
+
</summary>
|
|
1204
|
+
${a?this.renderMessageGroupBody(e,t):null}
|
|
1205
|
+
</details>
|
|
1206
|
+
`}renderMessageGroupBody(e,t){return g`
|
|
1207
|
+
<div class="group-body">
|
|
1208
|
+
${e.map((e,n)=>{let r=this.isToolExecutionOnlyMessage(e);return g`
|
|
1209
|
+
<section class=${r?`group-msg tool-execution-shell`:`group-msg ${e.role}`} data-index=${t+n} data-scroll-anchor-id=${this.eventAnchorKey(t+n)}>
|
|
1210
|
+
${r?null:this.renderMessageHeader(e,`${String(t)}:${String(n)}`)}
|
|
1211
|
+
${e.parts.map(t=>this.renderPart(t,e))}
|
|
1212
|
+
</section>
|
|
1213
|
+
`})}
|
|
1214
|
+
</div>
|
|
1215
|
+
`}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`
|
|
1216
|
+
<div class="msg-header">
|
|
1217
|
+
<b class="label">${n===e.role?vv(e.role):n}</b>
|
|
1218
|
+
<div class="msg-header-trailing">
|
|
1219
|
+
${this.renderMessageActions(e,t)}
|
|
1220
|
+
<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>
|
|
1221
|
+
</div>
|
|
1222
|
+
</div>
|
|
1223
|
+
`}renderMessageActions(e,t){if(!this.isCopyableMessage(e))return null;let n=this.copiedMessageKey===t;return g`
|
|
1224
|
+
<div class="msg-actions" aria-label="消息操作">
|
|
1225
|
+
<button type="button" class="msg-action" title=${n?`已复制`:`复制消息`} aria-label=${`${n?`已复制`:`复制`}${vv(e.role)}消息`} @click=${n=>{this.copyMessage(e,t,n)}}>
|
|
1226
|
+
<span aria-hidden="true">${n?`✓`:`⧉`}</span>
|
|
1227
|
+
</button>
|
|
1228
|
+
</div>
|
|
1229
|
+
`}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(`
|
|
1230
|
+
|
|
1231
|
+
`);return this.messageCopyTextCache.set(e,n),n}async copyMessage(e,t,n){n.stopPropagation(),await bh(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=hv(e);return this.messageMetaCache.set(e,n),n}renderPart(e,t){return e.type===`text`&&t?.role===`bash`?g`<pre class="part shell-output">${e.text}</pre>`:e.type===`text`?g`<formatted-text class="part" .text=${e.text}></formatted-text>`:e.type===`image`?g`<figure class="part chat-image"><img src=${`data:${e.mimeType};base64,${e.data}`} alt="用户上传的图片" loading="lazy" @load=${this.onImageLoad}></figure>`:e.type===`thinking`?g`<details class="part"><summary>思考</summary><formatted-text .text=${e.text}></formatted-text></details>`:e.type===`skillInvocation`?g`
|
|
1232
|
+
<details class="part skill-invocation">
|
|
1233
|
+
<summary><b>[技能]</b> ${e.name}</summary>
|
|
1234
|
+
<small>${e.location}</small>
|
|
1235
|
+
<formatted-text .text=${e.content}></formatted-text>
|
|
1236
|
+
</details>
|
|
1237
|
+
`:e.type===`skillRead`?g`
|
|
1238
|
+
<div class="part skill-read">
|
|
1239
|
+
<strong>已加载 ${e.name}</strong>
|
|
1240
|
+
<small>读取 ${e.path}</small>
|
|
1241
|
+
</div>
|
|
1242
|
+
`: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`
|
|
1243
|
+
<details class="part" ?open=${e.isError}>
|
|
1244
|
+
<summary>${e.isError?`✖`:`✓`} ${e.toolName} 结果</summary>
|
|
1245
|
+
<formatted-text .text=${e.text}></formatted-text>
|
|
1246
|
+
</details>
|
|
1247
|
+
`: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&&Ih({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||Xh(e)}isAtBottom(){let e=this.chat;return!e||Yh(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&&!this.isReceivingPartialStream}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 Oh(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(kh(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=pv(n,0,Math.max(0,e-1));return}this.currentConversationIndex=pv(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 $h(e,Array.from(this.renderRoot.querySelectorAll(`article.msg`)))??$h(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`m:${String(e)}`}groupRenderKey(e){return`g:${String(e)}`}groupAnchorKey(e){return`g:${String(e)}`}eventAnchorKey(e){return`e:${String(e)}`}messageScrollMarkerId(e){return`m:${String(e)}`}groupScrollMarkerId(e){return`g:${String(e)}`}static{this.styles=ng}};z([b({attribute:!1})],K.prototype,`messages`,void 0),z([b()],K.prototype,`sessionId`,void 0),z([b({type:Number})],K.prototype,`messageStart`,void 0),z([b({type:Number})],K.prototype,`messageEnd`,void 0),z([b({type:Number})],K.prototype,`messageTotal`,void 0),z([b({type:Boolean})],K.prototype,`hasMore`,void 0),z([b({type:Boolean})],K.prototype,`loadingMore`,void 0),z([b({type:Boolean})],K.prototype,`isReceivingPartialStream`,void 0),z([b({type:Boolean})],K.prototype,`isSendingPrompt`,void 0),z([b({type:Boolean})],K.prototype,`isCompacting`,void 0),z([b({type:Number})],K.prototype,`pendingMessageCount`,void 0),z([b({attribute:!1})],K.prototype,`clientQueuedMessages`,void 0),z([b({attribute:!1})],K.prototype,`status`,void 0),z([b({attribute:!1})],K.prototype,`activity`,void 0),z([b({type:Boolean})],K.prototype,`canClearServerQueue`,void 0),z([b({attribute:!1})],K.prototype,`onClearServerQueue`,void 0),z([b({attribute:!1})],K.prototype,`onLoadMore`,void 0),z([S(`.chat`)],K.prototype,`chat`,void 0),z([x()],K.prototype,`pinnedToBottom`,void 0),z([x()],K.prototype,`expandedMetaKey`,void 0),z([x()],K.prototype,`copiedMessageKey`,void 0),z([x()],K.prototype,`currentConversationIndex`,void 0),z([x()],K.prototype,`loadMoreRequested`,void 0),K=z([y(`chat-view`)],K);function vv(e){return e===`user`?`用户`:e===`assistant`?`助手`:e===`system`?`系统`:e===`tool`?`工具`:e===`toolResult`?`工具结果`:e===`bash`?`Shell`:e===`skill`?`技能`:e}function yv(e){return e===`bash`?`Shell 运行中`:e===`running`?`运行中`:uv[e]??e}var bv=new Set([`image/jpeg`,`image/png`,`image/gif`,`image/webp`]);function xv(e){return typeof e==`string`&&bv.has(e)}function Sv(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 Cv=`application/octet-stream`,wv=`读取附件失败。`;async function Tv(e,t){let n=[],r;for(let i of e)try{let e=await t(i);n.push(kv(i,e))}catch{r=wv}return{attachments:n,...r===void 0?{}:{error:r}}}function Ev(e){return e.kind===`image`&&xv(e.mimeType)}function Dv(e){return e.every(e=>Ev(e))}function Ov(e,t){return Dv(t)?e:`folder`}function kv(e,t){return xv(e.type)?{kind:`image`,name:jv(e),mimeType:e.type,data:t,size:e.size}:{kind:`file`,name:jv(e),mimeType:Av(e),data:t,size:e.size}}function Av(e){let t=e.type.trim();return t===``?Cv:t}function jv(e){return e.name===``?xv(e.type)?`pasted-image.${Sv(e.type)}`:`pasted-file.bin`:e.name}var Mv=`pi-web:attachment-delivery`;function Nv(){try{return typeof localStorage>`u`?void 0:localStorage}catch{return}}function Pv(e=Nv()){try{return e?.getItem(Mv)===`folder`?`folder`:`inline`}catch{return`inline`}}function Fv(e,t=Nv()){try{t?.setItem(Mv,e)}catch{}}var Iv=`(pointer: coarse), (max-width: 760px)`,Lv=`pi-web.promptEnterPreference`;function Rv(){return typeof window<`u`&&`matchMedia`in window?window.matchMedia(Iv):void 0}function zv(e){return e===`send`||e===`newline`?e:`auto`}function Bv(e=Gv()){if(e===void 0)return`auto`;try{return zv(e.getItem(Lv))}catch{return`auto`}}function Vv(e,t=Gv()){if(t!==void 0)try{t.setItem(Lv,e)}catch{}}function Hv(e=Rv(),t=Bv()){return t===`send`||t!==`newline`&&e?.matches!==!0}function Uv(e,t,n=Rv()){return e?n?.matches!==!0||t:!1}function Wv(e,t=Rv(),n=Bv()){let r=Hv(t,n);return e?!r:r}function Gv(){if(!(typeof window>`u`))try{return window.localStorage}catch{return}}function Kv(){return Je`
|
|
1248
|
+
<svg class="prompt-action-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
1249
|
+
<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>
|
|
1250
|
+
</svg>
|
|
1251
|
+
`}function qv(){return Je`
|
|
1252
|
+
<svg class="prompt-action-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
1253
|
+
<path d="M21 3 13.5 21l-2-8.5L3 10.5Z"></path>
|
|
1254
|
+
<path d="M21 3 11.5 12.5"></path>
|
|
1255
|
+
</svg>
|
|
1256
|
+
`}function Jv(){return Je`
|
|
1257
|
+
<svg class="prompt-action-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
1258
|
+
<path d="M4 7h11"></path>
|
|
1259
|
+
<path d="M4 12h7"></path>
|
|
1260
|
+
<path d="M4 17h7"></path>
|
|
1261
|
+
<path d="m15 14 5 3-5 3z"></path>
|
|
1262
|
+
</svg>
|
|
1263
|
+
`}function Yv(){return qv()}function Xv(){return Je`
|
|
1264
|
+
<svg class="prompt-action-icon prompt-action-icon-filled" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
1265
|
+
<rect x="6.5" y="6.5" width="11" height="11" rx="2"></rect>
|
|
1266
|
+
</svg>
|
|
1267
|
+
`}function Zv(e){let t=Math.max(e.total,1),n=t>1?1.2:0,r=(18-n*(t-1))/t;return Je`
|
|
1268
|
+
<svg class="prompt-thinking-gauge" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
1269
|
+
${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>`})}
|
|
1270
|
+
</svg>
|
|
1271
|
+
`}var Qv=[`off`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`];function $v(e){return e===void 0||e===``?`off`:e}function ey(e,t){let n=t.length>=2?t:Qv,r=n.length-1,i=$v(e),a=n.indexOf(i);return{total:r,filled:a<=0?0:Math.min(a,r)}}var ty=qm(class extends Jm{constructor(e){super(e),this.wasSelected=!1,this.isElementPart=e.type===Km.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){}}),ny=h`
|
|
1272
|
+
:host { display: block; }
|
|
1273
|
+
.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); }
|
|
1274
|
+
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; }
|
|
1275
|
+
button:last-child { border-bottom: 0; }
|
|
1276
|
+
button.selected, button:hover { background: var(--pi-selection-bg); }
|
|
1277
|
+
span { color: var(--pi-muted); font-size: 12px; }
|
|
1278
|
+
small { grid-column: 1 / -1; color: var(--pi-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1279
|
+
`,ry=class extends v{constructor(...e){super(...e),this.items=[],this.selectedIndex=0}render(){return this.items.length?g`
|
|
1280
|
+
<div class="menu">
|
|
1281
|
+
${this.items.map((e,t)=>g`
|
|
1282
|
+
<button class=${t===this.selectedIndex?`selected`:``} ${ty(t===this.selectedIndex,e)} @mousedown=${t=>{t.preventDefault(),this.onPick?.(e)}}>
|
|
1283
|
+
<strong>${e.insertText}</strong>
|
|
1284
|
+
<span>${e.detail}</span>
|
|
1285
|
+
${e.description!==void 0&&e.description!==``?g`<small>${e.description}</small>`:null}
|
|
1286
|
+
</button>
|
|
1287
|
+
`)}
|
|
1288
|
+
</div>
|
|
1289
|
+
`:null}static{this.styles=ny}};z([b({attribute:!1})],ry.prototype,`items`,void 0),z([b({type:Number})],ry.prototype,`selectedIndex`,void 0),z([b({attribute:!1})],ry.prototype,`onPick`,void 0),ry=z([y(`autocomplete-menu`)],ry);var q=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=Pv(),this.attachmentError=void 0,this.attachmentSeq=0,this.requestVersion=0,this.editableCompartment=new s,this.readOnlyCompartment=new s,this.mobilePromptEnterMedia=Rv(),this.explicitShiftKeyActive=!1}willUpdate(e){if(!e.has(`sessionId`)&&!e.has(`machineId`))return;let t=e.has(`sessionId`)?e.get(`sessionId`):this.sessionId,n=ay(e.has(`machineId`)?e.get(`machineId`):this.machineId,t);n!==void 0&&ms(n,this.draft);let r=ay(this.machineId,this.sessionId);this.draft=r===void 0?``:ps(r),this.currentInputMode=xc(this.draft),this.completions=[],this.selectedIndex=0}shouldUpdate(e){return e.has(`status`)&&e.size===1?!iy(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`
|
|
1290
|
+
<footer class=${t?`shell-mode`:``} @paste=${e=>{this.handlePaste(e)}} @dragover=${e=>{this.handleDragOver(e)}} @drop=${e=>{this.handleDrop(e)}}>
|
|
1291
|
+
<div class="editor-wrap">
|
|
1292
|
+
<div class=${`markdown-editor${this.disabled?` markdown-editor-disabled`:``}`} aria-label="给 pi 发送消息" aria-disabled=${this.disabled?`true`:`false`}></div>
|
|
1293
|
+
<input class="attachment-input" type="file" multiple hidden @change=${e=>{this.handleFileInput(e)}} />
|
|
1294
|
+
<button class="editor-attach icon-button" ?disabled=${r} title="附加文件" aria-label="附加文件" @click=${()=>{this.attachmentInput?.click()}}>${Kv()}</button>
|
|
1295
|
+
${t?g`<div class="mode-hint">Shell 命令${e.excludeFromContext?` · 已排除上下文`:``}</div>`:null}
|
|
1296
|
+
${this.isCompacting&&!t?g`<div class="mode-hint">正在压缩历史 · 消息将排队发送</div>`:null}
|
|
1297
|
+
${this.renderAttachments()}
|
|
1298
|
+
<autocomplete-menu .items=${this.completions} .selectedIndex=${this.selectedIndex} .onPick=${e=>{this.pick(e)}}></autocomplete-menu>
|
|
1299
|
+
</div>
|
|
1300
|
+
<div class="actions">
|
|
1301
|
+
${this.renderCompactStatus()}
|
|
1302
|
+
<button class="icon-button send-button" ?disabled=${r} title=${n?`当前活动结束后排队发送`:`发送`} aria-label=${n?`排队发送`:`发送`} @click=${()=>{this.send(`followUp`)}}>${n?Jv():qv()}</button>
|
|
1303
|
+
${this.canSteer&&!this.isCompacting?g`<button class="icon-button steer-button" ?disabled=${r} title="在下次模型调用前引导当前回复" aria-label="引导当前回复" @click=${()=>{this.send(`steer`)}}>${Yv()}</button>`:null}
|
|
1304
|
+
<button class="icon-button stop-button" ?disabled=${this.disabled||!this.canStop} title=${this.canStop?`停止当前工作并清空排队消息`:`当前没有运行任务`} aria-label="停止" @click=${()=>this.onStop?.()}>${Xv()}</button>
|
|
1305
|
+
</div>
|
|
1306
|
+
</footer>
|
|
1307
|
+
`}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??`无模型`;return g`
|
|
1308
|
+
<div class="compact-status" aria-label="会话状态">
|
|
1309
|
+
<button class="select-model" title="选择模型" @click=${()=>this.onSelectModel?.()}>${e.model?.provider!==void 0&&e.model.provider!==``?`${e.model.provider}/`:``}${t}</button>
|
|
1310
|
+
<button class="select-thinking icon-button" title=${`思考级别:${$v(e.thinkingLevel)}`} aria-label=${`思考级别:${$v(e.thinkingLevel)}`} @click=${()=>this.onSelectThinking?.()}>${Zv(ey(e.thinkingLevel,this.availableThinkingLevels))}</button>
|
|
1311
|
+
</div>
|
|
1312
|
+
`}renderAttachments(){if(this.attachments.length===0&&this.attachmentError===void 0)return null;let e=Dv(this.attachments),t=this.effectiveAttachmentDelivery();return g`
|
|
1313
|
+
<div class="attachments" aria-label="待发送附件">
|
|
1314
|
+
${this.attachments.map(e=>g`
|
|
1315
|
+
<div class=${`attachment-chip ${Ev(e)?`attachment-chip-image`:`attachment-chip-file`}`} title=${e.name}>
|
|
1316
|
+
${this.renderAttachmentPreview(e)}
|
|
1317
|
+
<button type="button" class="attachment-remove" title="移除附件" aria-label=${`移除 ${e.name}`} @click=${()=>{this.removeAttachment(e.id)}}>×</button>
|
|
1318
|
+
</div>
|
|
1319
|
+
`)}
|
|
1320
|
+
${this.attachments.length>0?g`
|
|
1321
|
+
<label class="attachment-delivery" title=${e?`附件发送给代理的方式`:`普通文件会保存到工作区并通过引用提及`}>
|
|
1322
|
+
<select .value=${t} @change=${e=>{this.changeDelivery(e)}}>
|
|
1323
|
+
<option value="inline" ?disabled=${!e}>附加到消息${e?``:`(仅图片)`}</option>
|
|
1324
|
+
<option value="folder">保存到 .pi-web/attachments</option>
|
|
1325
|
+
</select>
|
|
1326
|
+
</label>
|
|
1327
|
+
`:null}
|
|
1328
|
+
${this.attachmentError===void 0?null:g`<div class="attachment-error">${this.attachmentError}</div>`}
|
|
1329
|
+
</div>
|
|
1330
|
+
`}renderAttachmentPreview(e){return Ev(e)?g`<img src=${`data:${e.mimeType};base64,${e.data}`} alt=${e.name} />`:g`
|
|
1331
|
+
<div class="attachment-file-preview" aria-hidden="true">${dy(e.name)}</div>
|
|
1332
|
+
<span class="attachment-file-name">${e.name}</span>
|
|
1333
|
+
`}changeDelivery(e){if(!(e.target instanceof HTMLSelectElement))return;let t=e.target.value===`folder`?`folder`:`inline`;if(t===`inline`&&!Dv(this.attachments)){e.target.value=`folder`;return}this.attachmentDelivery=t,Fv(this.attachmentDelivery)}removeAttachment(e){this.attachments=this.attachments.filter(t=>t.id!==e)}async handlePaste(e){let t=cy(e.clipboardData);t.length!==0&&(e.preventDefault(),await this.addAttachmentFiles(t))}handleDragOver(e){e.dataTransfer!==null&&ly(e.dataTransfer)&&e.preventDefault()}async handleDrop(e){let t=cy(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 Tv(e,fy);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=>uy(e))}effectiveAttachmentDelivery(){return Ov(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=>hy(e.state.sliceDoc(0,e.state.selection.main.head))),p.domEventHandlers({keyup:e=>this.handleEditorKeyUp(e),blur:()=>this.resetEditorModifierState()}),o(`给 pi 发送消息... 使用 / 输入命令,@ 输入已跟踪文件,@ 空格显示所有文件`),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=ay(this.machineId,this.sessionId);t!==void 0&&ms(t,this.draft);let n=xc(this.draft);Cc(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 I.commands({id:this.sessionId,cwd:this.cwd},this.machineId).catch(oy);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 I.files(this.cwd,e.query,{scope:e.fileScope,machineId:this.machineId,projectId:this.projectId,workspaceId:this.workspaceId,workspaceScoped:this.workspaceScopedFileSuggestions}).catch(sy);if(t!==this.requestVersion)return;this.completions=n.slice(0,12).map(t=>{let n=gc(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 hc(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=Uv(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 Wv(t,this.mobilePromptEnterMedia,Bv())?(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=ay(this.machineId,this.sessionId);e!==void 0&&hs(e),this.completions=[],this.attachments=[],this.attachmentError=void 0,this.syncEditorDoc()}static{this.styles=yd}};z([b({type:Boolean})],q.prototype,`disabled`,void 0),z([b()],q.prototype,`sessionId`,void 0),z([b()],q.prototype,`cwd`,void 0),z([b()],q.prototype,`machineId`,void 0),z([b()],q.prototype,`projectId`,void 0),z([b()],q.prototype,`workspaceId`,void 0),z([b({type:Boolean})],q.prototype,`workspaceScopedFileSuggestions`,void 0),z([b({type:Boolean})],q.prototype,`canSteer`,void 0),z([b({type:Boolean})],q.prototype,`isCompacting`,void 0),z([b({type:Boolean})],q.prototype,`canStop`,void 0),z([b({attribute:!1})],q.prototype,`status`,void 0),z([b({type:Boolean})],q.prototype,`sending`,void 0),z([b({attribute:!1})],q.prototype,`onSend`,void 0),z([b({attribute:!1})],q.prototype,`onStop`,void 0),z([b({attribute:!1})],q.prototype,`onSelectModel`,void 0),z([b({attribute:!1})],q.prototype,`onSelectThinking`,void 0),z([b({attribute:!1})],q.prototype,`availableThinkingLevels`,void 0),z([S(`.markdown-editor`)],q.prototype,`editorHost`,void 0),z([S(`.attachment-input`)],q.prototype,`attachmentInput`,void 0),z([x()],q.prototype,`currentInputMode`,void 0),z([x()],q.prototype,`completions`,void 0),z([x()],q.prototype,`selectedIndex`,void 0),z([x()],q.prototype,`attachments`,void 0),z([x()],q.prototype,`attachmentDelivery`,void 0),z([x()],q.prototype,`attachmentError`,void 0),q=z([y(`prompt-editor`)],q);function iy(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 ay(e,t){if(!(typeof e!=`string`||e===``)&&!(typeof t!=`string`||t===``))return Na(e,t)}function oy(){return[]}function sy(){return[]}function cy(e){return e===null?[]:Array.from(e.files)}function ly(e){let t=Array.from(e.items);return t.length>0?t.some(e=>e.kind===`file`):Array.from(e.types).includes(`Files`)}function uy(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 dy(e){let t=e.trim(),n=t.lastIndexOf(`.`);return n>=0&&n<t.length-1?t.slice(n+1,n+5).toUpperCase():`FILE`}function fy(e){return new Promise((t,n)=>{let r=new FileReader;r.onerror=()=>{n(r.error??Error(`读取文件失败`))},r.onload=()=>{let e=r.result;if(typeof e!=`string`){n(Error(`文件读取结果异常`));return}let i=e.indexOf(`,`);t(i===-1?e:e.slice(i+1))},r.readAsDataURL(e)})}var py={spellcheck:`true`,autocorrect:`on`,autocapitalize:`sentences`,writingsuggestions:`true`,dir:`auto`},my={spellcheck:`false`,autocorrect:`off`,autocapitalize:`off`,writingsuggestions:`false`,dir:`auto`};function hy(e){return xc(e).kind===`normal`?py:my}function gy(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 _y(e){return!Number.isFinite(e)||e===0?`$0`:e<.01?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`}var vy=h`
|
|
1334
|
+
:host { display: block; color: var(--pi-muted); font: 12px system-ui, sans-serif; }
|
|
1335
|
+
.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; }
|
|
1336
|
+
span { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
1337
|
+
.activity { display: inline-flex; align-items: center; gap: 6px; color: var(--pi-muted); }
|
|
1338
|
+
.activity.active { color: var(--pi-success); }
|
|
1339
|
+
.dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; opacity: .45; flex: 0 0 auto; }
|
|
1340
|
+
.activity.active .dot { animation: pulse 1s ease-in-out infinite; opacity: 1; }
|
|
1341
|
+
.muted { color: var(--pi-dim); }
|
|
1342
|
+
@keyframes pulse { 0%, 100% { transform: scale(.75); opacity: .55; } 50% { transform: scale(1.2); opacity: 1; } }
|
|
1343
|
+
`,yy=class extends v{render(){let e=this.status;if(e===void 0)return g`<div class="bar muted">暂无会话状态</div>`;let t=e.contextUsage,n=t?t.percent==null?`上下文 ${gy(t.contextWindow)}`:`${t.percent.toFixed(1)}%/${gy(t.contextWindow)}`:`上下文未知`,r=e.tokens;return g`
|
|
1344
|
+
<div class="bar">
|
|
1345
|
+
<span>↑${gy(r.input)}</span>
|
|
1346
|
+
<span>↓${gy(r.output)}</span>
|
|
1347
|
+
<span class="context">${n}</span>
|
|
1348
|
+
<span>${_y(e.cost)}</span>
|
|
1349
|
+
${e.pendingMessageCount>0?g`<span>${String(e.pendingMessageCount)} 条排队</span>`:null}
|
|
1350
|
+
</div>
|
|
1351
|
+
`}static{this.styles=vy}};z([b({attribute:!1})],yy.prototype,`status`,void 0),yy=z([y(`status-bar`)],yy);var by=h`
|
|
1352
|
+
:host { position: fixed; inset: 0; z-index: 10; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
|
1353
|
+
.backdrop { display: grid; place-items: center; width: 100%; height: 100%; background: var(--pi-overlay); }
|
|
1354
|
+
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; }
|
|
1355
|
+
header { display: flex; align-items: center; justify-content: space-between; padding: 12px; border-bottom: 1px solid var(--pi-border); }
|
|
1356
|
+
.options { min-height: 0; overflow: auto; outline: none; }
|
|
1357
|
+
button { border: 0; background: transparent; color: var(--pi-text); cursor: pointer; }
|
|
1358
|
+
header button { font-size: 20px; color: var(--pi-muted); }
|
|
1359
|
+
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; }
|
|
1360
|
+
input:focus { border-color: var(--pi-accent); }
|
|
1361
|
+
.options button { display: block; width: 100%; padding: 10px 12px; border-bottom: 1px solid var(--pi-border-muted); text-align: left; }
|
|
1362
|
+
.options button.selected, .options button:hover { background: var(--pi-selection-bg); }
|
|
1363
|
+
small { display: block; margin-top: 4px; color: var(--pi-muted); }
|
|
1364
|
+
.empty { padding: 24px; color: var(--pi-muted); text-align: center; }
|
|
1365
|
+
`,xy=class extends v{constructor(...e){super(...e),this.title=`选择`,this.searchable=!1,this.options=[],this.selectedIndex=0,this.query=``}render(){let e=this.filteredOptions();return g`
|
|
1366
|
+
<div class="backdrop" @mousedown=${()=>this.onCancel?.()}>
|
|
1367
|
+
<section @mousedown=${e=>{e.stopPropagation()}}>
|
|
1368
|
+
<header>
|
|
1369
|
+
<strong>${this.title}</strong>
|
|
1370
|
+
<button @click=${()=>this.onCancel?.()}>×</button>
|
|
1371
|
+
</header>
|
|
1372
|
+
${this.searchable?g`<input placeholder="搜索" .value=${this.query} @input=${e=>{this.handleSearchInput(e)}} @keydown=${e=>{this.handleKeyDown(e)}}>`:null}
|
|
1373
|
+
<div class="options" @keydown=${e=>{this.handleKeyDown(e)}} tabindex="0">
|
|
1374
|
+
${e.map((e,t)=>g`
|
|
1375
|
+
<button class=${t===this.selectedIndex?`selected`:``} ${ty(t===this.selectedIndex,e.value)} @click=${()=>this.onPick?.(e.value)}>
|
|
1376
|
+
<span>${e.label}</span>
|
|
1377
|
+
${e.description!==void 0&&e.description!==``?g`<small>${e.description}</small>`:null}
|
|
1378
|
+
</button>
|
|
1379
|
+
`)}
|
|
1380
|
+
${e.length===0?g`<div class="empty">没有匹配选项</div>`:null}
|
|
1381
|
+
</div>
|
|
1382
|
+
</section>
|
|
1383
|
+
</div>
|
|
1384
|
+
`}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=by}};z([b()],xy.prototype,`title`,void 0),z([b({type:Boolean})],xy.prototype,`searchable`,void 0),z([b({attribute:!1})],xy.prototype,`options`,void 0),z([b({attribute:!1})],xy.prototype,`selectedValue`,void 0),z([b({attribute:!1})],xy.prototype,`onPick`,void 0),z([b({attribute:!1})],xy.prototype,`onCancel`,void 0),z([x()],xy.prototype,`selectedIndex`,void 0),z([x()],xy.prototype,`query`,void 0),xy=z([y(`command-picker`)],xy);var Sy=h`
|
|
1385
|
+
:host { position: fixed; inset: 0; z-index: 20; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
|
1386
|
+
.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; }
|
|
1387
|
+
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; }
|
|
1388
|
+
header { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 10px; border-bottom: 1px solid var(--pi-border); }
|
|
1389
|
+
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; }
|
|
1390
|
+
input::placeholder { color: var(--pi-dim); }
|
|
1391
|
+
button { border: 0; background: transparent; color: var(--pi-text); cursor: pointer; }
|
|
1392
|
+
header button { color: var(--pi-muted); font-size: 22px; padding: 2px 8px; }
|
|
1393
|
+
.options { flex: 1 1 auto; min-height: 0; overflow: auto; }
|
|
1394
|
+
.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; }
|
|
1395
|
+
.options button.selected, .options button:hover { background: var(--pi-selection-bg); }
|
|
1396
|
+
.main { min-width: 0; }
|
|
1397
|
+
strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1398
|
+
small { display: block; color: var(--pi-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1399
|
+
.group { grid-column: 1 / -1; font-size: 12px; }
|
|
1400
|
+
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; }
|
|
1401
|
+
.empty { padding: 24px; color: var(--pi-muted); text-align: center; }
|
|
1402
|
+
`,Cy=class extends v{constructor(...e){super(...e),this.actions=[],this.queryText=``,this.selectedIndex=0}render(){let e=this.filteredActions();return g`
|
|
1403
|
+
<div class="backdrop" @mousedown=${()=>this.onCancel?.()}>
|
|
1404
|
+
<section @mousedown=${e=>{e.stopPropagation()}} @keydown=${e=>{this.handleKeyDown(e)}}>
|
|
1405
|
+
<header>
|
|
1406
|
+
<input
|
|
1407
|
+
.value=${this.queryText}
|
|
1408
|
+
placeholder="搜索操作..."
|
|
1409
|
+
@input=${e=>{e.target instanceof HTMLInputElement&&(this.queryText=e.target.value,this.selectedIndex=0)}}
|
|
1410
|
+
>
|
|
1411
|
+
<button title="关闭" @click=${()=>this.onCancel?.()}>×</button>
|
|
1412
|
+
</header>
|
|
1413
|
+
<div class="options">
|
|
1414
|
+
${e.length===0?g`<div class="empty">未找到操作。</div>`:e.map((e,t)=>g`
|
|
1415
|
+
<button class=${`${t===this.selectedIndex?`selected`:``} ${e.enabled===!1?`disabled`:``}`} ?disabled=${e.enabled===!1} title=${e.disabledReason??e.title} ${ty(t===this.selectedIndex,e.id)} @click=${()=>{this.run(e)}}>
|
|
1416
|
+
<span class="main">
|
|
1417
|
+
<strong>${e.title}</strong>
|
|
1418
|
+
${e.description!==void 0&&e.description!==``?g`<small>${e.description}</small>`:null}
|
|
1419
|
+
${e.enabled===!1&&e.disabledReason!==void 0?g`<small class="disabled-reason">${e.disabledReason}</small>`:null}
|
|
1420
|
+
</span>
|
|
1421
|
+
${e.shortcut===void 0?null:g`<kbd>${nu(e.shortcut)}</kbd>`}
|
|
1422
|
+
${e.group!==void 0&&e.group!==``?g`<small class="group">${e.group}</small>`:null}
|
|
1423
|
+
</button>
|
|
1424
|
+
`)}
|
|
1425
|
+
</div>
|
|
1426
|
+
</section>
|
|
1427
|
+
</div>
|
|
1428
|
+
`}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 wy(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=Sy}};z([b({attribute:!1})],Cy.prototype,`actions`,void 0),z([b({attribute:!1})],Cy.prototype,`onRun`,void 0),z([b({attribute:!1})],Cy.prototype,`onCancel`,void 0),z([S(`input`)],Cy.prototype,`input`,void 0),z([x()],Cy.prototype,`queryText`,void 0),z([x()],Cy.prototype,`selectedIndex`,void 0),Cy=z([y(`action-palette`)],Cy);function wy(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 Ty=class extends v{render(){let e=this.state;return e===void 0?null:g`
|
|
1429
|
+
<div class="backdrop" @mousedown=${()=>{this.cancel()}}>
|
|
1430
|
+
<section @mousedown=${e=>{e.stopPropagation()}} @keydown=${e=>{this.handleKeyDown(e)}}>
|
|
1431
|
+
<header>
|
|
1432
|
+
<strong>${this.dialogTitle(e)}</strong>
|
|
1433
|
+
<button title="关闭" @click=${()=>{this.cancel()}}>×</button>
|
|
1434
|
+
</header>
|
|
1435
|
+
${this.renderBody(e)}
|
|
1436
|
+
</section>
|
|
1437
|
+
</div>
|
|
1438
|
+
`}updated(){this.focusInputIfNeeded()}dialogTitle(e){let t=e.target.projectName===void 0?``:` · ${e.target.projectName}`;switch(e.step){case`method`:return`配置提供商认证${t}`;case`providers`:return`${e.authType===void 0?`选择提供商认证`:e.authType===`oauth`?`选择订阅提供商`:`选择 API key 提供商`}${t}`;case`apiKey`:return`${e.provider.name} 的 API key${t}`;case`oauth`:return`登录 ${e.flow.providerName}${t}`;case`logout`:return`移除已保存的提供商认证${t}`}}renderBody(e){let t=e.target.projectName===void 0?`当前模式`:`当前项目`;switch(e.step){case`method`:return g`
|
|
1439
|
+
<div class="options">
|
|
1440
|
+
<button @click=${()=>{this.onChooseMethod?.(`oauth`)}}><span>使用订阅</span><small>ChatGPT Plus/Pro、Claude Pro/Max 或 GitHub Copilot</small></button>
|
|
1441
|
+
<button @click=${()=>{this.onChooseMethod?.(`api_key`)}}><span>使用 API key</span><small>将 API key 存入${t}的 auth.json</small></button>
|
|
1442
|
+
</div>
|
|
1443
|
+
`;case`providers`:return g`<div class="options">${e.providers.length===0?g`<div class="empty">没有可用提供商。</div>`:e.providers.map(e=>this.renderProviderButton(e))}</div>`;case`apiKey`:return g`
|
|
1444
|
+
<div class="form">
|
|
1445
|
+
<p>输入 <strong>${e.provider.name}</strong> 的 API key。它会保存到${t}的凭据文件。</p>
|
|
1446
|
+
<input type="password" autocomplete="off" placeholder="API key" .value=${e.value} @input=${e=>{e.target instanceof HTMLInputElement&&this.onApiKeyInput?.(e.target.value)}}>
|
|
1447
|
+
${e.error!==void 0&&e.error!==``?g`<div class="error-text">${e.error}</div>`:null}
|
|
1448
|
+
<div class="actions"><button @click=${()=>{this.cancel()}}>取消</button><button class="primary" ?disabled=${e.saving===!0} @click=${()=>{this.onSaveApiKey?.()}}>${e.saving===!0?`正在保存…`:`保存 API key`}</button></div>
|
|
1449
|
+
</div>
|
|
1450
|
+
`;case`oauth`:return this.renderOAuth(e);case`logout`:return g`<div class="options">${e.providers.length===0?g`<div class="empty">没有已保存的凭据。环境变量和 models.json 设置不会变化。</div>`:e.providers.map(e=>g`
|
|
1451
|
+
<button @click=${()=>{this.onLogoutProvider?.(e.id)}}><span>${e.name}</span><small>${e.id} · ${Ey(e.authType)}</small></button>
|
|
1452
|
+
`)}</div>`}}renderProviderButton(e){return g`
|
|
1453
|
+
<button @click=${()=>{this.onSelectProvider?.(e.id,e.authType)}}>
|
|
1454
|
+
<span>${e.name}${e.status.source===void 0?null:g` <em>${Oy(e)}</em>`}</span>
|
|
1455
|
+
<small>${e.id} · ${Ey(e.authType)}</small>
|
|
1456
|
+
</button>
|
|
1457
|
+
`}renderOAuth(e){let t=e.flow,n=t.prompt,r=t.select;return g`
|
|
1458
|
+
<div class="form">
|
|
1459
|
+
${t.auth===void 0?g`<p>正在启动登录流程…</p>`:g`
|
|
1460
|
+
<p>打开此授权链接:</p>
|
|
1461
|
+
<p><a href=${t.auth.url} target="_blank" rel="noreferrer">${t.auth.url}</a></p>
|
|
1462
|
+
${t.auth.instructions===void 0?null:g`<p class="warning">${t.auth.instructions}</p>`}
|
|
1463
|
+
`}
|
|
1464
|
+
${t.progress.length>0?g`<ul class="progress">${t.progress.map(e=>g`<li>${e}</li>`)}</ul>`:null}
|
|
1465
|
+
${n===void 0?null:g`
|
|
1466
|
+
<label>${n.message}</label>
|
|
1467
|
+
<input .value=${e.inputValue??``} placeholder=${n.placeholder??``} @input=${e=>{e.target instanceof HTMLInputElement&&this.onOAuthInput?.(e.target.value)}}>
|
|
1468
|
+
<div class="actions"><button @click=${()=>{this.onOAuthCancel?.()}}>取消</button><button class="primary" ?disabled=${e.responding===!0} @click=${()=>{this.onOAuthRespond?.()}}>提交</button></div>
|
|
1469
|
+
`}
|
|
1470
|
+
${r===void 0?null:g`
|
|
1471
|
+
<p>${r.message}</p>
|
|
1472
|
+
<div class="inline-options">${r.options.map(e=>g`<button @click=${()=>{this.onOAuthRespond?.(e.value)}}>${e.label}</button>`)}</div>
|
|
1473
|
+
`}
|
|
1474
|
+
${e.error!==void 0&&e.error!==``?g`<div class="error-text">${e.error}</div>`:null}
|
|
1475
|
+
${t.status===`error`||t.status===`cancelled`?g`<div class="error-text">${t.error??ky(t.status)}</div><div class="actions"><button @click=${()=>{this.cancel()}}>关闭</button></div>`:null}
|
|
1476
|
+
${n===void 0&&r===void 0&&t.status===`running`?g`<div class="actions"><button @click=${()=>{this.onOAuthCancel?.()}}>取消</button></div>`:null}
|
|
1477
|
+
</div>
|
|
1478
|
+
`}focusInputIfNeeded(){let e=Dy(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=[by,h`
|
|
1479
|
+
.form { display: grid; gap: 12px; padding: 14px; overflow: auto; }
|
|
1480
|
+
.form p { margin: 0; color: var(--pi-text-secondary); overflow-wrap: anywhere; }
|
|
1481
|
+
.form a { color: var(--pi-accent); overflow-wrap: anywhere; }
|
|
1482
|
+
.form code { border: 1px solid var(--pi-border); border-radius: 4px; background: var(--pi-surface); padding: 1px 4px; }
|
|
1483
|
+
label { color: var(--pi-muted); }
|
|
1484
|
+
.actions { display: flex; justify-content: flex-end; gap: 8px; }
|
|
1485
|
+
.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; }
|
|
1486
|
+
.actions button.primary { border-color: var(--pi-success-border); background: var(--pi-success-surface); color: var(--pi-success); }
|
|
1487
|
+
.actions button:disabled { opacity: .6; cursor: wait; }
|
|
1488
|
+
.warning { color: var(--pi-warning); }
|
|
1489
|
+
.error-text { color: var(--pi-danger); }
|
|
1490
|
+
.progress { margin: 0; padding-left: 18px; color: var(--pi-muted); }
|
|
1491
|
+
.inline-options { display: grid; gap: 8px; }
|
|
1492
|
+
em { color: var(--pi-success); font-style: normal; font-size: 12px; }
|
|
1493
|
+
`]}};z([b({attribute:!1})],Ty.prototype,`state`,void 0),z([b({attribute:!1})],Ty.prototype,`onChooseMethod`,void 0),z([b({attribute:!1})],Ty.prototype,`onSelectProvider`,void 0),z([b({attribute:!1})],Ty.prototype,`onApiKeyInput`,void 0),z([b({attribute:!1})],Ty.prototype,`onSaveApiKey`,void 0),z([b({attribute:!1})],Ty.prototype,`onLogoutProvider`,void 0),z([b({attribute:!1})],Ty.prototype,`onOAuthInput`,void 0),z([b({attribute:!1})],Ty.prototype,`onOAuthRespond`,void 0),z([b({attribute:!1})],Ty.prototype,`onOAuthCancel`,void 0),z([b({attribute:!1})],Ty.prototype,`onCancel`,void 0),z([S(`input`)],Ty.prototype,`input`,void 0),Ty=z([y(`auth-dialog`)],Ty);function Ey(e){return e===`oauth`?`订阅`:`API key`}function Dy(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 Oy(e){if(e.status.source===void 0)return``;switch(e.status.source){case`stored`:return`✓ 已配置`;case`environment`:return`✓ 环境变量${e.status.label===void 0?``:`: ${e.status.label}`}`;case`runtime`:return`✓ 运行时`;case`fallback`:return`✓ 自定义 key`;case`models_json_key`:return`✓ models.json key`;case`models_json_command`:return`✓ models.json command`;default:return``}}function ky(e){return e===`cancelled`?`已取消`:e===`error`?`错误`:e}var Ay=class extends v{constructor(...e){super(...e),this.mode=`login`,this.loading=!1,this.error=``,this.currentPassword=``,this.password=``,this.confirmPassword=``,this.localError=``}render(){return g`
|
|
1494
|
+
<div class="backdrop">
|
|
1495
|
+
<section role="dialog" aria-modal="true" aria-label=${this.dialogTitle()} @keydown=${e=>{this.handleKeyDown(e)}}>
|
|
1496
|
+
<header>
|
|
1497
|
+
<div>
|
|
1498
|
+
<span class="eyebrow">普通模式</span>
|
|
1499
|
+
<h1>${this.dialogTitle()}</h1>
|
|
1500
|
+
</div>
|
|
1501
|
+
${this.mode===`change`?g`<button class="close-button" title="关闭" aria-label="关闭" @click=${()=>this.onCancel?.()}>×</button>`:null}
|
|
1502
|
+
</header>
|
|
1503
|
+
<form @submit=${e=>{this.submit(e)}}>
|
|
1504
|
+
${this.mode===`change`?g`
|
|
1505
|
+
<label>
|
|
1506
|
+
<span>当前密码</span>
|
|
1507
|
+
<input type="password" .value=${this.currentPassword} autocomplete="current-password" @input=${e=>{this.currentPassword=My(e),this.localError=``}}>
|
|
1508
|
+
</label>
|
|
1509
|
+
`:null}
|
|
1510
|
+
<label>
|
|
1511
|
+
<span>${this.mode===`login`?`密码`:`新密码`}</span>
|
|
1512
|
+
<input type="password" .value=${this.password} autocomplete=${this.mode===`login`?`current-password`:`new-password`} @input=${e=>{this.password=My(e),this.localError=``}}>
|
|
1513
|
+
</label>
|
|
1514
|
+
${this.mode===`login`?null:g`
|
|
1515
|
+
<label>
|
|
1516
|
+
<span>确认密码</span>
|
|
1517
|
+
<input type="password" .value=${this.confirmPassword} autocomplete="new-password" @input=${e=>{this.confirmPassword=My(e),this.localError=``}}>
|
|
1518
|
+
</label>
|
|
1519
|
+
`}
|
|
1520
|
+
${this.message()===``?null:g`<p class="message">${this.message()}</p>`}
|
|
1521
|
+
<footer>
|
|
1522
|
+
${this.mode===`change`?g`<button type="button" class="secondary" ?disabled=${this.loading} @click=${()=>this.onCancel?.()}>取消</button>`:null}
|
|
1523
|
+
<button class="primary" ?disabled=${this.loading}>${this.loading?`正在处理...`:this.submitLabel()}</button>
|
|
1524
|
+
</footer>
|
|
1525
|
+
</form>
|
|
1526
|
+
</section>
|
|
1527
|
+
</div>
|
|
1528
|
+
`}dialogTitle(){return this.mode===`setup`?`设置进入密码`:this.mode===`change`?`修改进入密码`:`输入进入密码`}submitLabel(){return this.mode===`setup`?`设置并进入`:this.mode===`change`?`保存密码`:`进入`}message(){return this.localError||this.error}async submit(e){e.preventDefault();let t={currentPassword:this.currentPassword,password:this.password,confirmPassword:this.confirmPassword},n=jy(this.mode,t);if(n!==void 0){this.localError=n;return}this.localError=``,await this.onSubmit?.(t)}handleKeyDown(e){e.key!==`Escape`||this.mode!==`change`||(e.preventDefault(),e.stopPropagation(),this.onCancel?.())}static{this.styles=h`
|
|
1529
|
+
:host { position: fixed; inset: 0; z-index: 40; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
|
1530
|
+
.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-bg); }
|
|
1531
|
+
section { width: min(420px, 100%); border: 1px solid var(--pi-border); border-radius: 12px; background: var(--pi-surface); box-shadow: 0 20px 60px var(--pi-shadow-strong); overflow: hidden; }
|
|
1532
|
+
header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px; border-bottom: 1px solid var(--pi-border); }
|
|
1533
|
+
.eyebrow { display: block; color: var(--pi-muted); font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
|
|
1534
|
+
h1 { margin: 0; font-size: 20px; line-height: 1.2; }
|
|
1535
|
+
form { display: grid; gap: 14px; padding: 16px; }
|
|
1536
|
+
label { display: grid; gap: 6px; }
|
|
1537
|
+
label span { color: var(--pi-muted); font-size: 12px; font-weight: 700; }
|
|
1538
|
+
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: 10px; outline: none; font: var(--pi-control-font-size, 16px) var(--pi-control-font-family, system-ui, sans-serif); }
|
|
1539
|
+
input:focus { border-color: var(--pi-accent); box-shadow: 0 0 0 1px var(--pi-accent-border); }
|
|
1540
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 8px 10px; font: inherit; cursor: pointer; }
|
|
1541
|
+
button:disabled { opacity: .6; cursor: default; }
|
|
1542
|
+
.primary { border-color: var(--pi-accent); background: var(--pi-accent); color: #fff; }
|
|
1543
|
+
.close-button { width: 34px; height: 34px; display: grid; place-items: center; border: 0; background: transparent; color: var(--pi-muted); padding: 0; font-size: 24px; }
|
|
1544
|
+
.message { margin: 0; border: 1px solid var(--pi-danger-border); border-radius: 8px; background: var(--pi-danger-surface); color: var(--pi-danger); padding: 10px; }
|
|
1545
|
+
footer { display: flex; justify-content: flex-end; gap: 8px; }
|
|
1546
|
+
`}};z([b()],Ay.prototype,`mode`,void 0),z([b({type:Boolean})],Ay.prototype,`loading`,void 0),z([b()],Ay.prototype,`error`,void 0),z([b({attribute:!1})],Ay.prototype,`onSubmit`,void 0),z([b({attribute:!1})],Ay.prototype,`onCancel`,void 0),z([x()],Ay.prototype,`currentPassword`,void 0),z([x()],Ay.prototype,`password`,void 0),z([x()],Ay.prototype,`confirmPassword`,void 0),z([x()],Ay.prototype,`localError`,void 0),Ay=z([y(`normal-auth-dialog`)],Ay);function jy(e,t){if(e===`change`&&(t.currentPassword??``)===``)return`请输入当前密码。`;if(t.password===``)return`请输入密码。`;if(e!==`login`&&t.password!==(t.confirmPassword??``))return`两次输入的密码不一致。`}function My(e){return e.target instanceof HTMLInputElement?e.target.value:``}var Ny=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 I.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`
|
|
1547
|
+
<div class="backdrop" @click=${()=>this.onCancel?.()}>
|
|
1548
|
+
<section @click=${e=>{e.stopPropagation()}}>
|
|
1549
|
+
<header>
|
|
1550
|
+
<strong>添加项目</strong>
|
|
1551
|
+
<button @click=${()=>{this.onCancel?.()}} aria-label="关闭">×</button>
|
|
1552
|
+
</header>
|
|
1553
|
+
<div class="body">
|
|
1554
|
+
<label>
|
|
1555
|
+
项目文件夹
|
|
1556
|
+
<input .value=${this.path} @input=${e=>{this.onPathInput(e)}} @keydown=${e=>{this.onKeyDown(e)}} placeholder="/path/to/project or ~/code/project" autofocus />
|
|
1557
|
+
</label>
|
|
1558
|
+
<div class="suggestions">
|
|
1559
|
+
${this.loading?g`<div class="hint">正在加载文件夹…</div>`:null}
|
|
1560
|
+
${this.suggestions.map((e,t)=>g`
|
|
1561
|
+
<button class=${t===this.selected?`selected`:``} @click=${()=>{this.pick(e)}}>
|
|
1562
|
+
${e.path}
|
|
1563
|
+
</button>
|
|
1564
|
+
`)}
|
|
1565
|
+
${!this.loading&&this.suggestions.length===0?g`<div class="hint">没有匹配的文件夹。输入新路径即可创建。</div>`:null}
|
|
1566
|
+
</div>
|
|
1567
|
+
<label class="check">
|
|
1568
|
+
<input type="checkbox" .checked=${this.createMissing} @change=${e=>{this.onCreateMissingChange(e)}} />
|
|
1569
|
+
如果文件夹不存在则创建
|
|
1570
|
+
</label>
|
|
1571
|
+
</div>
|
|
1572
|
+
<footer>
|
|
1573
|
+
<button @click=${()=>{this.onCancel?.()}}>取消</button>
|
|
1574
|
+
<button class="primary" ?disabled=${this.path.trim()===``} @click=${()=>{this.submit()}}>添加项目</button>
|
|
1575
|
+
</footer>
|
|
1576
|
+
</section>
|
|
1577
|
+
</div>
|
|
1578
|
+
`}static{this.styles=h`
|
|
1579
|
+
:host { position: fixed; inset: 0; z-index: 30; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
|
1580
|
+
.backdrop { display: grid; place-items: start center; width: 100%; height: 100%; padding-top: min(12vh, 90px); box-sizing: border-box; background: var(--pi-overlay); }
|
|
1581
|
+
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; }
|
|
1582
|
+
header, footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px; border-bottom: 1px solid var(--pi-border); }
|
|
1583
|
+
footer { border-top: 1px solid var(--pi-border); border-bottom: 0; justify-content: end; }
|
|
1584
|
+
.body { display: grid; gap: 12px; padding: 12px; min-height: 0; }
|
|
1585
|
+
label { display: grid; gap: 6px; color: var(--pi-muted); }
|
|
1586
|
+
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); }
|
|
1587
|
+
.check { display: flex; grid-template-columns: auto 1fr; align-items: center; color: var(--pi-text); }
|
|
1588
|
+
.suggestions { min-height: 90px; max-height: 320px; overflow: auto; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); }
|
|
1589
|
+
.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; }
|
|
1590
|
+
.suggestions button.selected, .suggestions button:hover { background: var(--pi-selection-bg); }
|
|
1591
|
+
.hint { padding: 12px; color: var(--pi-muted); }
|
|
1592
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
|
1593
|
+
header button { border: 0; background: transparent; color: var(--pi-muted); font-size: 22px; padding: 0 8px; }
|
|
1594
|
+
.primary { border-color: var(--pi-success-border); background: var(--pi-success-border); }
|
|
1595
|
+
button:disabled { opacity: .5; cursor: not-allowed; }
|
|
1596
|
+
`}};z([b({attribute:!1})],Ny.prototype,`onSubmit`,void 0),z([b({attribute:!1})],Ny.prototype,`onCancel`,void 0),z([b()],Ny.prototype,`machineId`,void 0),z([x()],Ny.prototype,`path`,void 0),z([x()],Ny.prototype,`createMissing`,void 0),z([x()],Ny.prototype,`suggestions`,void 0),z([x()],Ny.prototype,`selected`,void 0),z([x()],Ny.prototype,`loading`,void 0),z([S(`input`)],Ny.prototype,`pathInput`,void 0),Ny=z([y(`project-dialog`)],Ny);var Py=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=Fy(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`&&Iy(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===``||Iy(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?Iy(this.url):void 0,n=this.validInput()!==void 0&&!this.submitting;return g`
|
|
1597
|
+
<div class="backdrop" @click=${()=>this.onCancel?.()}>
|
|
1598
|
+
<section @click=${e=>{e.stopPropagation()}}>
|
|
1599
|
+
<form @submit=${e=>{this.handleSubmit(e)}} @keydown=${e=>{this.handleKeyDown(e)}}>
|
|
1600
|
+
<header>
|
|
1601
|
+
<strong>添加机器</strong>
|
|
1602
|
+
<button type="button" @click=${()=>{this.onCancel?.()}} aria-label="关闭">×</button>
|
|
1603
|
+
</header>
|
|
1604
|
+
<div class="body">
|
|
1605
|
+
${this.error===``?null:g`<div class="dialog-error" role="alert">${this.error}</div>`}
|
|
1606
|
+
<label>
|
|
1607
|
+
远程 PI WEB URL
|
|
1608
|
+
<input name="baseUrl" type="url" .value=${this.url} @input=${e=>{this.handleUrlInput(e)}} placeholder="http://dev-box.local:8504" autocomplete="url" inputmode="url" autofocus />
|
|
1609
|
+
</label>
|
|
1610
|
+
<small class=${t===void 0?`hint`:`field-error`}>${t??`先输入可访问的基础 URL,包含 http:// 或 https://。`}</small>
|
|
1611
|
+
${e?g`
|
|
1612
|
+
<label>
|
|
1613
|
+
机器名称
|
|
1614
|
+
<input name="name" type="text" .value=${this.name} @input=${e=>{this.handleNameInput(e)}} placeholder=${this.previousSuggestedName||`开发机`} autocomplete="off" />
|
|
1615
|
+
</label>
|
|
1616
|
+
<small class="hint">根据 URL 自动建议。可以改成更友好的侧栏名称。</small>
|
|
1617
|
+
<label>
|
|
1618
|
+
Bearer token <span class="optional">可选</span>
|
|
1619
|
+
<input name="token" type="password" .value=${this.token} @input=${e=>{this.handleTokenInput(e)}} placeholder="如果远程机器不需要 token,可留空" autocomplete="off" />
|
|
1620
|
+
</label>
|
|
1621
|
+
<small class="hint">只粘贴 token 值;PI WEB 会通过 Authorization: Bearer 请求头发送。</small>
|
|
1622
|
+
`:g`<p class="hint intro">输入 URL 后,PI WEB 会建议机器名称,并允许添加可选的 bearer token。</p>`}
|
|
1623
|
+
</div>
|
|
1624
|
+
<footer>
|
|
1625
|
+
<button type="button" @click=${()=>{this.onCancel?.()}}>取消</button>
|
|
1626
|
+
<button class="primary" type="submit" ?disabled=${!n}>${this.submitting?`正在添加…`:`添加机器`}</button>
|
|
1627
|
+
</footer>
|
|
1628
|
+
</form>
|
|
1629
|
+
</section>
|
|
1630
|
+
</div>
|
|
1631
|
+
`}static{this.styles=h`
|
|
1632
|
+
:host { position: fixed; inset: 0; z-index: 30; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
|
1633
|
+
.backdrop { display: grid; place-items: start center; width: 100%; height: 100%; padding-top: min(12vh, 90px); box-sizing: border-box; background: var(--pi-overlay); }
|
|
1634
|
+
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; }
|
|
1635
|
+
form { display: flex; flex-direction: column; max-height: inherit; min-height: 0; }
|
|
1636
|
+
header, footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px; border-bottom: 1px solid var(--pi-border); }
|
|
1637
|
+
footer { border-top: 1px solid var(--pi-border); border-bottom: 0; justify-content: end; }
|
|
1638
|
+
.body { display: grid; gap: 8px; padding: 12px; min-height: 0; overflow: auto; }
|
|
1639
|
+
label { display: grid; gap: 6px; color: var(--pi-muted); }
|
|
1640
|
+
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); }
|
|
1641
|
+
input:focus-visible { outline: 2px solid var(--pi-accent); outline-offset: 1px; }
|
|
1642
|
+
.hint { color: var(--pi-muted); }
|
|
1643
|
+
.intro { margin: 4px 0 0; line-height: 1.4; }
|
|
1644
|
+
.optional { color: var(--pi-muted); font-weight: 400; }
|
|
1645
|
+
.field-error { color: var(--pi-danger); }
|
|
1646
|
+
.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; }
|
|
1647
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
|
1648
|
+
header button { border: 0; background: transparent; color: var(--pi-muted); font-size: 22px; padding: 0 8px; }
|
|
1649
|
+
.primary { border-color: var(--pi-success-border); background: var(--pi-success-border); }
|
|
1650
|
+
button:disabled { opacity: .5; cursor: not-allowed; }
|
|
1651
|
+
`}};z([b({attribute:!1})],Py.prototype,`onSubmit`,void 0),z([b({attribute:!1})],Py.prototype,`onCancel`,void 0),z([b()],Py.prototype,`error`,void 0),z([x()],Py.prototype,`url`,void 0),z([x()],Py.prototype,`name`,void 0),z([x()],Py.prototype,`token`,void 0),z([x()],Py.prototype,`submitting`,void 0),z([S(`input[name='baseUrl']`)],Py.prototype,`urlInput`,void 0),z([S(`input[name='name']`)],Py.prototype,`nameInput`,void 0),Py=z([y(`machine-dialog`)],Py);function Fy(e){let t=e.trim();if(t===``)return``;let n=Ly(t)??Ly(`http://${t.replace(/^\/+/u,``)}`);return n!==void 0&&n.hostname!==``?n.hostname.replace(/^\[(.*)\]$/u,`$1`):Ry(t)}function Iy(e){let t=e.trim();if(t===``)return`必须填写远程 PI WEB URL。`;let n;try{n=new URL(t)}catch{return`请输入包含 http:// 或 https:// 的有效 URL。`}if(n.protocol!==`http:`&&n.protocol!==`https:`)return`请使用 http:// 或 https:// URL。`;if(n.username!==``||n.password!==``)return`机器 URL 中不要包含凭据。`;if(n.search!==``||n.hash!==``)return`不要包含查询字符串或片段。`}function Ly(e){try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`?t:void 0}catch{return}}function Ry(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 zy={availability:`error`,error:`error`,success:`success`,security:`warning`,warning:`warning`,info:`info`};function By(e){return e.tone??zy[e.type]}var Vy=class extends v{constructor(...e){super(...e),this.heading=``,this.description=``,this.actionLabel=``,this.actionTitle=``,this.actionDisabled=!1,this.notices=[]}render(){return g`
|
|
1652
|
+
<section class="panel" aria-label=${this.heading||`Settings panel`}>
|
|
1653
|
+
<header class="section-heading">
|
|
1654
|
+
<div class="heading-copy">
|
|
1655
|
+
${this.heading===``?_:g`<h2>${this.heading}</h2>`}
|
|
1656
|
+
<div class="description"><slot name="description">${this.description}</slot></div>
|
|
1657
|
+
</div>
|
|
1658
|
+
<div class="heading-actions"><slot name="actions">${this.renderDefaultAction()}</slot></div>
|
|
1659
|
+
</header>
|
|
1660
|
+
${this.renderNoticeStack()}
|
|
1661
|
+
<div class="content"><slot></slot></div>
|
|
1662
|
+
</section>
|
|
1663
|
+
`}renderDefaultAction(){return this.actionLabel===``?_:g`
|
|
1664
|
+
<button
|
|
1665
|
+
class="secondary"
|
|
1666
|
+
title=${this.actionTitle||this.actionLabel}
|
|
1667
|
+
?disabled=${this.actionDisabled}
|
|
1668
|
+
@click=${()=>{this.onAction?.()}}
|
|
1669
|
+
>${this.actionLabel}</button>
|
|
1670
|
+
`}renderNoticeStack(){return this.notices.length===0?_:g`
|
|
1671
|
+
<div class="notice-stack" aria-label="Settings notices">
|
|
1672
|
+
${this.notices.map(e=>this.renderNotice(e))}
|
|
1673
|
+
</div>
|
|
1674
|
+
`}renderNotice(e){let t=By(e),n=e.role??Hy(t),r=e.title;return g`
|
|
1675
|
+
<article class=${`notice ${t}`} role=${n}>
|
|
1676
|
+
${r===void 0||r===``?_:g`<strong class="notice-title">${r}</strong>`}
|
|
1677
|
+
<div class="notice-content">${e.content}</div>
|
|
1678
|
+
</article>
|
|
1679
|
+
`}static{this.styles=h`
|
|
1680
|
+
:host { display: block; }
|
|
1681
|
+
.panel { display: block; }
|
|
1682
|
+
.section-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
|
|
1683
|
+
.heading-copy { display: grid; gap: 6px; min-width: 0; }
|
|
1684
|
+
.heading-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
|
|
1685
|
+
h2 { margin: 0; font-size: 17px; line-height: 1.25; }
|
|
1686
|
+
.description { color: var(--pi-muted); line-height: 1.45; }
|
|
1687
|
+
.description ::slotted(*) { margin: 0; }
|
|
1688
|
+
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; }
|
|
1689
|
+
button:disabled { opacity: .55; cursor: not-allowed; }
|
|
1690
|
+
.secondary { flex: 0 0 auto; }
|
|
1691
|
+
.notice-stack { display: grid; gap: 12px; margin-bottom: 14px; }
|
|
1692
|
+
.notice { border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; line-height: 1.45; }
|
|
1693
|
+
.notice.error { border-color: var(--pi-danger); color: var(--pi-danger); background: color-mix(in srgb, var(--pi-danger) 10%, var(--pi-surface)); }
|
|
1694
|
+
.notice.success { border-color: var(--pi-success-border); color: var(--pi-success); background: var(--pi-success-surface); }
|
|
1695
|
+
.notice.warning { border-color: var(--pi-warning-border); color: var(--pi-text); background: var(--pi-warning-surface); }
|
|
1696
|
+
.notice.info { color: var(--pi-muted); }
|
|
1697
|
+
.notice-title { display: block; margin-bottom: 4px; color: inherit; }
|
|
1698
|
+
.notice-content { min-width: 0; }
|
|
1699
|
+
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; }
|
|
1700
|
+
.content { display: grid; gap: 14px; min-width: 0; }
|
|
1701
|
+
.content ::slotted(*) { min-width: 0; }
|
|
1702
|
+
|
|
1703
|
+
@media (max-width: 760px) {
|
|
1704
|
+
.section-heading { display: grid; gap: 12px; }
|
|
1705
|
+
.heading-actions { justify-self: start; }
|
|
1706
|
+
}
|
|
1707
|
+
`}};z([b()],Vy.prototype,`heading`,void 0),z([b({attribute:!1})],Vy.prototype,`description`,void 0),z([b()],Vy.prototype,`actionLabel`,void 0),z([b()],Vy.prototype,`actionTitle`,void 0),z([b({type:Boolean})],Vy.prototype,`actionDisabled`,void 0),z([b({attribute:!1})],Vy.prototype,`notices`,void 0),z([b({attribute:!1})],Vy.prototype,`onAction`,void 0),Vy=z([y(`settings-panel-frame`)],Vy);function Hy(e){switch(e){case`error`:return`alert`;case`success`:return`status`;case`warning`:case`info`:return`note`}}function Uy(){return{host:``,port:``,allowedHostsMode:`list`,allowedHostsText:``}}function Wy(){return{allowedPathsText:``,uploadDefaultFolder:``}}function Gy(){return{command:``,dir:``}}function Ky(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(`
|
|
1708
|
+
`):``}}function qy(e){return{allowedPathsText:e.pathAccess?.allowedPaths?.join(`
|
|
1709
|
+
`)??``,uploadDefaultFolder:e.uploads?.defaultFolder??``}}function Jy(e){return{command:e.agent?.command??``,dir:e.agent?.dir??``}}function Yy(e){let t=e.command.trim(),n=e.dir.trim();return{agent:{...t===``?{}:{command:t},...n===``?{}:{dir:n}}}}function Xy(e,t){let n=Yy(e).agent??{},r=t.agent??{};return n.command===r.command&&n.dir===r.dir}function Zy(e,t={}){let n=$y(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(`端口必须是 1 到 65535 之间的整数。`);n.port=e}return n.allowedHosts=e.allowedHostsMode===`all`||eb(e.allowedHostsText),n}function Qy(e){let t=tb(e.allowedPathsText),n=nb(e.uploadDefaultFolder);return{pathAccess:{allowedPaths:t},uploads:n===``?{}:{defaultFolder:n}}}function $y(e){return{...e.shortcuts===void 0?{}:{shortcuts:e.shortcuts},...e.plugins===void 0?{}:{plugins:e.plugins},...e.normalAuth===void 0?{}:{normalAuth:e.normalAuth},...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 eb(e){return e.split(/[\n,]/u).map(e=>e.trim()).filter(e=>e!==``)}function tb(e){let t=e.split(`
|
|
1710
|
+
`).map(e=>e.trim()).filter(e=>e!==``),n=t.find(e=>!rb(e));if(n!==void 0)throw Error(`Allowed external paths must be absolute paths or start with ~: ${n}`);return t}function nb(e){let t=e.trim();if(t===``)return``;if(ib(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 rb(e){return e===`~`||e.startsWith(`~/`)||e.startsWith(`~\\`)||e.startsWith(`/`)||e.startsWith(`\\`)||/^[A-Za-z]:[\\/]/u.test(e)}function ib(e){let t=e.replace(/\\/g,`/`);return t.startsWith(`/`)||/^[A-Za-z]:\//u.test(t)}function ab(e){return g`网关服务器字段用于编辑当前本地网关;文件访问和上传默认值用于编辑 ${e}。`}var J=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=Uy(),this.machineDraft=Wy(),this.gatewayLocalError=``,this.machineLocalError=``}willUpdate(e){e.has(`configResponse`)&&this.configResponse!==void 0&&(this.gatewayDraft=Ky(this.configResponse.config),this.gatewayLocalError=``),e.has(`machineConfigResponse`)&&this.machineConfigResponse!==void 0&&(this.machineDraft=qy(this.machineConfigResponse.config),this.machineLocalError=``)}render(){return g`
|
|
1711
|
+
<settings-panel-frame
|
|
1712
|
+
heading="通用配置"
|
|
1713
|
+
.description=${ab(this.targetLabel)}
|
|
1714
|
+
actionLabel="重新加载"
|
|
1715
|
+
.actionDisabled=${this.loading||this.machineLoading}
|
|
1716
|
+
.notices=${this.panelNotices()}
|
|
1717
|
+
.onAction=${()=>{this.reloadAll()}}
|
|
1718
|
+
>
|
|
1719
|
+
<div class="settings-sections">
|
|
1720
|
+
${this.renderGatewayServerSettings()}
|
|
1721
|
+
${this.renderSelectedMachineAccessSettings()}
|
|
1722
|
+
</div>
|
|
1723
|
+
</settings-panel-frame>
|
|
1724
|
+
`}renderGatewayServerSettings(){let e=this.configResponse;return g`
|
|
1725
|
+
<section class="settings-card" aria-label="网关服务器设置">
|
|
1726
|
+
<div class="card-heading">
|
|
1727
|
+
<h3>网关服务器</h3>
|
|
1728
|
+
<p>Host、端口和允许的 host 会保存到网关配置中。地址变更后必须重启 Web 服务,运行中的服务器才会绑定到新地址。</p>
|
|
1729
|
+
</div>
|
|
1730
|
+
${e===void 0&&this.loading?g`<div class="loading-card">正在加载网关配置…</div>`:g`
|
|
1731
|
+
<div class="config-path-card">
|
|
1732
|
+
<span>网关配置文件</span>
|
|
1733
|
+
<code>${e?.path??`未知`}</code>
|
|
1734
|
+
<small>${e?.exists===!0?`已有文件`:`保存时会创建此文件`}</small>
|
|
1735
|
+
</div>
|
|
1736
|
+
<form class="config-form" @submit=${e=>{this.saveGatewayConfig(e)}}>
|
|
1737
|
+
<label class="field">
|
|
1738
|
+
<span class="field-heading">
|
|
1739
|
+
<span>Host</span>
|
|
1740
|
+
${this.renderOverrideBadge(`host`)}
|
|
1741
|
+
</span>
|
|
1742
|
+
<input .value=${this.gatewayDraft.host} placeholder="127.0.0.1" autocomplete="off" spellcheck="false" @input=${e=>{this.updateGatewayDraft({host:cb(e)})}}>
|
|
1743
|
+
<small>Web 服务器应绑定的地址。留空则使用 PI WEB 默认值。</small>
|
|
1744
|
+
</label>
|
|
1745
|
+
|
|
1746
|
+
<label class="field">
|
|
1747
|
+
<span class="field-heading">
|
|
1748
|
+
<span>Port</span>
|
|
1749
|
+
${this.renderOverrideBadge(`port`)}
|
|
1750
|
+
</span>
|
|
1751
|
+
<input .value=${this.gatewayDraft.port} inputmode="numeric" pattern="[0-9]*" placeholder="8504" autocomplete="off" @input=${e=>{this.updateGatewayDraft({port:cb(e)})}}>
|
|
1752
|
+
<small>TCP 端口,范围 1 到 65535。留空则使用 PI WEB 默认值。</small>
|
|
1753
|
+
</label>
|
|
1754
|
+
|
|
1755
|
+
<div class="field">
|
|
1756
|
+
<span class="field-heading">
|
|
1757
|
+
<span>允许的 hosts</span>
|
|
1758
|
+
${this.renderOverrideBadge(`allowedHosts`)}
|
|
1759
|
+
</span>
|
|
1760
|
+
<select .value=${this.gatewayDraft.allowedHostsMode} @change=${e=>{this.updateGatewayDraft({allowedHostsMode:lb(e)===`all`?`all`:`list`})}}>
|
|
1761
|
+
<option value="list">仅允许列出的 hosts</option>
|
|
1762
|
+
<option value="all">允许所有 host</option>
|
|
1763
|
+
</select>
|
|
1764
|
+
<textarea .value=${this.gatewayDraft.allowedHostsText} ?disabled=${this.gatewayDraft.allowedHostsMode===`all`} rows="4" placeholder="example.local 192.168.1.20" spellcheck="false" @input=${e=>{this.updateGatewayDraft({allowedHostsText:ub(e)})}}></textarea>
|
|
1765
|
+
<small>每行输入一个 host,或选择“允许所有 host”写入 <code>true</code>。</small>
|
|
1766
|
+
</div>
|
|
1767
|
+
|
|
1768
|
+
${this.renderGatewayEffectiveConfig()}
|
|
1769
|
+
|
|
1770
|
+
<footer class="form-actions">
|
|
1771
|
+
<button class="primary" ?disabled=${this.loading||this.saving}>${this.saving?`正在保存…`:`保存网关服务器配置`}</button>
|
|
1772
|
+
</footer>
|
|
1773
|
+
</form>
|
|
1774
|
+
`}
|
|
1775
|
+
</section>
|
|
1776
|
+
`}renderSelectedMachineAccessSettings(){let e=this.machineConfigResponse;return g`
|
|
1777
|
+
<section class="settings-card" aria-label="所选机器的文件访问和上传设置">
|
|
1778
|
+
<div class="card-heading">
|
|
1779
|
+
<h3>所选机器的文件访问和上传</h3>
|
|
1780
|
+
<p>外部文件系统根目录和上传默认值会保存到 ${this.targetLabel}。</p>
|
|
1781
|
+
</div>
|
|
1782
|
+
${this.renderMachineMessages()}
|
|
1783
|
+
${e===void 0?g`<div class="loading-card">${this.machineLoading?`正在加载所选机器的文件访问配置…`:`所选机器的文件访问配置不可用。保存文件/上传设置前请重新加载。`}</div>`:g`
|
|
1784
|
+
<div class="config-path-card">
|
|
1785
|
+
<span>所选机器配置文件</span>
|
|
1786
|
+
<code>${e.path}</code>
|
|
1787
|
+
<small>${e.exists?`已有文件`:`保存时会创建此文件`}</small>
|
|
1788
|
+
</div>
|
|
1789
|
+
<form class="config-form" @submit=${e=>{this.saveMachineAccessConfig(e)}}>
|
|
1790
|
+
<label class="field">
|
|
1791
|
+
<span class="field-heading">
|
|
1792
|
+
<span>外部文件系统根目录</span>
|
|
1793
|
+
</span>
|
|
1794
|
+
<textarea .value=${this.machineDraft.allowedPathsText} rows="4" placeholder="~/SDKs /opt/reference" spellcheck="false" @input=${e=>{this.updateMachineDraft({allowedPathsText:ub(e)})}}></textarea>
|
|
1795
|
+
<small>${this.targetLabel} 上允许用于绝对路径 <code>@</code> 补全和工作区外文件读取的目录。每行输入一个绝对路径、Windows 绝对路径或以 <code>~</code> 开头的路径。留空则默认禁止外部路径。</small>
|
|
1796
|
+
</label>
|
|
1797
|
+
|
|
1798
|
+
<label class="field">
|
|
1799
|
+
<span class="field-heading">
|
|
1800
|
+
<span>默认上传文件夹</span>
|
|
1801
|
+
</span>
|
|
1802
|
+
<input .value=${this.machineDraft.uploadDefaultFolder} placeholder=${oa} autocomplete="off" spellcheck="false" @input=${e=>{this.updateMachineDraft({uploadDefaultFolder:cb(e)})}}>
|
|
1803
|
+
<small>${this.targetLabel} 上手动上传文件使用的工作区相对目录。留空则使用 PI WEB 默认值 <code>${oa}</code>。</small>
|
|
1804
|
+
</label>
|
|
1805
|
+
|
|
1806
|
+
${this.renderMachineEffectiveConfig()}
|
|
1807
|
+
|
|
1808
|
+
<footer class="form-actions">
|
|
1809
|
+
<button class="primary" ?disabled=${this.machineLoading||this.saving}>${this.saving?`正在保存…`:`保存文件/上传配置`}</button>
|
|
1810
|
+
</footer>
|
|
1811
|
+
</form>
|
|
1812
|
+
`}
|
|
1813
|
+
</section>
|
|
1814
|
+
`}panelNotices(){let e=[],t=this.gatewayLocalError||this.error;return t!==``&&e.push({type:`error`,title:`网关服务器`,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">环境变量覆盖</span>`:null}renderGatewayEffectiveConfig(){let e=this.configResponse?.effectiveConfig??{};return g`
|
|
1815
|
+
<section class="effective-card" aria-label="最终生效配置摘要">
|
|
1816
|
+
<h3>环境变量覆盖后的网关生效配置</h3>
|
|
1817
|
+
<dl>
|
|
1818
|
+
<div><dt>Host</dt><dd>${e.host??g`<span class="muted">默认 127.0.0.1</span>`}</dd></div>
|
|
1819
|
+
<div><dt>端口</dt><dd>${e.port??g`<span class="muted">默认 8504</span>`}</dd></div>
|
|
1820
|
+
<div><dt>允许的 hosts</dt><dd>${ob(e.allowedHosts)}</dd></div>
|
|
1821
|
+
</dl>
|
|
1822
|
+
</section>
|
|
1823
|
+
`}renderMachineEffectiveConfig(){let e=this.machineConfigResponse?.effectiveConfig??{};return g`
|
|
1824
|
+
<section class="effective-card" aria-label="所选机器最终生效的文件访问和上传摘要">
|
|
1825
|
+
<h3>所选机器的生效配置</h3>
|
|
1826
|
+
<dl>
|
|
1827
|
+
<div><dt>外部根目录</dt><dd>${sb(e.pathAccess?.allowedPaths)}</dd></div>
|
|
1828
|
+
<div><dt>上传文件夹</dt><dd>${e.uploads?.defaultFolder??g`<span class="muted">默认 ${`.pi-web/uploads`}</span>`}</dd></div>
|
|
1829
|
+
</dl>
|
|
1830
|
+
</section>
|
|
1831
|
+
`}reloadAll(){this.onReload?.(),this.onReloadMachine?.()}async saveGatewayConfig(e){e.preventDefault(),this.gatewayLocalError=``;try{await this.onSave?.(Zy(this.gatewayDraft,this.configResponse?.config??{}))}catch(e){this.gatewayLocalError=db(e)}}async saveMachineAccessConfig(e){e.preventDefault(),this.machineLocalError=``;try{await this.onSaveMachineConfig?.(Qy(this.machineDraft))}catch(e){this.machineLocalError=db(e)}}updateGatewayDraft(e){this.gatewayDraft={...this.gatewayDraft,...e},this.gatewayLocalError=``}updateMachineDraft(e){this.machineDraft={...this.machineDraft,...e},this.machineLocalError=``}static{this.styles=h`
|
|
1832
|
+
:host { display: block; }
|
|
1833
|
+
.card-heading { display: grid; gap: 6px; min-width: 0; }
|
|
1834
|
+
h3, p { margin: 0; }
|
|
1835
|
+
h3 { font-size: 13px; line-height: 1.3; }
|
|
1836
|
+
p { color: var(--pi-muted); line-height: 1.45; }
|
|
1837
|
+
button, input, select, textarea { font: inherit; }
|
|
1838
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
|
1839
|
+
button:disabled { opacity: .55; cursor: not-allowed; }
|
|
1840
|
+
.settings-sections { display: grid; gap: 14px; }
|
|
1841
|
+
.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; }
|
|
1842
|
+
.settings-card { display: grid; gap: 14px; }
|
|
1843
|
+
.message { margin-bottom: 12px; }
|
|
1844
|
+
.settings-card .message { margin-bottom: 0; }
|
|
1845
|
+
.error-message { border-color: var(--pi-danger); color: var(--pi-danger); background: color-mix(in srgb, var(--pi-danger) 10%, var(--pi-surface)); }
|
|
1846
|
+
.loading-card { color: var(--pi-muted); }
|
|
1847
|
+
.config-path-card { display: grid; gap: 5px; }
|
|
1848
|
+
.config-path-card span, .field-heading, dt { color: var(--pi-muted); font-size: 12px; font-weight: 700; text-transform: uppercase; }
|
|
1849
|
+
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; }
|
|
1850
|
+
.config-path-card small, .field small { color: var(--pi-muted); }
|
|
1851
|
+
.config-form { display: grid; gap: 14px; }
|
|
1852
|
+
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); }
|
|
1853
|
+
input:focus, select:focus, textarea:focus { border-color: var(--pi-accent); box-shadow: 0 0 0 1px var(--pi-accent-border); }
|
|
1854
|
+
textarea { resize: vertical; min-height: 94px; font-family: var(--pi-control-monospace-font-family, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); }
|
|
1855
|
+
textarea:disabled { opacity: .55; }
|
|
1856
|
+
.form-actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 2px; }
|
|
1857
|
+
.primary { border-color: var(--pi-accent); background: var(--pi-selection-bg); color: var(--pi-text-bright); }
|
|
1858
|
+
|
|
1859
|
+
@media (max-width: 760px) {
|
|
1860
|
+
.effective-card dl > div { grid-template-columns: minmax(0, 1fr); gap: 3px; }
|
|
1861
|
+
}
|
|
1862
|
+
`}};z([b({attribute:!1})],J.prototype,`configResponse`,void 0),z([b({attribute:!1})],J.prototype,`machineConfigResponse`,void 0),z([b({type:Boolean})],J.prototype,`loading`,void 0),z([b({type:Boolean})],J.prototype,`machineLoading`,void 0),z([b({type:Boolean})],J.prototype,`saving`,void 0),z([b()],J.prototype,`error`,void 0),z([b()],J.prototype,`machineError`,void 0),z([b()],J.prototype,`savedMessage`,void 0),z([b()],J.prototype,`targetLabel`,void 0),z([b({attribute:!1})],J.prototype,`onReload`,void 0),z([b({attribute:!1})],J.prototype,`onReloadMachine`,void 0),z([b({attribute:!1})],J.prototype,`onSave`,void 0),z([b({attribute:!1})],J.prototype,`onSaveMachineConfig`,void 0),z([x()],J.prototype,`gatewayDraft`,void 0),z([x()],J.prototype,`machineDraft`,void 0),z([x()],J.prototype,`gatewayLocalError`,void 0),z([x()],J.prototype,`machineLocalError`,void 0),J=z([y(`settings-general-panel`)],J);function ob(e){return e===!0?`任意 host`:Array.isArray(e)?e.length===0?g`<span class="muted">未列出</span>`:e.join(`, `):g`<span class="muted">未设置</span>`}function sb(e){return e===void 0||e.length===0?g`<span class="muted">已禁止外部路径</span>`:e.join(`, `)}function cb(e){return e.target instanceof HTMLInputElement?e.target.value:``}function lb(e){return e.target instanceof HTMLSelectElement?e.target.value:``}function ub(e){return e.target instanceof HTMLTextAreaElement?e.target.value:``}function db(e){return e instanceof Error?e.message:String(e)}function fb(e){return{spawnSessions:e}}function pb(e){return{subsessions:e}}function mb(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`,...Bt(n.command)?[`PI_CODING_AGENT_SESSION_DIR`]:[]];return n.command===t.command&&n.dir===t.dir&&_b(t.sessionDirEnvKeys,r)?`active`:`restart-required`}function hb(e,t){return e?.agentDirSource===`pi-web`?!0:e?.agentDirSource===`pi-compatibility`?Bt(t.trim()||`pi`):e?.agentDir===!0}function gb(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 _b(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}var vb=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=Gy(),this.agentDraftDirty=!1,this.agentLocalError=``}willUpdate(e){if(e.has(`configResponse`)){if(this.configResponse===void 0){this.agentDraft=Gy(),this.agentDraftDirty=!1,this.agentLocalError=``;return}(!this.agentDraftDirty||Xy(this.agentDraft,this.configResponse.config))&&(this.agentDraft=Jy(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=hb(e?.envOverrides,s),l=e?.envOverrides.agentDir===!0,u=e?.effectiveConfig.agent,d=mb(e,this.activeAgentProfile);return g`
|
|
1863
|
+
<settings-panel-frame
|
|
1864
|
+
heading="会话守护进程"
|
|
1865
|
+
.description=${Sb(this.targetLabel)}
|
|
1866
|
+
actionLabel="重新加载"
|
|
1867
|
+
.actionDisabled=${this.loading}
|
|
1868
|
+
.notices=${this.panelNotices(e)}
|
|
1869
|
+
.onAction=${this.onReload}
|
|
1870
|
+
>
|
|
1871
|
+
${e===void 0?this.renderUnavailableConfigState():g`
|
|
1872
|
+
<div class="config-path-card">
|
|
1873
|
+
<span>配置文件</span>
|
|
1874
|
+
<code>${e.path}</code>
|
|
1875
|
+
</div>
|
|
1876
|
+
<form class="profile-form" aria-label="Pi 兼容 Agent Profile" @submit=${e=>{this.saveAgentProfile(e)}}>
|
|
1877
|
+
${o?null:g`<div class="profile-support-message">${this.agentProfileSupport.message??`此机器不支持编辑 Pi 兼容 Agent Profile。`}</div>`}
|
|
1878
|
+
<label class="field">
|
|
1879
|
+
<span class="field-heading">
|
|
1880
|
+
<span>Companion CLI 命令</span>
|
|
1881
|
+
${a?g`<span class="override-badge">环境变量覆盖</span>`:null}
|
|
1882
|
+
</span>
|
|
1883
|
+
<input
|
|
1884
|
+
class="text-input"
|
|
1885
|
+
type="text"
|
|
1886
|
+
autocomplete="off"
|
|
1887
|
+
spellcheck="false"
|
|
1888
|
+
.value=${this.agentDraft.command}
|
|
1889
|
+
placeholder="pi"
|
|
1890
|
+
?disabled=${this.loading||this.saving||!o||a}
|
|
1891
|
+
@input=${e=>{this.updateAgentDraft({command:bb(e)})}}
|
|
1892
|
+
>
|
|
1893
|
+
<small>设置诊断和更新检查所用的 Pi 兼容 Companion CLI。内嵌会话运行时仍使用 PI WEB 捆绑的 Pi SDK。</small>
|
|
1894
|
+
</label>
|
|
1895
|
+
<label class="field">
|
|
1896
|
+
<span class="field-heading">
|
|
1897
|
+
<span>Profile 状态目录</span>
|
|
1898
|
+
${l?g`<span class="override-badge">环境变量覆盖</span>`:null}
|
|
1899
|
+
</span>
|
|
1900
|
+
<input
|
|
1901
|
+
class="text-input"
|
|
1902
|
+
type="text"
|
|
1903
|
+
autocomplete="off"
|
|
1904
|
+
spellcheck="false"
|
|
1905
|
+
.value=${this.agentDraft.dir}
|
|
1906
|
+
placeholder="~/.pi/agent or ~/agent-profiles/work"
|
|
1907
|
+
?disabled=${this.loading||this.saving||!o||c}
|
|
1908
|
+
@input=${e=>{this.updateAgentDraft({dir:bb(e)})}}
|
|
1909
|
+
>
|
|
1910
|
+
<small>选择 PI WEB 读取的 Pi 兼容认证、模型、设置和会话目录。备用命令会与其所需状态目录一并保存。</small>
|
|
1911
|
+
</label>
|
|
1912
|
+
<footer class="form-actions">
|
|
1913
|
+
<button class="primary" type="submit" ?disabled=${this.loading||this.saving||!o||a&&c}>${this.saving?`正在保存…`:`保存 Agent Profile`}</button>
|
|
1914
|
+
</footer>
|
|
1915
|
+
</form>
|
|
1916
|
+
<div class="field">
|
|
1917
|
+
<span class="field-heading">
|
|
1918
|
+
<span>允许代理启动会话</span>
|
|
1919
|
+
${t?g`<span class="override-badge">环境变量覆盖</span>`:null}
|
|
1920
|
+
</span>
|
|
1921
|
+
<label class="toggle">
|
|
1922
|
+
<input
|
|
1923
|
+
type="checkbox"
|
|
1924
|
+
.checked=${n}
|
|
1925
|
+
?disabled=${this.loading||this.saving||t}
|
|
1926
|
+
@change=${e=>{this.toggleSpawnSessions(e)}}
|
|
1927
|
+
>
|
|
1928
|
+
<span>启用 <code>spawn_session</code> 工具</span>
|
|
1929
|
+
</label>
|
|
1930
|
+
<small>启用后,LLM 可以启动新会话,但会被限制在同一个已注册项目的工作区(包括任意 worktree)内,因此每个派生会话都会显示在这里。默认启用。</small>
|
|
1931
|
+
</div>
|
|
1932
|
+
<div class="field">
|
|
1933
|
+
<span class="field-heading">
|
|
1934
|
+
<span>允许代理启动受跟踪的子会话</span>
|
|
1935
|
+
<span class="beta-badge">beta</span>
|
|
1936
|
+
${r?g`<span class="override-badge">环境变量覆盖</span>`:null}
|
|
1937
|
+
</span>
|
|
1938
|
+
<label class="toggle">
|
|
1939
|
+
<input
|
|
1940
|
+
type="checkbox"
|
|
1941
|
+
.checked=${i}
|
|
1942
|
+
?disabled=${this.loading||this.saving||r||!n}
|
|
1943
|
+
@change=${e=>{this.toggleSubsessions(e)}}
|
|
1944
|
+
>
|
|
1945
|
+
<span>启用 <code>spawn_subsession</code> 工具</span>
|
|
1946
|
+
</label>
|
|
1947
|
+
<small>Beta:代理可以启动自己持续关联的子会话(<code>spawn_subsession</code>、<code>list_subsessions</code>、<code>check_subsession</code>、<code>read_subsession</code>),并在子会话完成时收到通知。需要先启用“允许代理启动会话”。默认关闭。</small>
|
|
1948
|
+
</div>
|
|
1949
|
+
<section class="effective-card" aria-label="最终生效配置摘要">
|
|
1950
|
+
<h3>环境变量覆盖后的生效配置</h3>
|
|
1951
|
+
<dl>
|
|
1952
|
+
<div><dt>期望命令</dt><dd>${u?.command??g`<span class="muted">不可用</span>`}</dd></div>
|
|
1953
|
+
<div><dt>期望状态目录</dt><dd>${u?.dir??g`<span class="muted">不可用</span>`}</dd></div>
|
|
1954
|
+
<div><dt>当前命令</dt><dd>${this.activeAgentProfile?.command??g`<span class="muted">不可用</span>`}</dd></div>
|
|
1955
|
+
<div><dt>当前状态目录</dt><dd>${this.activeAgentProfile?.dir??g`<span class="muted">不可用</span>`}</dd></div>
|
|
1956
|
+
<div><dt>Profile 状态</dt><dd>${yb(d)}</dd></div>
|
|
1957
|
+
<div><dt>派生会话</dt><dd>${n?`已启用`:g`<span class="muted">已禁用</span>`}</dd></div>
|
|
1958
|
+
<div><dt>子会话</dt><dd>${i?`已启用`:g`<span class="muted">已禁用</span>`}</dd></div>
|
|
1959
|
+
</dl>
|
|
1960
|
+
</section>
|
|
1961
|
+
`}
|
|
1962
|
+
</settings-panel-frame>
|
|
1963
|
+
`}panelNotices(e){let t=[],n=this.agentLocalError||this.error;return n!==``&&t.push({type:`error`,content:n}),this.savedMessage!==``&&t.push({type:`success`,content:this.savedMessage}),mb(e,this.activeAgentProfile)===`restart-required`&&t.push({type:`warning`,title:`${this.targetLabel} 需要重启`,content:g`更改这些设置后,请在该机器上运行 <code>pi-web restart</code>,或重启其会话守护进程服务。`}),t}renderUnavailableConfigState(){return g`<div class="loading-card">${this.loading?`正在加载配置…`:`配置不可用,请重新加载。`}</div>`}async saveAgentProfile(e){e.preventDefault(),this.agentLocalError=``;try{await this.onSave?.(Yy(this.agentDraft))}catch(e){this.agentLocalError=xb(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?.(fb(t))}async toggleSubsessions(e){let t=e.target instanceof HTMLInputElement&&e.target.checked;await this.onSave?.(pb(t))}static{this.styles=h`
|
|
1964
|
+
:host { display: block; }
|
|
1965
|
+
h3 { margin: 0; font-size: 13px; line-height: 1.3; }
|
|
1966
|
+
button, input { font: inherit; }
|
|
1967
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
|
1968
|
+
button:disabled { opacity: .55; cursor: not-allowed; }
|
|
1969
|
+
.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; }
|
|
1970
|
+
.loading-card { color: var(--pi-muted); }
|
|
1971
|
+
.config-path-card { display: grid; gap: 5px; }
|
|
1972
|
+
.profile-form { display: grid; gap: 14px; }
|
|
1973
|
+
.profile-support-message { color: var(--pi-muted); line-height: 1.45; }
|
|
1974
|
+
.form-actions { display: flex; justify-content: flex-end; }
|
|
1975
|
+
.primary { border-color: var(--pi-accent); background: var(--pi-accent); color: var(--pi-accent-contrast); }
|
|
1976
|
+
.config-path-card span, .field-heading, dt { color: var(--pi-muted); font-size: 12px; font-weight: 700; text-transform: uppercase; }
|
|
1977
|
+
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; }
|
|
1978
|
+
.field { display: grid; gap: 7px; }
|
|
1979
|
+
.field small { color: var(--pi-muted); line-height: 1.45; }
|
|
1980
|
+
.field-heading { display: flex; align-items: center; gap: 8px; }
|
|
1981
|
+
.toggle { display: flex; align-items: center; gap: 9px; cursor: pointer; }
|
|
1982
|
+
.toggle input { width: 16px; height: 16px; }
|
|
1983
|
+
.text-input {
|
|
1984
|
+
width: 100%;
|
|
1985
|
+
min-width: 0;
|
|
1986
|
+
box-sizing: border-box;
|
|
1987
|
+
border: 1px solid var(--pi-border);
|
|
1988
|
+
border-radius: 8px;
|
|
1989
|
+
background: var(--pi-bg);
|
|
1990
|
+
color: var(--pi-text);
|
|
1991
|
+
padding: 8px 9px;
|
|
1992
|
+
outline: none;
|
|
1993
|
+
font: var(--pi-control-font-size, 16px) var(--pi-control-monospace-font-family, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
1994
|
+
}
|
|
1995
|
+
.text-input:focus { border-color: var(--pi-accent); box-shadow: 0 0 0 1px var(--pi-accent-border); }
|
|
1996
|
+
.text-input:disabled { opacity: .55; cursor: not-allowed; }
|
|
1997
|
+
.toggle input:disabled { cursor: not-allowed; }
|
|
1998
|
+
.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; }
|
|
1999
|
+
.effective-card { display: grid; gap: 10px; }
|
|
2000
|
+
.effective-card dl { display: grid; gap: 8px; margin: 0; }
|
|
2001
|
+
.effective-card dl > div { display: grid; grid-template-columns: 130px minmax(0, 1fr); gap: 12px; align-items: baseline; }
|
|
2002
|
+
dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
|
|
2003
|
+
.muted { color: var(--pi-muted); }
|
|
2004
|
+
|
|
2005
|
+
@media (max-width: 760px) {
|
|
2006
|
+
.effective-card dl > div { grid-template-columns: minmax(0, 1fr); gap: 3px; }
|
|
2007
|
+
}
|
|
2008
|
+
`}};z([b({attribute:!1})],vb.prototype,`configResponse`,void 0),z([b({type:Boolean})],vb.prototype,`loading`,void 0),z([b({type:Boolean})],vb.prototype,`saving`,void 0),z([b()],vb.prototype,`error`,void 0),z([b()],vb.prototype,`savedMessage`,void 0),z([b()],vb.prototype,`targetLabel`,void 0),z([b({attribute:!1})],vb.prototype,`activeAgentProfile`,void 0),z([b({attribute:!1})],vb.prototype,`agentProfileSupport`,void 0),z([b({attribute:!1})],vb.prototype,`onReload`,void 0),z([b({attribute:!1})],vb.prototype,`onSave`,void 0),z([x()],vb.prototype,`agentDraft`,void 0),z([x()],vb.prototype,`agentDraftDirty`,void 0),z([x()],vb.prototype,`agentLocalError`,void 0),vb=z([y(`settings-sessiond-panel`)],vb);function yb(e){return e===`active`?`已生效`:e===`restart-required`?`需要重启`:g`<span class="muted">不可用</span>`}function bb(e){return e.target instanceof HTMLInputElement?e.target.value:``}function xb(e){return e instanceof Error?e.message:String(e)}function Sb(e){return`这些设置会影响 ${e} 上长生命周期的会话运行时。更改会立即保存,但只有在该机器的会话守护进程重启后才会生效。`}function Cb(e){return e===void 0?{id:`local`,name:`local`,kind:`local`}:{id:e.id,name:e.name,kind:e.kind}}function wb(e){return e.kind===`local`?`${e.name} (local gateway)`:`${e.name} (remote machine)`}function Tb(e,t){return e.kind===`local`?{state:`supported`}:t?.ok===!0?en(t,M.piPackagesManage)?{state:`supported`}:{state:`unsupported`,message:Ob(e)}:{state:`unknown`}}function Eb(e){return`${e.state}:${e.message??``}`}function Db(e){return e?.state===`unsupported`}function Ob(e){return`Pi package management is not available on ${e.name}. Update and restart Pi-Web on that machine, then try again.`}function kb(e){return e.kind===`local`}function Ab(e){return e.trim()}function jb(e){if(Ab(e)===``)return`Enter a Pi package source accepted by Pi, such as npm:@scope/package, a git/URL source, or a local path.`}function Mb(e){return e.scope===`project`?`Project scope`:`User scope`}function Nb(e){return e.filtered?`Filtered by current Pi package settings`:`Available in this PI WEB process`}function Pb(e){return e.installedPath??`Installed path not reported by Pi`}function Fb(e){return e.scope===`user`}function Ib(e){if(!Fb(e))return`Project-scope Pi packages are listed for visibility, but PI WEB only updates user-scope Pi packages safely from this view.`}function Lb(e){return e.length>0&&e.every(Fb)}function Rb(e){if(e.length===0)return`No Pi packages are configured yet.`;if(!Lb(e))return`Update all is disabled while project-scope Pi packages are listed; update user-scope packages individually.`}function zb(e,t,n){return e?.kind===t?n===void 0||e.source===n:!1}function Bb(e,t=Cb(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 Vb(e,t){let n=e.trim();return t.kind===`remote`?Hb(n)?Ob(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 Hb(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=wb(t),r=this.packageManagementUnavailable,i=this.packagesResponse!==void 0&&!r;return g`
|
|
2009
|
+
<settings-panel-frame
|
|
2010
|
+
heading="Pi packages"
|
|
2011
|
+
.description=${Wb(n)}
|
|
2012
|
+
actionLabel="Reload"
|
|
2013
|
+
actionTitle=${r?this.packageManagementUnavailableMessage(n):`Reload Pi packages from ${n}`}
|
|
2014
|
+
.actionDisabled=${this.loading||this.isOperating||r}
|
|
2015
|
+
.notices=${this.panelNotices(n,i)}
|
|
2016
|
+
.onAction=${this.onReload}
|
|
2017
|
+
>
|
|
2018
|
+
${this.renderPanelContent(e,t,n)}
|
|
2019
|
+
</settings-panel-frame>
|
|
2020
|
+
`}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`
|
|
2021
|
+
${this.renderInstallForm(n)}
|
|
2022
|
+
${this.renderPackageList(e,t)}
|
|
2023
|
+
`}renderInstallForm(e){return g`
|
|
2024
|
+
<form class="install-card" @submit=${e=>{this.installPackage(e)}}>
|
|
2025
|
+
<label for="package-source">Pi package source</label>
|
|
2026
|
+
<div class="install-row">
|
|
2027
|
+
<input id="package-source" .value=${this.installSource} ?disabled=${this.isOperating} placeholder="npm:@scope/package, git URL, or local path" @input=${e=>{this.updateInstallSource(e)}}>
|
|
2028
|
+
<button type="submit" title="Install this Pi package" ?disabled=${this.isOperating}>${zb(this.operation,`install`)?`Installing…`:`Install`}</button>
|
|
2029
|
+
</div>
|
|
2030
|
+
${this.validationMessage===``?null:g`<div class="field-error">${this.validationMessage}</div>`}
|
|
2031
|
+
<small>Installs run on ${e} and use Pi's default package location, equivalent to <code>pi install <source></code>. PI WEB does not ask you to choose an install location.</small>
|
|
2032
|
+
</form>
|
|
2033
|
+
`}renderPackageList(e,t){let n=wb(t),r=this.packageManagementUnavailable?this.packageManagementUnavailableMessage(n):Rb(e),i=r!==void 0&&e.length>0;return g`
|
|
2034
|
+
<section class="package-section" aria-label="Configured Pi packages">
|
|
2035
|
+
<div class="package-toolbar">
|
|
2036
|
+
<div>
|
|
2037
|
+
<h3>Configured Pi packages</h3>
|
|
2038
|
+
<p>This list comes from Pi's package manager settings on ${n}.</p>
|
|
2039
|
+
</div>
|
|
2040
|
+
<button class="secondary" title=${r??`Update all user-scope Pi packages`} ?disabled=${this.isOperating||r!==void 0} @click=${()=>{this.updatePackage()}}>
|
|
2041
|
+
${zb(this.operation,`update-all`)?`Updating…`:`Update all`}
|
|
2042
|
+
</button>
|
|
2043
|
+
</div>
|
|
2044
|
+
${i?g`<div class="action-note">${r}</div>`:null}
|
|
2045
|
+
${this.loading&&e.length>0?g`<div class="action-note">Refreshing Pi packages from ${n}…</div>`:null}
|
|
2046
|
+
${this.renderPackageListContent(e,n)}
|
|
2047
|
+
</section>
|
|
2048
|
+
`}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`
|
|
2049
|
+
<div class="package-list">
|
|
2050
|
+
${e.map(e=>this.renderPackage(e))}
|
|
2051
|
+
</div>
|
|
2052
|
+
`}renderPackage(e){let t=wb(this.packageTarget),n=this.packageManagementUnavailable,r=n?this.packageManagementUnavailableMessage(t):Ib(e),i=n?this.packageManagementUnavailableMessage(t):`Remove this Pi package`,a=zb(this.operation,`update`,e.source),o=zb(this.operation,`remove`,e.source);return g`
|
|
2053
|
+
<article class=${`package-card${e.filtered?` filtered`:``}`}>
|
|
2054
|
+
<div class="package-main">
|
|
2055
|
+
<strong>${e.source}</strong>
|
|
2056
|
+
<small>${Mb(e)} · ${Nb(e)}</small>
|
|
2057
|
+
<small>Installed path: <code>${Pb(e)}</code></small>
|
|
2058
|
+
${r===void 0?null:g`<small class="action-note">${r}</small>`}
|
|
2059
|
+
</div>
|
|
2060
|
+
<div class="package-actions">
|
|
2061
|
+
<button class="secondary" title=${r??`Update this Pi package`} ?disabled=${this.isOperating||r!==void 0} @click=${()=>{this.updatePackage(e.source)}}>${a?`Updating…`:`Update`}</button>
|
|
2062
|
+
<button class="danger" title=${i} ?disabled=${this.isOperating||n} @click=${()=>{this.removePackage(e)}}>${o?`Removing…`:`Remove`}</button>
|
|
2063
|
+
</div>
|
|
2064
|
+
</article>
|
|
2065
|
+
`}updateInstallSource(e){this.installSource=e.target instanceof HTMLInputElement?e.target.value:``,this.validationMessage=``}async installPackage(e){e.preventDefault();let t=jb(this.installSource);if(t!==void 0){this.validationMessage=t;return}let n=Ab(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??Cb(void 0)}get packageManagementUnavailable(){return Db(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`
|
|
2066
|
+
:host { display: block; }
|
|
2067
|
+
.package-toolbar { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
|
|
2068
|
+
.package-toolbar > div, .package-main { display: grid; gap: 6px; min-width: 0; }
|
|
2069
|
+
h3, p { margin: 0; }
|
|
2070
|
+
h3 { font-size: 15px; line-height: 1.25; }
|
|
2071
|
+
p, small { color: var(--pi-muted); line-height: 1.45; }
|
|
2072
|
+
button, input { font: inherit; }
|
|
2073
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
|
2074
|
+
button:disabled, input:disabled { opacity: .55; cursor: not-allowed; }
|
|
2075
|
+
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; }
|
|
2076
|
+
label { font-weight: 700; }
|
|
2077
|
+
.secondary { flex: 0 0 auto; }
|
|
2078
|
+
.danger { border-color: color-mix(in srgb, var(--pi-danger) 55%, var(--pi-border)); color: var(--pi-danger); }
|
|
2079
|
+
.loading-card, .install-card, .package-card { border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; }
|
|
2080
|
+
.field-error { color: var(--pi-danger); font-size: 12px; }
|
|
2081
|
+
.install-card { display: grid; gap: 8px; }
|
|
2082
|
+
.install-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: center; }
|
|
2083
|
+
.package-section { display: block; }
|
|
2084
|
+
.loading-card, .action-note { color: var(--pi-muted); }
|
|
2085
|
+
.action-note { margin-bottom: 10px; font-size: 12px; }
|
|
2086
|
+
.package-list { display: grid; gap: 10px; }
|
|
2087
|
+
.package-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; }
|
|
2088
|
+
.package-card.filtered { opacity: .82; }
|
|
2089
|
+
.package-main strong, .package-main small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2090
|
+
.package-actions { display: flex; align-items: center; gap: 8px; }
|
|
2091
|
+
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; }
|
|
2092
|
+
|
|
2093
|
+
@media (max-width: 760px) {
|
|
2094
|
+
.package-toolbar { display: grid; gap: 12px; }
|
|
2095
|
+
.package-toolbar .secondary { justify-self: start; }
|
|
2096
|
+
.install-row, .package-card { grid-template-columns: minmax(0, 1fr); align-items: start; }
|
|
2097
|
+
.package-actions { justify-self: start; flex-wrap: wrap; }
|
|
2098
|
+
.package-main strong, .package-main small { white-space: normal; }
|
|
2099
|
+
}
|
|
2100
|
+
`}};z([b({attribute:!1})],Ub.prototype,`packagesResponse`,void 0),z([b({type:Boolean})],Ub.prototype,`loading`,void 0),z([b({attribute:!1})],Ub.prototype,`operation`,void 0),z([b({attribute:!1})],Ub.prototype,`targetMachine`,void 0),z([b({attribute:!1})],Ub.prototype,`managementSupport`,void 0),z([b()],Ub.prototype,`error`,void 0),z([b()],Ub.prototype,`operationMessage`,void 0),z([b({attribute:!1})],Ub.prototype,`onReload`,void 0),z([b({attribute:!1})],Ub.prototype,`onInstallPackage`,void 0),z([b({attribute:!1})],Ub.prototype,`onRemovePackage`,void 0),z([b({attribute:!1})],Ub.prototype,`onUpdatePackage`,void 0),z([x()],Ub.prototype,`installSource`,void 0),z([x()],Ub.prototype,`validationMessage`,void 0),Ub=z([y(`settings-packages-panel`)],Ub);function Wb(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 Gb=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`
|
|
2101
|
+
<settings-panel-frame
|
|
2102
|
+
heading="PI WEB 插件"
|
|
2103
|
+
.description=${Kb(this.targetLabel)}
|
|
2104
|
+
actionLabel="重新加载"
|
|
2105
|
+
actionTitle=${`从 ${this.targetLabel} 重新加载 PI WEB 插件`}
|
|
2106
|
+
.actionDisabled=${this.loading}
|
|
2107
|
+
.notices=${this.panelNotices(e.length>0)}
|
|
2108
|
+
.onAction=${this.onReload}
|
|
2109
|
+
>
|
|
2110
|
+
${this.renderPanelContent(e,t)}
|
|
2111
|
+
</settings-panel-frame>
|
|
2112
|
+
`}panelNotices(e){let t=[];return this.error!==``&&t.push({type:`error`,content:this.error}),this.shouldShowConfigUnavailableNotice(e)&&t.push({type:`availability`,content:`配置不可用。更改插件启用状态前请重新加载。`}),this.savedMessage!==``&&t.push({type:`success`,content:`${this.savedMessage} 重新加载浏览器标签页以应用插件更改。`}),e&&t.push({type:`security`,content:g`<strong>受信代码警告:</strong>PI WEB 插件和 Pi 包可使用你的用户权限运行。请仅启用可信来源的插件。`}),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">在 ${this.targetLabel} 上未发现 PI WEB 浏览器插件。</div>`:g`
|
|
2113
|
+
<div class="plugin-note">${this.targetLabel} 上的配置键:<code>plugins</code>。除非条目将 <code>enabled</code> 设为 <code>false</code>,插件默认启用。</div>
|
|
2114
|
+
<div class="plugin-list">
|
|
2115
|
+
${e.map(e=>this.renderPlugin(e))}
|
|
2116
|
+
</div>
|
|
2117
|
+
`:g`<div class="loading-card">${this.loading?`正在加载 PI WEB 插件…`:`${this.targetLabel} 的 PI WEB 插件列表不可用,请重新加载。`}</div>`}renderPlugin(e){let t=this.configResponse?.config.plugins?.[e.id],n=t?.enabled===!1?`配置已禁用`:t?.enabled===!0?`配置已启用`:`默认启用`;return g`
|
|
2118
|
+
<article class=${`plugin-card${e.enabled?``:` disabled`}`}>
|
|
2119
|
+
<div class="plugin-main">
|
|
2120
|
+
<strong>${e.id}</strong>
|
|
2121
|
+
<small>${e.source} · ${e.scope}${e.machineSpecific?` · machine-specific`:``}</small>
|
|
2122
|
+
<small>${n}</small>
|
|
2123
|
+
</div>
|
|
2124
|
+
<label class="toggle">
|
|
2125
|
+
<input type="checkbox" .checked=${e.enabled} ?disabled=${this.saving||this.configResponse===void 0} @change=${t=>{this.togglePlugin(e,t)}}>
|
|
2126
|
+
<span>${e.enabled?`已启用`:`已禁用`}</span>
|
|
2127
|
+
</label>
|
|
2128
|
+
</article>
|
|
2129
|
+
`}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`
|
|
2130
|
+
:host { display: block; }
|
|
2131
|
+
input { font: inherit; }
|
|
2132
|
+
input:disabled { opacity: .55; cursor: not-allowed; }
|
|
2133
|
+
.loading-card, .plugin-note, .plugin-card { border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; }
|
|
2134
|
+
.loading-card, .plugin-note { color: var(--pi-muted); }
|
|
2135
|
+
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; }
|
|
2136
|
+
.plugin-list { display: grid; gap: 10px; }
|
|
2137
|
+
.plugin-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; }
|
|
2138
|
+
.plugin-card.disabled { opacity: .75; }
|
|
2139
|
+
.plugin-main { min-width: 0; display: grid; gap: 3px; }
|
|
2140
|
+
.plugin-main strong, .plugin-main small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2141
|
+
.plugin-main small { color: var(--pi-muted); }
|
|
2142
|
+
.toggle { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
|
|
2143
|
+
.toggle input { width: 18px; height: 18px; accent-color: var(--pi-accent); }
|
|
2144
|
+
|
|
2145
|
+
@media (max-width: 760px) {
|
|
2146
|
+
.plugin-card { grid-template-columns: minmax(0, 1fr); align-items: start; }
|
|
2147
|
+
.toggle { justify-self: start; }
|
|
2148
|
+
}
|
|
2149
|
+
`}};z([b({attribute:!1})],Gb.prototype,`pluginsResponse`,void 0),z([b({attribute:!1})],Gb.prototype,`configResponse`,void 0),z([b({type:Boolean})],Gb.prototype,`loading`,void 0),z([b({type:Boolean})],Gb.prototype,`saving`,void 0),z([b()],Gb.prototype,`error`,void 0),z([b()],Gb.prototype,`savedMessage`,void 0),z([b()],Gb.prototype,`targetLabel`,void 0),z([b({attribute:!1})],Gb.prototype,`onReload`,void 0),z([b({attribute:!1})],Gb.prototype,`onTogglePlugin`,void 0),Gb=z([y(`settings-plugins-panel`)],Gb);function Kb(e){return g`启用或禁用 <strong>${e}</strong> 上发现的 PI WEB 浏览器插件。这与安装 Pi 包相互独立;请重新加载浏览器标签页以应用插件运行时更改。`}var qb={capture:!0},Jb=[{value:`auto`,label:`自动/默认`,description:`桌面环境按 Enter 发送;移动设备、粗略指针或窄屏环境按 Enter 换行。`},{value:`send`,label:`Enter 发送消息`,description:`Enter 发送聊天消息;支持时 Shift+Enter 插入新行。`},{value:`newline`,label:`Enter 插入新行`,description:`Enter 插入换行;支持时 Shift+Enter 发送聊天消息。`}];function Yb(){return g`按操作编辑应用快捷键。输入 <code>mod+k</code> 或 <code>mod+g p</code> 这类快捷键,也可以从键盘录制、设为无或恢复默认。快捷键冲突时,自定义快捷键优先于默认值;同级按 action id 排序,较短快捷键会遮蔽相同前缀的较长序列。`}var Xb=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=Bv(),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=ru(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&&!iu(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=ex(this.actions),t=this.shortcutResolutions();return g`
|
|
2150
|
+
<settings-panel-frame
|
|
2151
|
+
heading="键盘快捷键"
|
|
2152
|
+
.description=${Yb()}
|
|
2153
|
+
actionLabel="重新加载"
|
|
2154
|
+
.actionDisabled=${this.loading}
|
|
2155
|
+
.notices=${this.panelNotices()}
|
|
2156
|
+
.onAction=${this.onReload}
|
|
2157
|
+
>
|
|
2158
|
+
${this.renderPromptEnterPreferenceCard()}
|
|
2159
|
+
${this.configResponse===void 0&&this.loading?g`<div class="loading-card">正在加载快捷键…</div>`:g`
|
|
2160
|
+
<div class="config-path-card">
|
|
2161
|
+
<span>配置文件</span>
|
|
2162
|
+
<code>${this.configResponse?.path??`未知`}</code>
|
|
2163
|
+
<small>快捷键覆盖项保存在 <code>shortcuts</code> 下。值为 <code>null</code> 时会禁用该操作快捷键。</small>
|
|
2164
|
+
</div>
|
|
2165
|
+
${e.length===0?g`<div class="loading-card">没有已注册操作。</div>`:e.map(e=>g`
|
|
2166
|
+
<section class="shortcut-group">
|
|
2167
|
+
<h3>${e.name}</h3>
|
|
2168
|
+
<div class="shortcut-list">
|
|
2169
|
+
${e.actions.map(e=>this.renderShortcutRow(e,t.get(e.id)))}
|
|
2170
|
+
</div>
|
|
2171
|
+
</section>
|
|
2172
|
+
`)}
|
|
2173
|
+
`}
|
|
2174
|
+
</settings-panel-frame>
|
|
2175
|
+
`}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`
|
|
2176
|
+
<section class="prompt-enter-card" aria-labelledby="prompt-enter-preference-title">
|
|
2177
|
+
<div class="prompt-enter-copy">
|
|
2178
|
+
<span class="card-eyebrow">聊天输入框</span>
|
|
2179
|
+
<h3 id="prompt-enter-preference-title">Enter 键行为</h3>
|
|
2180
|
+
<p>选择当前浏览器中 Enter 键的行为。支持时 Shift+Enter 执行相反操作;为避免误发送,会忽略触摸键盘的自动大写状态。</p>
|
|
2181
|
+
</div>
|
|
2182
|
+
<div class="prompt-enter-options" role="radiogroup" aria-label="聊天输入框中的 Enter 和 Shift Enter 行为">
|
|
2183
|
+
${Jb.map(e=>g`
|
|
2184
|
+
<label class="prompt-enter-option">
|
|
2185
|
+
<input
|
|
2186
|
+
type="radio"
|
|
2187
|
+
name="prompt-enter-preference"
|
|
2188
|
+
.value=${e.value}
|
|
2189
|
+
.checked=${this.promptEnterPreference===e.value}
|
|
2190
|
+
@change=${()=>{this.updatePromptEnterPreference(e.value)}}
|
|
2191
|
+
>
|
|
2192
|
+
<span>
|
|
2193
|
+
<strong>${e.label}</strong>
|
|
2194
|
+
<small>${e.description}</small>
|
|
2195
|
+
</span>
|
|
2196
|
+
</label>
|
|
2197
|
+
`)}
|
|
2198
|
+
</div>
|
|
2199
|
+
</section>
|
|
2200
|
+
`}updatePromptEnterPreference(e){this.promptEnterPreference=e,Vv(e)}renderShortcutRow(e,t){let n=this.configResponse?.config.shortcuts,r=nx(e.id,n),i=ax(e,n),a=this.shortcutInputText(e),o=a.trim()===``?void 0:eu(a),s=o?.ok===!0?o.shortcut:ix(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=$b(t);return g`
|
|
2201
|
+
<article class=${Zb(t)}>
|
|
2202
|
+
<div class="shortcut-main">
|
|
2203
|
+
<strong>${e.title}</strong>
|
|
2204
|
+
${e.description!==void 0&&e.description!==``?g`<small>${e.description}</small>`:null}
|
|
2205
|
+
<small class="shortcut-id">${e.id}</small>
|
|
2206
|
+
<small>${e.shortcut!==void 0&&e.shortcut!==``?g`Default: <kbd>${nu(e.shortcut)}</kbd>`:`No default shortcut`}</small>
|
|
2207
|
+
</div>
|
|
2208
|
+
<div class="shortcut-editor">
|
|
2209
|
+
<div class="shortcut-status">
|
|
2210
|
+
${s!==void 0&&s!==``?g`<kbd>${nu(s)}</kbd>`:g`<span class="unassigned">${i===`disabled`?`已禁用`:`未分配`}</span>`}
|
|
2211
|
+
<small class=${u}>${ox(u)}${l?` · 未保存`:``}</small>
|
|
2212
|
+
${f===void 0?null:g`<small class=${Qb(t)}>${f}</small>`}
|
|
2213
|
+
</div>
|
|
2214
|
+
<label class="shortcut-input-label">
|
|
2215
|
+
<span>快捷键</span>
|
|
2216
|
+
<input
|
|
2217
|
+
class="shortcut-input"
|
|
2218
|
+
data-action-id=${e.id}
|
|
2219
|
+
.value=${a}
|
|
2220
|
+
placeholder=${e.shortcut??`mod+k`}
|
|
2221
|
+
autocomplete="off"
|
|
2222
|
+
autocapitalize="off"
|
|
2223
|
+
spellcheck="false"
|
|
2224
|
+
?disabled=${this.saving}
|
|
2225
|
+
@input=${t=>{this.updateDraft(e.id,sx(t))}}
|
|
2226
|
+
>
|
|
2227
|
+
</label>
|
|
2228
|
+
${d===``?null:g`<small class="recording-hint">${d}</small>`}
|
|
2229
|
+
<div class="shortcut-actions">
|
|
2230
|
+
<button class="primary" ?disabled=${this.loading||this.saving||!l||a.trim()===``} @click=${()=>{this.saveShortcut(e)}}>保存</button>
|
|
2231
|
+
<button ?disabled=${this.loading||this.saving} @click=${()=>{this.toggleRecording(e.id)}}>${this.recording?.actionId===e.id?`取消录制`:`录制`}</button>
|
|
2232
|
+
<button ?disabled=${this.loading||this.saving||r===null} @click=${()=>{this.setShortcutNone(e.id)}}>无</button>
|
|
2233
|
+
<button ?disabled=${this.loading||this.saving||!c} @click=${()=>{this.resetShortcut(e.id)}}>重置</button>
|
|
2234
|
+
</div>
|
|
2235
|
+
</div>
|
|
2236
|
+
</article>
|
|
2237
|
+
`}shortcutInputText(e){let t=this.drafts[e.id];if(t!==void 0)return t;let n=nx(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: ${nu(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=eu(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?rx(r,e):{...r,[e]:t};Object.keys(i).length===0?delete n.shortcuts:n.shortcuts=i,await this.onSave?.(n)}shortcutResolutions(){return new Map($l(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=eu(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()},Xl)}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,qb),!0)}removeRecordingListener(){this.recordingListenerActive&&=(window.removeEventListener(`keydown`,this.onRecordKeyDown,qb),!1)}static{this.styles=h`
|
|
2238
|
+
:host { display: block; }
|
|
2239
|
+
h3, p { margin: 0; }
|
|
2240
|
+
h3 { font-size: 13px; line-height: 1.3; }
|
|
2241
|
+
p { color: var(--pi-muted); line-height: 1.45; }
|
|
2242
|
+
button, input { font: inherit; }
|
|
2243
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
|
2244
|
+
button:disabled, input:disabled { opacity: .55; cursor: not-allowed; }
|
|
2245
|
+
.primary { border-color: var(--pi-accent); background: var(--pi-selection-bg); color: var(--pi-text-bright); }
|
|
2246
|
+
.loading-card, .config-path-card, .prompt-enter-card { border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; }
|
|
2247
|
+
.loading-card, .config-path-card { color: var(--pi-muted); }
|
|
2248
|
+
.config-path-card { display: grid; gap: 5px; }
|
|
2249
|
+
.config-path-card span, .card-eyebrow { color: var(--pi-muted); font-size: 12px; font-weight: 700; text-transform: uppercase; }
|
|
2250
|
+
.prompt-enter-card { display: grid; grid-template-columns: minmax(0, .85fr) minmax(260px, 1fr); gap: 12px; align-items: start; }
|
|
2251
|
+
.prompt-enter-copy { display: grid; gap: 5px; min-width: 0; }
|
|
2252
|
+
.prompt-enter-copy p, .prompt-enter-option small { font-size: 12px; }
|
|
2253
|
+
.prompt-enter-options { display: grid; gap: 7px; }
|
|
2254
|
+
.prompt-enter-option { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px; align-items: start; color: var(--pi-text); }
|
|
2255
|
+
.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; }
|
|
2256
|
+
.prompt-enter-option input:focus { border-color: transparent; box-shadow: none; outline: 2px solid var(--pi-accent-border); outline-offset: 2px; }
|
|
2257
|
+
.prompt-enter-option span { display: grid; gap: 2px; }
|
|
2258
|
+
.prompt-enter-option small { color: var(--pi-muted); line-height: 1.35; }
|
|
2259
|
+
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; }
|
|
2260
|
+
.shortcut-group { margin: 0; }
|
|
2261
|
+
.shortcut-group h3 { margin: 0 0 8px; color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
|
|
2262
|
+
.shortcut-list { border: 1px solid var(--pi-border); border-radius: 10px; overflow: hidden; }
|
|
2263
|
+
.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); }
|
|
2264
|
+
.shortcut-row.shadowed { background: color-mix(in srgb, var(--pi-warning) 5%, var(--pi-surface)); }
|
|
2265
|
+
.shortcut-row.shadowing { background: color-mix(in srgb, var(--pi-accent) 5%, var(--pi-surface)); }
|
|
2266
|
+
.shortcut-row:last-child { border-bottom: 0; }
|
|
2267
|
+
.shortcut-main { min-width: 0; display: grid; gap: 4px; }
|
|
2268
|
+
.shortcut-main strong, .shortcut-main small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2269
|
+
.shortcut-main small { color: var(--pi-muted); }
|
|
2270
|
+
.shortcut-id { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
|
2271
|
+
.shortcut-editor { min-width: 0; display: grid; gap: 8px; }
|
|
2272
|
+
.shortcut-status { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
|
|
2273
|
+
.shortcut-status small { color: var(--pi-muted); font-size: 11px; }
|
|
2274
|
+
.shortcut-status small.custom { color: var(--pi-accent); }
|
|
2275
|
+
.shortcut-status small.disabled { color: var(--pi-warning); }
|
|
2276
|
+
.shortcut-status small.conflict { border: 1px solid currentColor; border-radius: 999px; padding: 2px 7px; }
|
|
2277
|
+
.shortcut-status small.conflict.shadowing { color: var(--pi-accent); }
|
|
2278
|
+
.shortcut-status small.conflict.shadowed { color: var(--pi-warning); }
|
|
2279
|
+
.shortcut-input-label { min-width: 0; display: grid; gap: 5px; }
|
|
2280
|
+
.shortcut-input-label span { color: var(--pi-muted); font-size: 11px; font-weight: 700; text-transform: uppercase; }
|
|
2281
|
+
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); }
|
|
2282
|
+
input:focus { border-color: var(--pi-accent); box-shadow: 0 0 0 1px var(--pi-accent-border); }
|
|
2283
|
+
.shortcut-actions { display: flex; justify-content: flex-end; gap: 7px; flex-wrap: wrap; }
|
|
2284
|
+
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; }
|
|
2285
|
+
.unassigned { color: var(--pi-muted); font-size: 12px; }
|
|
2286
|
+
.recording-hint { color: var(--pi-accent); font-size: 12px; }
|
|
2287
|
+
|
|
2288
|
+
@media (max-width: 760px) {
|
|
2289
|
+
.prompt-enter-card { grid-template-columns: minmax(0, 1fr); }
|
|
2290
|
+
.shortcut-row { grid-template-columns: minmax(0, 1fr); align-items: start; }
|
|
2291
|
+
.shortcut-status, .shortcut-actions { justify-content: flex-start; }
|
|
2292
|
+
}
|
|
2293
|
+
`}};z([b({attribute:!1})],Xb.prototype,`actions`,void 0),z([b({attribute:!1})],Xb.prototype,`configResponse`,void 0),z([b({type:Boolean})],Xb.prototype,`loading`,void 0),z([b({type:Boolean})],Xb.prototype,`saving`,void 0),z([b()],Xb.prototype,`error`,void 0),z([b()],Xb.prototype,`savedMessage`,void 0),z([b({attribute:!1})],Xb.prototype,`onReload`,void 0),z([b({attribute:!1})],Xb.prototype,`onSave`,void 0),z([x()],Xb.prototype,`drafts`,void 0),z([x()],Xb.prototype,`localError`,void 0),z([x()],Xb.prototype,`promptEnterPreference`,void 0),z([x()],Xb.prototype,`recording`,void 0),Xb=z([y(`settings-shortcuts-panel`)],Xb);function Zb(e){return e?.active===!1?`shortcut-row shadowed`:e?.active===!0&&e.shadows.length>0?`shortcut-row shadowing`:`shortcut-row`}function Qb(e){return e?.active===!1?`conflict shadowed`:`conflict shadowing`}function $b(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 ex(e){let t=new Map;for(let n of[...e].sort(tx)){let e=n.group??`其他`;t.set(e,[...t.get(e)??[],n])}return[...t.entries()].map(([e,t])=>({name:e,actions:t}))}function tx(e,t){return(e.group??`其他`).localeCompare(t.group??`其他`)||e.title.localeCompare(t.title)}function nx(e,t){if(!(t===void 0||!Object.hasOwn(t,e)))return t[e]}function rx(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>e!==t))}function ix(e,t){let n=nx(e.id,t);if(n!==null)return n??e.shortcut}function ax(e,t){let n=nx(e.id,t);return n===null?`disabled`:n===void 0?e.shortcut===void 0||e.shortcut===``?`unassigned`:`default`:`custom`}function ox(e){switch(e){case`default`:return`默认`;case`custom`:return`配置覆盖`;case`disabled`:return`配置禁用`;case`unassigned`:return`无默认值`}}function sx(e){return e.target instanceof HTMLInputElement?e.target.value:``}async function cx(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: ${ux(t.reason)}`),n.status===`fulfilled`?r.plugins=n.value:i.push(`PI WEB plugins: ${ux(n.reason)}`),i.length>0&&(r.error=`Failed to load settings: ${i.join(`; `)}`),r}async function lx(e,t,n){if(Db(n))return{error:n.message??`Pi package management is not available on ${wb(e)}.`,skipped:!0};try{return{packagesResponse:await t(e.id),error:``}}catch(t){return{error:`Failed to load Pi packages from ${wb(e)}: ${Vb(ux(t),e)}`}}}function ux(e){return e instanceof Error?e.message:String(e)}function dx(e,t){return{...e,config:fx(e.config,t.config),effectiveConfig:fx(e.effectiveConfig,t.effectiveConfig)}}function fx(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 px(e){return e===void 0?{id:`local`,name:`local`,kind:`local`}:{id:e.id,name:e.name,kind:e.kind}}function Y(e){return e.kind===`local`?`${e.name} (local gateway)`:`${e.name} (remote machine)`}function mx(e,t){return e.kind===`local`?{state:`supported`}:t?.ok===!0?en(t,M.selectedMachineSettings)?{state:`supported`}:{state:`unsupported`,message:yx(e)}:{state:`unknown`}}function hx(e,t){return e.kind===`local`?{state:`supported`}:t?.ok===!0?en(t,M.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 gx(e){return`${e.state}:${e.message??``}`}function _x(e){return e?.state===`unsupported`}function vx(e){return e?.state===`supported`}function yx(e){return`Selected-machine settings are not available on ${e.name}. Update and restart PI WEB on that machine, then try again.`}function bx(e,t){let n=e.trim();return t.kind===`remote`?xx(n)?yx(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 xx(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 Sx(e,t,n){let r=e.plugins??{},i=r[t]??{};return{plugins:{...r,[t]:{...i,enabled:n}}}}function Cx(e,t){return{...e,config:wx(e.config,t.config),effectiveConfig:wx(e.effectiveConfig,t.effectiveConfig)}}function wx(e,t){return t.plugins===void 0?e:{...e,plugins:t.plugins}}var X=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`)&&px(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`
|
|
2294
|
+
<div class="backdrop" @mousedown=${()=>this.onClose?.()}>
|
|
2295
|
+
<section class="settings-shell" role="dialog" aria-modal="true" aria-label="PI WEB 设置" @mousedown=${e=>{e.stopPropagation()}} @keydown=${e=>{this.handleKeyDown(e)}}>
|
|
2296
|
+
<header class="settings-header">
|
|
2297
|
+
<div>
|
|
2298
|
+
<span class="eyebrow">设置</span>
|
|
2299
|
+
<h1>PI WEB</h1>
|
|
2300
|
+
</div>
|
|
2301
|
+
<button class="close-button" title="关闭设置" aria-label="关闭设置" @click=${()=>this.onClose?.()}>×</button>
|
|
2302
|
+
</header>
|
|
2303
|
+
<div class="settings-body">
|
|
2304
|
+
<nav class="settings-nav" aria-label="设置分区">
|
|
2305
|
+
${this.renderNavButton(`general`,`通用`,`网关与所选机器`)}
|
|
2306
|
+
${this.renderNavButton(`sessiond`,`会话守护进程`,`所选机器`)}
|
|
2307
|
+
${this.renderNavButton(`packages`,`Pi 包`,`所选机器`)}
|
|
2308
|
+
${this.renderNavButton(`plugins`,`PI WEB 插件`,`所选机器`)}
|
|
2309
|
+
${this.renderNavButton(`shortcuts`,`键盘`,`网关快捷键`)}
|
|
2310
|
+
</nav>
|
|
2311
|
+
<main class="settings-content">
|
|
2312
|
+
${this.renderActiveSection()}
|
|
2313
|
+
</main>
|
|
2314
|
+
</div>
|
|
2315
|
+
</section>
|
|
2316
|
+
</div>
|
|
2317
|
+
`}renderActiveSection(){return this.section===`sessiond`?g`
|
|
2318
|
+
<settings-sessiond-panel
|
|
2319
|
+
.configResponse=${this.sessiondConfigResponse}
|
|
2320
|
+
.loading=${this.sessiondLoading}
|
|
2321
|
+
.saving=${this.saving}
|
|
2322
|
+
.error=${this.sessiondError}
|
|
2323
|
+
.savedMessage=${this.savedMessage}
|
|
2324
|
+
.targetLabel=${Y(this.settingsTarget())}
|
|
2325
|
+
.activeAgentProfile=${this.machineRuntime?.components?.sessiond.activeAgentProfile}
|
|
2326
|
+
.agentProfileSupport=${this.agentProfileSettingsSupport()}
|
|
2327
|
+
.onReload=${()=>this.reloadSessiondState()}
|
|
2328
|
+
.onSave=${e=>this.saveSessiondConfig(e)}
|
|
2329
|
+
></settings-sessiond-panel>
|
|
2330
|
+
`:this.section===`shortcuts`?g`
|
|
2331
|
+
<settings-shortcuts-panel
|
|
2332
|
+
.actions=${this.actions}
|
|
2333
|
+
.configResponse=${this.configResponse}
|
|
2334
|
+
.loading=${this.loading}
|
|
2335
|
+
.saving=${this.saving}
|
|
2336
|
+
.error=${this.error}
|
|
2337
|
+
.savedMessage=${this.savedMessage}
|
|
2338
|
+
.onReload=${()=>this.loadConfig()}
|
|
2339
|
+
.onSave=${e=>this.saveConfig(e)}
|
|
2340
|
+
></settings-shortcuts-panel>
|
|
2341
|
+
`:this.section===`packages`?g`
|
|
2342
|
+
<settings-packages-panel
|
|
2343
|
+
.packagesResponse=${this.packagesResponse}
|
|
2344
|
+
.targetMachine=${this.packageTarget()}
|
|
2345
|
+
.managementSupport=${this.packageManagementSupport()}
|
|
2346
|
+
.loading=${this.packageLoading}
|
|
2347
|
+
.operation=${this.packageOperation}
|
|
2348
|
+
.error=${this.packageError}
|
|
2349
|
+
.operationMessage=${this.packageMessage}
|
|
2350
|
+
.onReload=${()=>this.loadPackagesForTarget()}
|
|
2351
|
+
.onInstallPackage=${e=>this.installPiPackage(e)}
|
|
2352
|
+
.onRemovePackage=${(e,t)=>this.removePiPackage(e,t)}
|
|
2353
|
+
.onUpdatePackage=${e=>this.updatePiPackage(e)}
|
|
2354
|
+
></settings-packages-panel>
|
|
2355
|
+
`:this.section===`plugins`?g`
|
|
2356
|
+
<settings-plugins-panel
|
|
2357
|
+
.configResponse=${this.selectedPluginConfigResponse}
|
|
2358
|
+
.pluginsResponse=${this.selectedPluginsResponse}
|
|
2359
|
+
.loading=${this.pluginLoading}
|
|
2360
|
+
.saving=${this.saving}
|
|
2361
|
+
.error=${this.pluginError}
|
|
2362
|
+
.savedMessage=${this.savedMessage}
|
|
2363
|
+
.targetLabel=${Y(this.settingsTarget())}
|
|
2364
|
+
.onReload=${()=>this.loadPluginsForTarget()}
|
|
2365
|
+
.onTogglePlugin=${(e,t)=>this.togglePlugin(e,t)}
|
|
2366
|
+
></settings-plugins-panel>
|
|
2367
|
+
`:g`
|
|
2368
|
+
<settings-general-panel
|
|
2369
|
+
.configResponse=${this.configResponse}
|
|
2370
|
+
.machineConfigResponse=${this.accessConfigResponse}
|
|
2371
|
+
.loading=${this.loading}
|
|
2372
|
+
.machineLoading=${this.accessLoading}
|
|
2373
|
+
.saving=${this.saving}
|
|
2374
|
+
.error=${this.error}
|
|
2375
|
+
.machineError=${this.accessError}
|
|
2376
|
+
.savedMessage=${this.savedMessage}
|
|
2377
|
+
.targetLabel=${Y(this.settingsTarget())}
|
|
2378
|
+
.onReload=${()=>this.loadConfig()}
|
|
2379
|
+
.onReloadMachine=${()=>this.loadAccessConfigForTarget()}
|
|
2380
|
+
.onSave=${e=>this.saveConfig(e)}
|
|
2381
|
+
.onSaveMachineConfig=${e=>this.saveMachineAccessConfig(e)}
|
|
2382
|
+
></settings-general-panel>
|
|
2383
|
+
`}renderNavButton(e,t,n){let r=this.section===e;return g`
|
|
2384
|
+
<button class=${r?`selected`:``} aria-current=${r?`page`:`false`} @click=${()=>{this.navigate(e)}}>
|
|
2385
|
+
<strong>${t}</strong>
|
|
2386
|
+
<small>${n}</small>
|
|
2387
|
+
</button>
|
|
2388
|
+
`}navigate(e){this.onNavigate?.(e)}async loadConfig(){let e=++this.loadRequestSeq;this.loading=!0,this.error=``;try{let t=await cx({loadConfig:()=>Ri.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(_x(n)){this.accessConfigResponse=void 0,this.accessLoading=!1,this.accessError=n.message??`Selected-machine settings are not available on ${Y(e)}.`;return}this.accessLoading=!0,this.accessError=``;try{let n=await Ri.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 ${Y(e)}: ${bx(Tx(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(_x(n)){this.sessiondConfigResponse=void 0,this.sessiondLoading=!1,this.sessiondError=n.message??`Selected-machine settings are not available on ${Y(e)}.`;return}this.sessiondLoading=!0,this.sessiondError=``;try{let n=await Ri.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 ${Y(e)}: ${bx(Tx(n),e)}`)}finally{this.isCurrentSessiondLoad(t,e)&&(this.sessiondLoading=!1)}}async loadPluginsForTarget(e=this.settingsTarget()){let t=++this.pluginLoadRequestSeq,n=this.selectedMachineSettingsSupport(e);if(_x(n)){this.selectedPluginConfigResponse=void 0,this.selectedPluginsResponse=void 0,this.pluginLoading=!1,this.pluginError=n.message??`Selected-machine settings are not available on ${Y(e)}.`;return}this.pluginLoading=!0,this.pluginError=``;try{let[n,r]=await Promise.allSettled([Ri.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: ${bx(Tx(n.reason),e)}`),r.status===`fulfilled`?this.selectedPluginsResponse=r.value:i.push(`PI WEB plugins: ${bx(Tx(r.reason),e)}`),this.pluginError=i.length===0?``:`Failed to load PI WEB plugin settings from ${Y(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 lx(e,e=>Hi.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(_x(r)){this.pluginError=r.message??`Selected-machine settings are not available on ${Y(n)}.`;return}if(this.selectedPluginConfigResponse===void 0){this.pluginError=`Plugin config is not loaded for ${Y(n)}. Reload before changing plugin enablement.`;return}let i=Sx(this.selectedPluginConfigResponse.config,e,t);this.saving=!0,this.pluginError=``,this.savedMessage=``;try{let e=await Ri.saveConfig(i,n.id);if(!this.isCurrentSettingsTarget(n))return;this.selectedPluginConfigResponse=e,n.kind===`local`&&this.configResponse!==void 0&&(this.configResponse=Cx(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 ${Y(n)}: ${bx(Tx(e),n)}`)}finally{this.saving=!1}}async saveConfig(e){if(!this.saving){this.saving=!0,this.error=``,this.savedMessage=``;try{let t=await Ri.saveConfig(e);this.configResponse=t,this.onConfigSaved?.(t.effectiveConfig),this.showSavedMessage()}catch(e){this.error=`保存配置失败:${Tx(e)}`}finally{this.saving=!1}}}async saveMachineAccessConfig(e){if(this.saving)return;let t=this.settingsTarget(),n=this.selectedMachineSettingsSupport(t);if(_x(n)){this.accessError=n.message??`Selected-machine settings are not available on ${Y(t)}.`;return}this.saving=!0,this.accessError=``,this.savedMessage=``;try{let n=await Ri.saveConfig(e,t.id);if(!this.isCurrentSettingsTarget(t))return;this.accessConfigResponse=n,t.kind===`local`&&this.configResponse!==void 0&&(this.configResponse=dx(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 ${Y(t)}: ${bx(Tx(e),t)}`)}finally{this.saving=!1}}async saveSessiondConfig(e){if(this.saving)return;let t=this.settingsTarget(),n=this.selectedMachineSettingsSupport(t);if(_x(n)){this.sessiondError=n.message??`Selected-machine settings are not available on ${Y(t)}.`;return}if(e.agent!==void 0){let e=this.agentProfileSettingsSupport(t);if(!vx(e)){this.sessiondError=e.message??`Pi-compatible agent profile settings are not available on ${Y(t)}.`;return}}this.saving=!0,this.sessiondError=``,this.savedMessage=``;try{let n=await Ri.saveConfig(e,t.id);if(!this.isCurrentSettingsTarget(t))return;this.sessiondConfigResponse=n,t.kind===`local`&&this.configResponse!==void 0&&(this.configResponse=gb(this.configResponse,n)),this.showSavedMessage()}catch(e){this.isCurrentSettingsTarget(t)&&(this.sessiondError=`Failed to save session-daemon config on ${Y(t)}: ${bx(Tx(e),t)}`)}finally{this.saving=!1}}async installPiPackage(e){let t=this.packageTarget();await this.runPiPackageMutation({kind:`install`,source:e},`install Pi package`,t,()=>Hi.install(e,t.id))}async removePiPackage(e,t){let n=this.packageTarget();await this.runPiPackageMutation({kind:`remove`,source:e},`remove Pi package`,n,()=>Hi.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,()=>Hi.update(e,t.id))}async runPiPackageMutation(e,t,n,r){let i=this.packageManagementSupport(n);if(Db(i))throw this.packageError=i.message??`Pi package management is not available on ${wb(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=kb(n)?await this.refreshGatewayPlugins():void 0;if(!this.isCurrentPackageMutation(a,n))return;t!==void 0&&(this.packageError=t),this.packageMessage=Bb(e.action,n)}catch(e){throw this.isCurrentPackageMutation(a,n)&&(this.packageError=`Failed to ${t} on ${wb(n)}: ${Vb(Tx(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`刷新网关 PI WEB 插件失败:${Tx(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 ${Y(e)}: ${bx(Tx(t),e)}`}}settingsTarget(){return px(this.machine)}packageTarget(){return this.settingsTarget()}selectedMachineSettingsSupport(e=this.settingsTarget()){return mx(e,this.machineRuntime)}agentProfileSettingsSupport(e=this.settingsTarget()){return hx(e,this.machineRuntime)}selectedMachineSettingsSupportNeedsReload(e,t){let n=mx(t,e),r=this.selectedMachineSettingsSupport(t);return gx(n)!==gx(r)}packageManagementSupport(e=this.packageTarget()){return Tb(e,this.machineRuntime)}packageManagementSupportNeedsReload(e,t){let n=Tb(t,e),r=this.packageManagementSupport(t);return Eb(n)===Eb(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=`配置已保存。`,this.savedMessageTimer!==void 0&&window.clearTimeout(this.savedMessageTimer),this.savedMessageTimer=window.setTimeout(()=>{this.savedMessage===`配置已保存。`&&(this.savedMessage=``),this.savedMessageTimer=void 0},3e3)}handleKeyDown(e){e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),this.onClose?.())}static{this.styles=h`
|
|
2389
|
+
:host { position: fixed; inset: 0; z-index: 30; color: var(--pi-text); font: 14px system-ui, sans-serif; }
|
|
2390
|
+
.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; }
|
|
2391
|
+
.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; }
|
|
2392
|
+
.settings-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--pi-border); }
|
|
2393
|
+
.eyebrow { display: block; color: var(--pi-muted); font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
|
|
2394
|
+
h1 { margin: 0; font-size: 20px; line-height: 1.2; }
|
|
2395
|
+
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; }
|
|
2396
|
+
.close-button { width: 34px; height: 34px; display: grid; place-items: center; border: 0; background: transparent; color: var(--pi-muted); padding: 0; font-size: 24px; }
|
|
2397
|
+
.close-button:hover, .close-button:focus { color: var(--pi-text); background: var(--pi-surface-hover); }
|
|
2398
|
+
.settings-body { min-height: 0; display: grid; grid-template-columns: 220px minmax(0, 1fr); }
|
|
2399
|
+
.settings-nav { min-height: 0; padding: 10px; border-right: 1px solid var(--pi-border); background: var(--pi-surface); overflow: auto; }
|
|
2400
|
+
.settings-nav button { display: grid; gap: 2px; width: 100%; margin: 0 0 6px; text-align: left; border-color: transparent; background: transparent; }
|
|
2401
|
+
.settings-nav button:hover, .settings-nav button:focus { background: var(--pi-surface-hover); }
|
|
2402
|
+
.settings-nav button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
|
|
2403
|
+
.settings-nav small { color: var(--pi-muted); }
|
|
2404
|
+
.settings-content { min-width: 0; min-height: 0; overflow: auto; padding: 18px; }
|
|
2405
|
+
|
|
2406
|
+
@media (max-width: 760px) {
|
|
2407
|
+
.backdrop { padding: 0; place-items: stretch; }
|
|
2408
|
+
.settings-shell { width: 100%; height: 100dvh; max-height: none; min-height: 0; border: 0; border-radius: 0; }
|
|
2409
|
+
.settings-header { padding: max(12px, env(safe-area-inset-top)) 12px 12px; }
|
|
2410
|
+
.settings-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
|
|
2411
|
+
.settings-nav { display: flex; gap: 8px; padding: 8px; border-right: 0; border-bottom: 1px solid var(--pi-border); overflow-x: auto; overflow-y: hidden; }
|
|
2412
|
+
.settings-nav button { flex: 0 0 auto; width: auto; min-width: 128px; margin: 0; }
|
|
2413
|
+
.settings-content { padding: 14px 12px calc(18px + env(safe-area-inset-bottom)); }
|
|
2414
|
+
}
|
|
2415
|
+
`}};z([b({attribute:!1})],X.prototype,`section`,void 0),z([b({attribute:!1})],X.prototype,`actions`,void 0),z([b({attribute:!1})],X.prototype,`machine`,void 0),z([b({attribute:!1})],X.prototype,`machineRuntime`,void 0),z([b({attribute:!1})],X.prototype,`onNavigate`,void 0),z([b({attribute:!1})],X.prototype,`onClose`,void 0),z([b({attribute:!1})],X.prototype,`onConfigSaved`,void 0),z([b({attribute:!1})],X.prototype,`onRefreshMachineRuntime`,void 0),z([x()],X.prototype,`configResponse`,void 0),z([x()],X.prototype,`accessConfigResponse`,void 0),z([x()],X.prototype,`sessiondConfigResponse`,void 0),z([x()],X.prototype,`pluginsResponse`,void 0),z([x()],X.prototype,`selectedPluginConfigResponse`,void 0),z([x()],X.prototype,`selectedPluginsResponse`,void 0),z([x()],X.prototype,`packagesResponse`,void 0),z([x()],X.prototype,`loading`,void 0),z([x()],X.prototype,`accessLoading`,void 0),z([x()],X.prototype,`sessiondLoading`,void 0),z([x()],X.prototype,`pluginLoading`,void 0),z([x()],X.prototype,`packageLoading`,void 0),z([x()],X.prototype,`saving`,void 0),z([x()],X.prototype,`packageOperation`,void 0),z([x()],X.prototype,`error`,void 0),z([x()],X.prototype,`accessError`,void 0),z([x()],X.prototype,`sessiondError`,void 0),z([x()],X.prototype,`pluginError`,void 0),z([x()],X.prototype,`packageError`,void 0),z([x()],X.prototype,`savedMessage`,void 0),z([x()],X.prototype,`packageMessage`,void 0),X=z([y(`settings-dialog`)],X);function Tx(e){return e instanceof Error?e.message:String(e)}var Ex=h`
|
|
2416
|
+
: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; }
|
|
2417
|
+
header { flex: 0 0 auto; min-width: 0; border-bottom: 1px solid var(--pi-border); }
|
|
2418
|
+
.workspace-header-scroll-frame { position: relative; min-width: 0; background: var(--pi-bg); }
|
|
2419
|
+
.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; }
|
|
2420
|
+
.workspace-header-scroll-frame::before { left: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
2421
|
+
.workspace-header-scroll-frame::after { right: 0; background: linear-gradient(270deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
2422
|
+
.workspace-header-scroll-frame.can-scroll-left::before, .workspace-header-scroll-frame.can-scroll-right::after { opacity: 1; }
|
|
2423
|
+
.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; }
|
|
2424
|
+
.tabs { flex: 0 0 auto; display: flex; gap: 6px; align-items: center; }
|
|
2425
|
+
.tabs button { flex: 0 0 auto; white-space: nowrap; }
|
|
2426
|
+
.tabs button.icon-tab { min-width: 34px; }
|
|
2427
|
+
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; }
|
|
2428
|
+
button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
|
|
2429
|
+
.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; }
|
|
2430
|
+
.tab-custom-icon { flex: 0 0 auto; width: 16px; height: 16px; display: inline-grid; place-items: center; color: currentColor; pointer-events: none; }
|
|
2431
|
+
.tab-custom-icon svg { width: 16px; height: 16px; pointer-events: none; }
|
|
2432
|
+
.tab-label { min-width: 0; }
|
|
2433
|
+
.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; }
|
|
2434
|
+
@container (max-width: 430px) {
|
|
2435
|
+
.tabs button.icon-tab { justify-content: center; padding-inline: 7px; }
|
|
2436
|
+
.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; }
|
|
2437
|
+
}
|
|
2438
|
+
.panel-content { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: auto; }
|
|
2439
|
+
.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; }
|
|
2440
|
+
.empty-state h2 { margin: 0; color: var(--pi-text); font-size: 15px; line-height: 1.3; }
|
|
2441
|
+
.empty-state p { margin: 0; line-height: 1.45; }
|
|
2442
|
+
small, .muted { color: var(--pi-muted); }
|
|
2443
|
+
@media (max-width: 1180px) { header { display: none; } }
|
|
2444
|
+
.workspace-label { min-width: 0; display: inline-flex; align-items: baseline; gap: 5px; max-width: 100%; overflow: hidden; white-space: nowrap; }
|
|
2445
|
+
.workspace-label-base, .workspace-label-item, .workspace-label-render { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
2446
|
+
.workspace-label-item, .workspace-label-render, .workspace-label-separator { color: var(--pi-muted); }
|
|
2447
|
+
.workspace-label-link { color: var(--pi-accent); text-decoration: none; }
|
|
2448
|
+
.workspace-label-link:hover, .workspace-label-link:focus { text-decoration: underline; }
|
|
2449
|
+
.toolbar { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; padding: 8px; border-bottom: 1px solid var(--pi-border-muted); }
|
|
2450
|
+
.toolbar > button { margin-left: auto; }
|
|
2451
|
+
.toolbar-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
|
2452
|
+
.file-upload-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; user-select: none; }
|
|
2453
|
+
.file-upload-button:hover, .file-upload-button:focus-visible { background: var(--pi-surface-hover); }
|
|
2454
|
+
.file-upload-button.disabled { opacity: .5; cursor: not-allowed; }
|
|
2455
|
+
.stale { border: 1px solid var(--pi-warning-border); border-radius: 999px; color: var(--pi-warning); padding: 1px 6px; font-size: 12px; }
|
|
2456
|
+
.split { flex: 1 1 auto; min-height: 0; display: grid; grid-template-rows: minmax(160px, 34%) minmax(0, 1fr); }
|
|
2457
|
+
.list { min-height: 0; overflow: auto; border-bottom: 1px solid var(--pi-border); padding: 6px; }
|
|
2458
|
+
.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); }
|
|
2459
|
+
.row:hover, .row.selected { background: var(--pi-selection-bg); }
|
|
2460
|
+
.row span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2461
|
+
.summary { margin: 4px 6px 8px; color: var(--pi-muted); }
|
|
2462
|
+
.viewer { min-height: 0; overflow: auto; display: flex; flex-direction: column; }
|
|
2463
|
+
.diffs { flex: 1 1 auto; min-height: 0; overflow: auto; display: grid; grid-template-rows: minmax(120px, 1fr) minmax(120px, 1fr); }
|
|
2464
|
+
.diffs.single { grid-template-rows: minmax(0, 1fr); }
|
|
2465
|
+
.diff-section { min-height: 0; display: flex; flex-direction: column; border-bottom: 1px solid var(--pi-border); }
|
|
2466
|
+
.diff-section:last-child { border-bottom: 0; }
|
|
2467
|
+
.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); }
|
|
2468
|
+
.viewer-header strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2469
|
+
code-viewer { flex: 1 1 auto; min-height: 0; }
|
|
2470
|
+
.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; }
|
|
2471
|
+
.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); }
|
|
2472
|
+
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; }
|
|
2473
|
+
p { margin: 10px; }
|
|
2474
|
+
`,Dx=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:`选择工作区`,body:`选择工作区来查看文件、Git 或终端。`});let e=this.panelContext;if(e===void 0)return this.renderEmptyState({title:`工作区工具不可用`,body:`请尝试重新选择工作区。`});let t=this.panels,n=t.find(e=>e.id===this.tool)??t[0];return g`
|
|
2475
|
+
${this.hideToolTabs?null:g`
|
|
2476
|
+
<header>
|
|
2477
|
+
<div class=${this.workspaceHeaderFrameClass()}>
|
|
2478
|
+
<div class="workspace-header-strip" @scroll=${this.onWorkspaceHeaderScroll}>
|
|
2479
|
+
<div class="tabs">
|
|
2480
|
+
${t.map(t=>{let r=n?.id===t.id,i=t.badge?.(e),a=this.panelTabAriaLabel(t,i);return g`
|
|
2481
|
+
<button class=${this.panelTabClass(t,r)} title=${a} aria-label=${a} aria-pressed=${String(r)} @click=${()=>{this.onSelectTool(t.id)}}>
|
|
2482
|
+
${this.renderPanelTabContent(t,i)}
|
|
2483
|
+
</button>
|
|
2484
|
+
`})}
|
|
2485
|
+
</div>
|
|
2486
|
+
</div>
|
|
2487
|
+
</div>
|
|
2488
|
+
</header>
|
|
2489
|
+
`}
|
|
2490
|
+
${n===void 0?this.renderEmptyState({title:`没有可用的工作区工具`,body:`此工作区没有可用工具。`}):g`
|
|
2491
|
+
<div class="panel-content">
|
|
2492
|
+
${n.render(e)}
|
|
2493
|
+
</div>
|
|
2494
|
+
`}
|
|
2495
|
+
`}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`
|
|
2496
|
+
${e.icon===void 0?null:g`<span class="tab-custom-icon" aria-hidden="true">${e.icon}</span>`}
|
|
2497
|
+
<span class="tab-label">${e.title}</span>
|
|
2498
|
+
${this.isEmptyBadge(t)?null:g`<span class="tab-badge">${t}</span>`}
|
|
2499
|
+
`}isEmptyBadge(e){return e===void 0||e===``}renderEmptyState(e){return g`
|
|
2500
|
+
<section class="empty-state" role="status">
|
|
2501
|
+
<h2>${e.title}</h2>
|
|
2502
|
+
${e.body===void 0?null:g`<p>${e.body}</p>`}
|
|
2503
|
+
</section>
|
|
2504
|
+
`}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=Ex}};z([b({attribute:!1})],Dx.prototype,`workspace`,void 0),z([b({attribute:!1})],Dx.prototype,`panelContext`,void 0),z([b({attribute:!1})],Dx.prototype,`emptyState`,void 0),z([b()],Dx.prototype,`tool`,void 0),z([b({attribute:!1})],Dx.prototype,`panels`,void 0),z([b({type:Boolean})],Dx.prototype,`hideToolTabs`,void 0),z([b({attribute:!1})],Dx.prototype,`onSelectTool`,void 0),z([S(`.workspace-header-strip`)],Dx.prototype,`workspaceHeaderStrip`,void 0),z([x()],Dx.prototype,`workspaceHeaderCanScrollLeft`,void 0),z([x()],Dx.prototype,`workspaceHeaderCanScrollRight`,void 0),Dx=z([y(`workspace-panel`)],Dx);var Ox=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=kx(this.machines),t=Ax(this.machine),n=Mx(this.project),r=Px(this.workspace),i=Ix(this.session);return g`
|
|
2505
|
+
<nav class=${this.contextBarClass()} aria-label="当前位置">
|
|
2506
|
+
<span class="context-bar-label">位置</span>
|
|
2507
|
+
<ol class="context-items" @scroll=${this.onContextScroll}>
|
|
2508
|
+
${e?g`
|
|
2509
|
+
<li class="context-item">
|
|
2510
|
+
<button type="button" class=${this.machine===void 0?`context-chip empty`:`context-chip`} title=${jx(this.machine)} aria-label=${`机器:${t}。打开机器选择。`} @click=${()=>{this.onOpenSection?.(`machines`)}}>
|
|
2511
|
+
<span class="context-kind">机器</span>
|
|
2512
|
+
<span class="context-value">${t}</span>
|
|
2513
|
+
</button>
|
|
2514
|
+
</li>
|
|
2515
|
+
`:null}
|
|
2516
|
+
<li class="context-item">
|
|
2517
|
+
<button type="button" class=${this.project===void 0?`context-chip empty`:`context-chip`} title=${Nx(this.project)} aria-label=${`项目:${n}。打开项目选择。`} @click=${()=>{this.onOpenSection?.(`projects`)}}>
|
|
2518
|
+
<span class="context-kind">项目</span>
|
|
2519
|
+
<span class="context-value">${n}</span>
|
|
2520
|
+
</button>
|
|
2521
|
+
</li>
|
|
2522
|
+
<li class="context-item">
|
|
2523
|
+
<button type="button" class=${this.workspace===void 0?`context-chip empty`:`context-chip`} title=${Fx(this.workspace)} aria-label=${`工作区:${r}。打开工作区选择。`} @click=${()=>{this.onOpenSection?.(`workspaces`)}}>
|
|
2524
|
+
<span class="context-kind">工作区</span>
|
|
2525
|
+
<span class="context-value">${r}</span>
|
|
2526
|
+
</button>
|
|
2527
|
+
</li>
|
|
2528
|
+
<li class="context-item">
|
|
2529
|
+
<button type="button" class=${this.session===void 0?`context-chip empty`:`context-chip`} title=${Lx(this.session)} aria-label=${`会话:${i}。打开会话选择。`} @click=${()=>{this.onOpenSection?.(`sessions`)}}>
|
|
2530
|
+
<span class="context-kind">会话</span>
|
|
2531
|
+
<span class="context-value">${i}</span>
|
|
2532
|
+
</button>
|
|
2533
|
+
</li>
|
|
2534
|
+
</ol>
|
|
2535
|
+
${this.hasContextActions()?g`<div class="context-actions">${this.renderActionsButton()}${this.refreshControl}</div>`:null}
|
|
2536
|
+
</nav>
|
|
2537
|
+
`}renderActionsButton(){return this.onShowActions===void 0?null:g`
|
|
2538
|
+
<button type="button" class="context-action-button" title="显示操作" aria-label="显示操作" @click=${e=>{e.stopPropagation(),this.onShowActions?.()}}>
|
|
2539
|
+
<svg class="context-action-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
2540
|
+
<path d="M13 2 4 14h7l-1 8 10-13h-7V2Z"></path>
|
|
2541
|
+
</svg>
|
|
2542
|
+
</button>
|
|
2543
|
+
`}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`
|
|
2544
|
+
/* Keep the refresh menu in this shadow tree above the following mobile tab strip. */
|
|
2545
|
+
:host { position: relative; z-index: 20; flex: 0 0 auto; min-width: 0; }
|
|
2546
|
+
.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); }
|
|
2547
|
+
.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; }
|
|
2548
|
+
.context-bar::before { left: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
2549
|
+
.context-bar::after { right: 0; background: linear-gradient(270deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
2550
|
+
.context-bar.can-scroll-left::before, .context-bar.can-scroll-right::after { opacity: 1; }
|
|
2551
|
+
.context-bar-label { display: none; }
|
|
2552
|
+
.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; }
|
|
2553
|
+
.context-bar.has-context-actions .context-items { padding-right: 58px; scroll-padding-inline: 8px 58px; }
|
|
2554
|
+
.context-bar.has-context-actions-double .context-items { padding-right: 102px; scroll-padding-inline: 8px 102px; }
|
|
2555
|
+
.context-item { flex: 0 0 auto; min-width: 0; display: flex; }
|
|
2556
|
+
.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; }
|
|
2557
|
+
.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; }
|
|
2558
|
+
app-refresh-control, .context-action-button { position: relative; z-index: 1; pointer-events: auto; }
|
|
2559
|
+
.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; }
|
|
2560
|
+
.context-action-button:hover, .context-action-button:focus-visible { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
|
|
2561
|
+
.context-action-icon { width: 18px; height: 18px; fill: currentColor; pointer-events: none; }
|
|
2562
|
+
.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; }
|
|
2563
|
+
.context-chip:hover { background: var(--pi-surface-hover); }
|
|
2564
|
+
.context-chip:focus-visible { outline: 2px solid var(--pi-accent); outline-offset: 2px; }
|
|
2565
|
+
.context-chip.empty { border-style: dashed; color: var(--pi-muted); }
|
|
2566
|
+
.context-kind { display: none; }
|
|
2567
|
+
.context-value { min-width: 0; overflow: visible; text-overflow: clip; white-space: nowrap; }
|
|
2568
|
+
button { cursor: pointer; }
|
|
2569
|
+
`}};z([b({attribute:!1})],Ox.prototype,`machines`,void 0),z([b({attribute:!1})],Ox.prototype,`machine`,void 0),z([b({attribute:!1})],Ox.prototype,`project`,void 0),z([b({attribute:!1})],Ox.prototype,`workspace`,void 0),z([b({attribute:!1})],Ox.prototype,`session`,void 0),z([b({attribute:!1})],Ox.prototype,`refreshControl`,void 0),z([b({attribute:!1})],Ox.prototype,`onOpenSection`,void 0),z([b({attribute:!1})],Ox.prototype,`onShowActions`,void 0),z([S(`.context-items`)],Ox.prototype,`contextItems`,void 0),z([x()],Ox.prototype,`canScrollLeft`,void 0),z([x()],Ox.prototype,`canScrollRight`,void 0),Ox=z([y(`app-context-bar`)],Ox);function kx(e){return e.length>1}function Ax(e){return e===void 0?`未选择机器`:`${e.name}${e.kind===`remote`?` · 远程`:``}`}function jx(e){return e===void 0?`未选择机器`:e.baseUrl??e.name}function Mx(e){return e?.name??`未选择项目`}function Nx(e){return e===void 0?`未选择项目`:`${e.name} — ${e.path}`}function Px(e){return e===void 0?`未选择工作区`:`${e.label}${e.isMain?` · 主工作区`:``} · ${e.path}`}function Fx(e){return e===void 0?`未选择工作区`:`${e.label}${e.isMain?` · 主工作区`:``} — ${e.path}`}function Ix(e){let t=e?.name?.trim(),n=e?.firstMessage.trim();return t!==void 0&&t!==``?t:n!==void 0&&n!==``?n:e===void 0?`未选择会话`:Pm(e.id)}function Lx(e){return e===void 0?`未选择会话`:e.path}var Rx=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`
|
|
2570
|
+
<div class=${this.frameClass()}>
|
|
2571
|
+
<div class="mobile-tabs" @scroll=${this.onMobileTabsScroll}>
|
|
2572
|
+
${this.tabs.map(t=>{let n=this.selectedView===t.id;return g`
|
|
2573
|
+
<button class=${this.tabClass(t)} title=${t.label} aria-label=${this.tabAriaLabel(t)} aria-pressed=${String(n)} @click=${()=>{this.onSelect?.(t.id)}}>
|
|
2574
|
+
${this.renderTabMark(t,e)}
|
|
2575
|
+
<span class="tab-label">${t.label}</span>
|
|
2576
|
+
${this.isEmptyBadge(t.badge)?null:g`<span class="tab-badge">${t.badge}</span>`}
|
|
2577
|
+
</button>
|
|
2578
|
+
`})}
|
|
2579
|
+
</div>
|
|
2580
|
+
</div>
|
|
2581
|
+
`}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>`:hd(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`
|
|
2582
|
+
:host { flex: 0 0 auto; min-width: 0; }
|
|
2583
|
+
.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); }
|
|
2584
|
+
.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; }
|
|
2585
|
+
.mobile-tabs-frame::before { left: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
2586
|
+
.mobile-tabs-frame::after { right: 0; background: linear-gradient(270deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
2587
|
+
.mobile-tabs-frame.can-scroll-left::before, .mobile-tabs-frame.can-scroll-right::after { opacity: 1; }
|
|
2588
|
+
.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; }
|
|
2589
|
+
.mobile-tabs button { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
|
|
2590
|
+
.mobile-tabs .navigation-tab { display: none; }
|
|
2591
|
+
.mobile-tabs button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
|
|
2592
|
+
.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; }
|
|
2593
|
+
.tab-custom-icon { flex: 0 0 auto; width: 18px; height: 18px; display: inline-grid; place-items: center; color: currentColor; pointer-events: none; }
|
|
2594
|
+
.tab-custom-icon svg { width: 18px; height: 18px; pointer-events: none; }
|
|
2595
|
+
.tab-fallback { display: none; font-weight: 650; letter-spacing: .01em; pointer-events: none; }
|
|
2596
|
+
.tab-label { min-width: 0; }
|
|
2597
|
+
.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; }
|
|
2598
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
|
2599
|
+
@media (max-width: 760px) {
|
|
2600
|
+
.mobile-tabs { gap: 4px; padding: 6px 8px; }
|
|
2601
|
+
.mobile-tabs button { min-width: 40px; height: 36px; justify-content: center; gap: 4px; padding: 0 8px; }
|
|
2602
|
+
.mobile-tabs .navigation-tab { display: inline-flex; }
|
|
2603
|
+
.tab-fallback { display: inline-block; }
|
|
2604
|
+
.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; }
|
|
2605
|
+
.tab-badge { min-width: 13px; padding: 0 4px; font-size: 10px; line-height: 13px; }
|
|
2606
|
+
}
|
|
2607
|
+
`}};z([b({attribute:!1})],Rx.prototype,`tabs`,void 0),z([b({attribute:!1})],Rx.prototype,`selectedView`,void 0),z([b({attribute:!1})],Rx.prototype,`onSelect`,void 0),z([S(`.mobile-tabs`)],Rx.prototype,`mobileTabs`,void 0),z([x()],Rx.prototype,`canScrollLeft`,void 0),z([x()],Rx.prototype,`canScrollRight`,void 0),Rx=z([y(`app-mobile-main-tabs`)],Rx);var zx=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=Bx(e,this.statuses),n=e.name;return g`
|
|
2608
|
+
<div class="machine-switcher">
|
|
2609
|
+
<button
|
|
2610
|
+
type="button"
|
|
2611
|
+
class="machine-switcher-button"
|
|
2612
|
+
title=${Hx(e)}
|
|
2613
|
+
aria-label=${`Machine: ${n}. Switch machine.`}
|
|
2614
|
+
aria-expanded=${String(this.open)}
|
|
2615
|
+
@click=${e=>{this.toggleMenu(e.currentTarget)}}
|
|
2616
|
+
@keydown=${e=>{this.handleSwitcherButtonKeydown(e)}}
|
|
2617
|
+
>
|
|
2618
|
+
${this.renderActivity(e)}
|
|
2619
|
+
<span class="machine-switcher-text">
|
|
2620
|
+
<span class="machine-switcher-kicker">Machine</span>
|
|
2621
|
+
<span class="machine-switcher-label">${n}</span>
|
|
2622
|
+
</span>
|
|
2623
|
+
<span class=${`machine-status ${t}`}>${Vx(t)}</span>
|
|
2624
|
+
<span class="machine-chevron" aria-hidden="true">▾</span>
|
|
2625
|
+
</button>
|
|
2626
|
+
${this.open?g`
|
|
2627
|
+
<div class="machine-switcher-menu" style=${this.menuStyle} @click=${e=>{e.stopPropagation()}}>
|
|
2628
|
+
${this.machines.map(e=>this.renderMachineOption(e))}
|
|
2629
|
+
</div>
|
|
2630
|
+
`:null}
|
|
2631
|
+
</div>
|
|
2632
|
+
`}renderMachineOption(e){let t=this.selected?.id===e.id,n=Bx(e,this.statuses),r=Tm(e)&&this.onRemove!==void 0,i=this.openActionsMachineId===e.id;return g`
|
|
2633
|
+
<div class=${`machine-option ${t?`selected`:``} ${r?``:`no-actions`}`}>
|
|
2634
|
+
<button
|
|
2635
|
+
type="button"
|
|
2636
|
+
class="machine-option-main"
|
|
2637
|
+
title=${Hx(e)}
|
|
2638
|
+
data-machine-id=${e.id}
|
|
2639
|
+
@click=${()=>{this.select(e)}}
|
|
2640
|
+
@keydown=${e=>{this.handleMachineOptionKeydown(e)}}
|
|
2641
|
+
>
|
|
2642
|
+
<span class="machine-option-name">${this.renderActivity(e)}<span>${e.name}</span></span>
|
|
2643
|
+
<small>${e.kind===`local`?`Local Pi Web`:e.baseUrl??`Remote Pi Web`} · ${Vx(n)}</small>
|
|
2644
|
+
</button>
|
|
2645
|
+
${r?g`
|
|
2646
|
+
<div class="machine-option-actions">
|
|
2647
|
+
<button
|
|
2648
|
+
type="button"
|
|
2649
|
+
class="machine-option-actions-toggle"
|
|
2650
|
+
title="Machine actions"
|
|
2651
|
+
aria-label=${`Actions for ${e.name}`}
|
|
2652
|
+
aria-expanded=${String(i)}
|
|
2653
|
+
@click=${t=>{t.stopPropagation(),this.toggleActionsMenu(e.id,t.currentTarget)}}
|
|
2654
|
+
>⋯</button>
|
|
2655
|
+
${i?g`
|
|
2656
|
+
<div class="machine-option-actions-panel" style=${this.actionMenuStyle} @click=${e=>{e.stopPropagation()}}>
|
|
2657
|
+
<button class="danger" title=${`Remove ${e.name}`} @click=${()=>{this.removeMachine(e)}}>Remove</button>
|
|
2658
|
+
</div>
|
|
2659
|
+
`:null}
|
|
2660
|
+
</div>
|
|
2661
|
+
`:null}
|
|
2662
|
+
</div>
|
|
2663
|
+
`}renderActivity(e){let t=Bx(e,this.statuses);if(t===`offline`||t===`error`)return;let n=Qp(this.activities[e.id]);return tm(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=Ux(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=Ux(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=am(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`
|
|
2664
|
+
:host { min-width: 0; display: block; }
|
|
2665
|
+
.machine-switcher { min-width: 0; }
|
|
2666
|
+
.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; }
|
|
2667
|
+
.machine-switcher-button:hover, .machine-switcher-button:focus-visible { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
|
|
2668
|
+
.machine-switcher-text { flex: 1 1 auto; min-width: 0; display: grid; gap: 1px; }
|
|
2669
|
+
.machine-switcher-kicker { color: var(--pi-muted); font-size: 10px; line-height: 1; text-transform: uppercase; letter-spacing: .02em; }
|
|
2670
|
+
.machine-switcher-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; font-weight: 600; line-height: 1.2; }
|
|
2671
|
+
.machine-status { flex: 0 0 auto; color: var(--pi-muted); font-size: 11px; }
|
|
2672
|
+
.machine-status.online { color: var(--pi-success); }
|
|
2673
|
+
.machine-status.offline, .machine-status.error { color: var(--pi-danger); }
|
|
2674
|
+
.machine-chevron { flex: 0 0 auto; color: var(--pi-muted); font-size: 11px; }
|
|
2675
|
+
.activity-indicator { flex: 0 0 auto; display: inline-block; width: 7px; height: 7px; background: var(--pi-success); animation: pulse 1s ease-in-out infinite; }
|
|
2676
|
+
.activity-indicator.session { border-radius: 50%; background: var(--pi-success); }
|
|
2677
|
+
.activity-indicator.terminal { border-radius: 2px; background: var(--pi-accent); }
|
|
2678
|
+
.activity-indicator.sending { border-radius: 50%; background: var(--pi-warning); }
|
|
2679
|
+
.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); }
|
|
2680
|
+
.machine-option { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px; align-items: stretch; margin: 2px 0; }
|
|
2681
|
+
.machine-option.no-actions { grid-template-columns: minmax(0, 1fr); }
|
|
2682
|
+
.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; }
|
|
2683
|
+
.machine-option-main { min-width: 0; display: grid; gap: 2px; padding: 7px 8px; text-align: left; }
|
|
2684
|
+
.machine-option-name { min-width: 0; display: flex; align-items: baseline; gap: 6px; }
|
|
2685
|
+
.machine-option-name span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2686
|
+
.machine-option-main small { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--pi-muted); }
|
|
2687
|
+
.machine-option-actions { position: relative; align-self: stretch; }
|
|
2688
|
+
.machine-option-actions-toggle { display: grid; place-items: center; height: 100%; min-width: 32px; padding: 0; color: var(--pi-muted); }
|
|
2689
|
+
.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); }
|
|
2690
|
+
.machine-option-actions-panel button { display: block; width: 100%; padding: 7px 9px; text-align: left; white-space: nowrap; }
|
|
2691
|
+
.machine-option-actions-panel button.danger { color: var(--pi-danger); }
|
|
2692
|
+
.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); }
|
|
2693
|
+
.machine-option-actions-panel button:hover, .machine-option-actions-panel button:focus-visible { background: var(--pi-selection-bg); }
|
|
2694
|
+
.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); }
|
|
2695
|
+
@keyframes pulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
|
|
2696
|
+
`}};z([b({attribute:!1})],zx.prototype,`machines`,void 0),z([b({attribute:!1})],zx.prototype,`selected`,void 0),z([b({attribute:!1})],zx.prototype,`statuses`,void 0),z([b({attribute:!1})],zx.prototype,`activities`,void 0),z([b({attribute:!1})],zx.prototype,`onSelect`,void 0),z([b({attribute:!1})],zx.prototype,`onRemove`,void 0),z([b({attribute:!1})],zx.prototype,`onFocusNextSection`,void 0),z([b({attribute:!1})],zx.prototype,`onCancelKeyboardNavigation`,void 0),z([x()],zx.prototype,`open`,void 0),z([x()],zx.prototype,`menuStyle`,void 0),z([x()],zx.prototype,`openActionsMachineId`,void 0),z([x()],zx.prototype,`actionMenuStyle`,void 0),zx=z([y(`machine-switcher`)],zx);function Bx(e,t){return t[e.id]?.status??e.status??`unknown`}function Vx(e){return e===`online`?`online`:e===`offline`?`offline`:e===`error`?`error`:`unknown`}function Hx(e){return e.baseUrl??e.name}function Ux(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: ${Wx(t.bottom)};`,`left: ${Wx(r)};`,`width: ${Wx(n)};`,`max-height: ${Wx(i)};`].join(` `)}function Wx(e){return`${String(Math.round(e))}px`}var Z=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=`请更新并重启此机器上的 Pi-Web 后再删除已归档会话。`,this.cleanupUnavailableMessage=`请更新并重启此机器上的 Pi-Web 后再清理会话。`}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`
|
|
2697
|
+
<header>
|
|
2698
|
+
<strong>PI WEB</strong>
|
|
2699
|
+
${Gx(this.machines)?g`
|
|
2700
|
+
<machine-switcher
|
|
2701
|
+
.machines=${this.machines}
|
|
2702
|
+
.selected=${this.selectedMachine}
|
|
2703
|
+
.statuses=${this.machineStatuses}
|
|
2704
|
+
.activities=${this.machineActivities}
|
|
2705
|
+
.onSelect=${e=>this.onSelectMachine?.(e)}
|
|
2706
|
+
.onRemove=${e=>this.onRemoveMachine?.(e)}
|
|
2707
|
+
.onFocusNextSection=${()=>{this.focusNextFrom(`machines`)}}
|
|
2708
|
+
.onCancelKeyboardNavigation=${()=>{this.cancelKeyboardNavigation()}}
|
|
2709
|
+
></machine-switcher>
|
|
2710
|
+
`:null}
|
|
2711
|
+
<div class="header-actions">
|
|
2712
|
+
${this.refreshControl}
|
|
2713
|
+
<button title="显示操作" aria-label="显示操作" @click=${()=>{this.onShowActions?.()}}>操作</button>
|
|
2714
|
+
</div>
|
|
2715
|
+
</header>
|
|
2716
|
+
${this.compact&&Gx(this.machines)?g`
|
|
2717
|
+
<machine-list
|
|
2718
|
+
.machines=${this.machines}
|
|
2719
|
+
.selected=${this.selectedMachine}
|
|
2720
|
+
.statuses=${this.machineStatuses}
|
|
2721
|
+
.activities=${this.machineActivities}
|
|
2722
|
+
.collapsible=${this.collapsible}
|
|
2723
|
+
.collapsed=${this.machinesCollapsed}
|
|
2724
|
+
.onToggleCollapsed=${()=>{this.onToggleMachines?.()}}
|
|
2725
|
+
.onSelect=${e=>this.onSelectMachine?.(e)}
|
|
2726
|
+
.onRemove=${e=>this.onRemoveMachine?.(e)}
|
|
2727
|
+
.onFocusNextSection=${()=>{this.focusNextFrom(`machines`)}}
|
|
2728
|
+
.onCancelKeyboardNavigation=${()=>{this.cancelKeyboardNavigation()}}
|
|
2729
|
+
></machine-list>
|
|
2730
|
+
`:null}
|
|
2731
|
+
<project-list
|
|
2732
|
+
.projects=${this.projects}
|
|
2733
|
+
.selected=${this.selectedProject}
|
|
2734
|
+
.activities=${this.workspaceActivities}
|
|
2735
|
+
.workspacesByProjectId=${this.workspacesByProjectId}
|
|
2736
|
+
.collapsible=${this.collapsible}
|
|
2737
|
+
.collapsed=${this.projectsCollapsed}
|
|
2738
|
+
.onToggleCollapsed=${()=>{this.onToggleProjects?.()}}
|
|
2739
|
+
.onSelect=${e=>this.onSelectProject?.(e)}
|
|
2740
|
+
.onClose=${e=>this.onCloseProject?.(e)}
|
|
2741
|
+
.onFocusPreviousSection=${()=>{this.focusPreviousFrom(`projects`)}}
|
|
2742
|
+
.onFocusNextSection=${()=>{this.focusNextFrom(`projects`)}}
|
|
2743
|
+
.onCancelKeyboardNavigation=${()=>{this.cancelKeyboardNavigation()}}
|
|
2744
|
+
></project-list>
|
|
2745
|
+
<workspace-list
|
|
2746
|
+
.workspaces=${this.workspaces}
|
|
2747
|
+
.selected=${this.selectedWorkspace}
|
|
2748
|
+
.activities=${this.workspaceActivities}
|
|
2749
|
+
.deletingWorkspaceIds=${this.deletingWorkspaceIds}
|
|
2750
|
+
.collapsible=${this.collapsible}
|
|
2751
|
+
.collapsed=${this.workspacesCollapsed}
|
|
2752
|
+
.workspaceLabelItems=${this.workspaceLabelItems}
|
|
2753
|
+
.onToggleCollapsed=${()=>{this.onToggleWorkspaces?.()}}
|
|
2754
|
+
.onSelect=${e=>this.onSelectWorkspace?.(e)}
|
|
2755
|
+
.onDelete=${e=>this.onDeleteWorkspace?.(e)}
|
|
2756
|
+
.onFocusPreviousSection=${()=>{this.focusPreviousFrom(`workspaces`)}}
|
|
2757
|
+
.onFocusNextSection=${()=>{this.focusNextFrom(`workspaces`)}}
|
|
2758
|
+
.onCancelKeyboardNavigation=${()=>{this.cancelKeyboardNavigation()}}
|
|
2759
|
+
></workspace-list>
|
|
2760
|
+
<session-list
|
|
2761
|
+
.sessions=${this.sessions}
|
|
2762
|
+
.statuses=${this.sessionStatuses}
|
|
2763
|
+
.activities=${this.sessionActivities}
|
|
2764
|
+
.sending=${this.sendingPrompts}
|
|
2765
|
+
.selected=${this.selectedSession}
|
|
2766
|
+
.startingCount=${this.startingSessionCount}
|
|
2767
|
+
.canStart=${this.canStartSession}
|
|
2768
|
+
.canDeleteArchived=${this.canDeleteArchivedSessions}
|
|
2769
|
+
.canReload=${this.canReloadSessions}
|
|
2770
|
+
.canCleanup=${this.canCleanupSessions}
|
|
2771
|
+
.authoritativeSessionPersistence=${this.authoritativeSessionPersistence}
|
|
2772
|
+
.archivedDeleteUnavailableMessage=${this.archivedDeleteUnavailableMessage}
|
|
2773
|
+
.cleanupUnavailableMessage=${this.cleanupUnavailableMessage}
|
|
2774
|
+
.collapsible=${this.collapsible}
|
|
2775
|
+
.collapsed=${this.sessionsCollapsed}
|
|
2776
|
+
.onToggleCollapsed=${()=>{this.onToggleSessions?.()}}
|
|
2777
|
+
.onArchivedCollapsed=${()=>this.onArchivedCollapsed?.()}
|
|
2778
|
+
.onStart=${()=>this.onStartSession?.()}
|
|
2779
|
+
.onSelect=${e=>this.onSelectSession?.(e)}
|
|
2780
|
+
.onArchive=${e=>this.onArchiveSession?.(e)}
|
|
2781
|
+
.onArchiveWithDescendants=${e=>this.onArchiveSessionWithDescendants?.(e)}
|
|
2782
|
+
.onArchiveMany=${e=>this.onArchiveSessions?.(e)}
|
|
2783
|
+
.onRestore=${e=>this.onRestoreSession?.(e)}
|
|
2784
|
+
.onDelete=${e=>this.onDeleteCachedNewSession?.(e)}
|
|
2785
|
+
.onDeleteArchived=${e=>this.onDeleteArchivedSession?.(e)}
|
|
2786
|
+
.onDeleteArchivedMany=${e=>this.onDeleteArchivedSessions?.(e)}
|
|
2787
|
+
.onRename=${(e,t)=>this.onRenameSession?.(e,t)}
|
|
2788
|
+
.onDetachParent=${e=>this.onDetachParentSession?.(e)}
|
|
2789
|
+
.onReload=${e=>this.onReloadSession?.(e)}
|
|
2790
|
+
.onCleanup=${()=>this.onCleanupSessions?.()}
|
|
2791
|
+
.onFocusPreviousSection=${()=>{this.focusPreviousFrom(`sessions`)}}
|
|
2792
|
+
.onFocusNextSection=${()=>{this.focusNextFrom(`sessions`)}}
|
|
2793
|
+
.onCancelKeyboardNavigation=${()=>{this.cancelKeyboardNavigation()}}
|
|
2794
|
+
></session-list>
|
|
2795
|
+
`}async focusNavigableSection(e){return e!==void 0&&await e.focusSelectedOrFirst()}focusPreviousFrom(e){let t=Kx(e,this.machines);t!==void 0&&this.onFocusNavigationTarget?.(t)}focusNextFrom(e){this.onFocusNavigationTarget?.(qx(e,this.machines))}cancelKeyboardNavigation(){this.onCancelKeyboardNavigation?.()}static{this.styles=h`
|
|
2796
|
+
:host { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
|
|
2797
|
+
:host([compact]) { flex: 1 1 auto; }
|
|
2798
|
+
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); }
|
|
2799
|
+
header strong { flex: 0 0 auto; }
|
|
2800
|
+
machine-switcher { flex: 1 1 auto; min-width: 0; }
|
|
2801
|
+
:host([compact]) header { display: none; }
|
|
2802
|
+
.header-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
|
|
2803
|
+
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); }
|
|
2804
|
+
session-list { flex: 1 1 auto; min-height: 0; overflow: hidden; }
|
|
2805
|
+
machine-list[collapsed],
|
|
2806
|
+
project-list[collapsed],
|
|
2807
|
+
workspace-list[collapsed],
|
|
2808
|
+
session-list[collapsed] { flex: 0 0 auto; min-height: auto; overflow: hidden; }
|
|
2809
|
+
:host([compact]) machine-list,
|
|
2810
|
+
:host([compact]) project-list,
|
|
2811
|
+
:host([compact]) workspace-list,
|
|
2812
|
+
:host([compact]) session-list { flex: 1 1 auto; max-height: none; min-height: 0; overflow: hidden; }
|
|
2813
|
+
:host([compact]) machine-list[collapsed],
|
|
2814
|
+
:host([compact]) project-list[collapsed],
|
|
2815
|
+
:host([compact]) workspace-list[collapsed],
|
|
2816
|
+
:host([compact]) session-list[collapsed] { flex: 0 0 auto; min-height: auto; overflow: hidden; }
|
|
2817
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
|
2818
|
+
`}};z([b({attribute:!1})],Z.prototype,`machines`,void 0),z([b({attribute:!1})],Z.prototype,`selectedMachine`,void 0),z([b({attribute:!1})],Z.prototype,`machineStatuses`,void 0),z([b({attribute:!1})],Z.prototype,`machineActivities`,void 0),z([b({attribute:!1})],Z.prototype,`projects`,void 0),z([b({attribute:!1})],Z.prototype,`selectedProject`,void 0),z([b({attribute:!1})],Z.prototype,`workspaces`,void 0),z([b({attribute:!1})],Z.prototype,`selectedWorkspace`,void 0),z([b({attribute:!1})],Z.prototype,`sessions`,void 0),z([b({attribute:!1})],Z.prototype,`selectedSession`,void 0),z([b({attribute:!1})],Z.prototype,`workspaceActivities`,void 0),z([b({attribute:!1})],Z.prototype,`sessionActivities`,void 0),z([b({attribute:!1})],Z.prototype,`sessionStatuses`,void 0),z([b({attribute:!1})],Z.prototype,`sendingPrompts`,void 0),z([b({attribute:!1})],Z.prototype,`workspacesByProjectId`,void 0),z([b({attribute:!1})],Z.prototype,`deletingWorkspaceIds`,void 0),z([b({attribute:!1})],Z.prototype,`workspaceLabelItems`,void 0),z([b({attribute:!1})],Z.prototype,`refreshControl`,void 0),z([b({type:Boolean,reflect:!0})],Z.prototype,`collapsible`,void 0),z([b({type:Boolean,reflect:!0})],Z.prototype,`compact`,void 0),z([b({type:Boolean})],Z.prototype,`machinesCollapsed`,void 0),z([b({type:Boolean})],Z.prototype,`projectsCollapsed`,void 0),z([b({type:Boolean})],Z.prototype,`workspacesCollapsed`,void 0),z([b({type:Boolean})],Z.prototype,`sessionsCollapsed`,void 0),z([b({type:Number})],Z.prototype,`startingSessionCount`,void 0),z([b({type:Boolean})],Z.prototype,`canStartSession`,void 0),z([b({type:Boolean})],Z.prototype,`canDeleteArchivedSessions`,void 0),z([b({type:Boolean})],Z.prototype,`canReloadSessions`,void 0),z([b({type:Boolean})],Z.prototype,`canCleanupSessions`,void 0),z([b({type:Boolean})],Z.prototype,`authoritativeSessionPersistence`,void 0),z([b({type:String})],Z.prototype,`archivedDeleteUnavailableMessage`,void 0),z([b({type:String})],Z.prototype,`cleanupUnavailableMessage`,void 0),z([b({attribute:!1})],Z.prototype,`onShowActions`,void 0),z([b({attribute:!1})],Z.prototype,`onToggleMachines`,void 0),z([b({attribute:!1})],Z.prototype,`onToggleProjects`,void 0),z([b({attribute:!1})],Z.prototype,`onToggleWorkspaces`,void 0),z([b({attribute:!1})],Z.prototype,`onToggleSessions`,void 0),z([b({attribute:!1})],Z.prototype,`onSelectProject`,void 0),z([b({attribute:!1})],Z.prototype,`onCloseProject`,void 0),z([b({attribute:!1})],Z.prototype,`onSelectWorkspace`,void 0),z([b({attribute:!1})],Z.prototype,`onDeleteWorkspace`,void 0),z([b({attribute:!1})],Z.prototype,`onStartSession`,void 0),z([b({attribute:!1})],Z.prototype,`onSelectSession`,void 0),z([b({attribute:!1})],Z.prototype,`onArchiveSession`,void 0),z([b({attribute:!1})],Z.prototype,`onArchiveSessionWithDescendants`,void 0),z([b({attribute:!1})],Z.prototype,`onArchiveSessions`,void 0),z([b({attribute:!1})],Z.prototype,`onRestoreSession`,void 0),z([b({attribute:!1})],Z.prototype,`onDeleteCachedNewSession`,void 0),z([b({attribute:!1})],Z.prototype,`onDeleteArchivedSession`,void 0),z([b({attribute:!1})],Z.prototype,`onDeleteArchivedSessions`,void 0),z([b({attribute:!1})],Z.prototype,`onRenameSession`,void 0),z([b({attribute:!1})],Z.prototype,`onDetachParentSession`,void 0),z([b({attribute:!1})],Z.prototype,`onReloadSession`,void 0),z([b({attribute:!1})],Z.prototype,`onCleanupSessions`,void 0),z([b({attribute:!1})],Z.prototype,`onArchivedCollapsed`,void 0),z([b({attribute:!1})],Z.prototype,`onSelectMachine`,void 0),z([b({attribute:!1})],Z.prototype,`onRemoveMachine`,void 0),z([b({attribute:!1})],Z.prototype,`onFocusNavigationTarget`,void 0),z([b({attribute:!1})],Z.prototype,`onCancelKeyboardNavigation`,void 0),z([S(`machine-list`)],Z.prototype,`machineList`,void 0),z([S(`machine-switcher`)],Z.prototype,`machineSwitcher`,void 0),z([S(`project-list`)],Z.prototype,`projectList`,void 0),z([S(`workspace-list`)],Z.prototype,`workspaceList`,void 0),z([S(`session-list`)],Z.prototype,`sessionList`,void 0),Z=z([y(`app-navigation-panel`)],Z);function Gx(e){return e.length>1}function Kx(e,t){let n=Jx(t);return n[n.indexOf(e)-1]}function qx(e,t){let n=Jx(t);return n[n.indexOf(e)+1]??`chat`}function Jx(e){return tp.filter(t=>t!==`machines`||Gx(e))}var Yx=new Set([`ArrowLeft`,`ArrowRight`,`Home`,`End`]),Xx=420,Zx=4,Q=class extends v{constructor(...e){super(...e),this.side=`navigation`,this.collapsed=!1,this.resizable=!1,this.controls=``,this.resizeLabel=`调整面板宽度`,this.expandLabel=`展开面板`,this.collapseLabel=`折叠面板`,this.lastTapAt=0}disconnectedCallback(){this.finishActiveResize(),super.disconnectedCallback()}render(){let e=this.collapsed?this.expandLabel:this.collapseLabel;return g`
|
|
2819
|
+
${this.renderResizeHandle()}
|
|
2820
|
+
<button
|
|
2821
|
+
type="button"
|
|
2822
|
+
class="edge-button"
|
|
2823
|
+
title=${e}
|
|
2824
|
+
aria-label=${e}
|
|
2825
|
+
aria-controls=${this.controls}
|
|
2826
|
+
aria-expanded=${String(!this.collapsed)}
|
|
2827
|
+
@click=${()=>{this.onToggle?.()}}
|
|
2828
|
+
>${this.renderIcon()}</button>
|
|
2829
|
+
`}renderResizeHandle(){if(!this.resizable)return _;let e=this.resizeConstraints();return g`
|
|
2830
|
+
<div
|
|
2831
|
+
class="resize-handle"
|
|
2832
|
+
role="separator"
|
|
2833
|
+
tabindex="0"
|
|
2834
|
+
aria-label=${this.resizeLabel}
|
|
2835
|
+
title=${`${this.resizeLabel}。双击或双击轻触可重置。`}
|
|
2836
|
+
aria-controls=${this.controls}
|
|
2837
|
+
aria-orientation="vertical"
|
|
2838
|
+
aria-valuemin=${String(e.minWidth)}
|
|
2839
|
+
aria-valuemax=${String(e.maxWidth)}
|
|
2840
|
+
aria-valuenow=${this.resizeAriaValueNow()}
|
|
2841
|
+
@pointerdown=${e=>{this.onResizePointerDown(e)}}
|
|
2842
|
+
@pointermove=${e=>{this.onResizePointerMove(e)}}
|
|
2843
|
+
@pointerup=${e=>{this.onResizePointerUp(e)}}
|
|
2844
|
+
@pointercancel=${e=>{this.onResizePointerCancel(e)}}
|
|
2845
|
+
@dblclick=${e=>{this.onResizeDoubleClick(e)}}
|
|
2846
|
+
@keydown=${e=>{this.onResizeKeyDown(e)}}
|
|
2847
|
+
></div>
|
|
2848
|
+
`}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)<=Zx)&&(t.moved=!0,this.commitPanelWidth(yp(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||!Yx.has(e.key))return;let t=this.resizeStartWidth();if(t===void 0)return;let n=bp(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<=Xx){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 xp(this.side,e,this.resizeConstraints())}commitPanelWidth(e){this.onResize?.(xp(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=_p(this.side);return{...e,minWidth:this.minWidth??e.minWidth,maxWidth:this.maxWidth??e.maxWidth}}static{this.styles=h`
|
|
2849
|
+
: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; }
|
|
2850
|
+
:host([side="navigation"]) { grid-column: 2; }
|
|
2851
|
+
:host([side="workspace"]) { grid-column: 4; }
|
|
2852
|
+
.resize-handle { position: absolute; inset: 0 -6px; z-index: 0; cursor: col-resize; touch-action: none; outline: none; }
|
|
2853
|
+
.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; }
|
|
2854
|
+
.resize-handle:hover::after, .resize-handle:focus-visible::after, :host([resizing]) .resize-handle::after { width: 3px; background: var(--pi-accent); opacity: .72; }
|
|
2855
|
+
.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; }
|
|
2856
|
+
.edge-button:hover, .edge-button:focus-visible { color: var(--pi-text); background: var(--pi-surface-hover); opacity: 1; }
|
|
2857
|
+
:host([side="navigation"][collapsed]) .edge-button { transform: translateX(calc(50% - .5px)); }
|
|
2858
|
+
:host([side="workspace"][collapsed]) .edge-button { transform: translateX(calc(-50% + .5px)); }
|
|
2859
|
+
.edge-icon { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
|
|
2860
|
+
@media (max-width: 1180px) {
|
|
2861
|
+
:host([side="navigation"]) { grid-row: 1 / 3; }
|
|
2862
|
+
:host([side="workspace"]) { display: none; }
|
|
2863
|
+
}
|
|
2864
|
+
@media (max-width: 760px) {
|
|
2865
|
+
:host([side="navigation"]) { display: none; }
|
|
2866
|
+
}
|
|
2867
|
+
`}};z([b({reflect:!0})],Q.prototype,`side`,void 0),z([b({type:Boolean,reflect:!0})],Q.prototype,`collapsed`,void 0),z([b({type:Boolean})],Q.prototype,`resizable`,void 0),z([b({type:Number})],Q.prototype,`panelWidth`,void 0),z([b({type:Number})],Q.prototype,`minWidth`,void 0),z([b({type:Number})],Q.prototype,`maxWidth`,void 0),z([b()],Q.prototype,`controls`,void 0),z([b()],Q.prototype,`resizeLabel`,void 0),z([b()],Q.prototype,`expandLabel`,void 0),z([b()],Q.prototype,`collapseLabel`,void 0),z([b({attribute:!1})],Q.prototype,`onToggle`,void 0),z([b({attribute:!1})],Q.prototype,`onResizeStart`,void 0),z([b({attribute:!1})],Q.prototype,`onResize`,void 0),z([b({attribute:!1})],Q.prototype,`onResizeEnd`,void 0),z([b({attribute:!1})],Q.prototype,`onReset`,void 0),Q=z([y(`app-panel-edge-control`)],Q);var Qx=class extends v{constructor(...e){super(...e),this.onReloadClick=e=>{e.stopPropagation(),this.onReload?.()}}render(){let e=`完整重载页面`;return g`
|
|
2868
|
+
<button
|
|
2869
|
+
class="app-refresh-button"
|
|
2870
|
+
title=${e}
|
|
2871
|
+
aria-label=${e}
|
|
2872
|
+
@click=${this.onReloadClick}
|
|
2873
|
+
>${this.renderRefreshIcon()}</button>
|
|
2874
|
+
`}renderRefreshIcon(){return g`
|
|
2875
|
+
<svg class="app-refresh-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
2876
|
+
<path d="M20 6v5h-5"></path>
|
|
2877
|
+
<path d="M4 18v-5h5"></path>
|
|
2878
|
+
<path d="M18.2 9A7 7 0 0 0 6.1 6.8L4 9"></path>
|
|
2879
|
+
<path d="M5.8 15a7 7 0 0 0 12.1 2.2L20 15"></path>
|
|
2880
|
+
</svg>
|
|
2881
|
+
`}static{this.styles=h`
|
|
2882
|
+
: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; }
|
|
2883
|
+
:host, :host * { -webkit-user-select: none; user-select: none; }
|
|
2884
|
+
.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; }
|
|
2885
|
+
.app-refresh-icon { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
|
|
2886
|
+
`}};z([b({attribute:!1})],Qx.prototype,`onReload`,void 0),Qx=z([y(`app-refresh-control`)],Qx);var $x=h`
|
|
2887
|
+
/* Mobile browsers already subtract browser controls from 100dvh; reserve bottom safe area only in standalone PWA modes. */
|
|
2888
|
+
: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; }
|
|
2889
|
+
:host([pwa-display-mode]) { --pi-app-safe-area-bottom: env(safe-area-inset-bottom); }
|
|
2890
|
+
@media (display-mode: standalone), (display-mode: fullscreen), (display-mode: minimal-ui) {
|
|
2891
|
+
:host { --pi-app-safe-area-bottom: env(safe-area-inset-bottom); }
|
|
2892
|
+
}
|
|
2893
|
+
.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); grid-template-rows: minmax(0, 1fr); height: 100%; max-height: 100%; min-height: 0; overflow: hidden; }
|
|
2894
|
+
aside { grid-column: 1; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
|
|
2895
|
+
aside app-navigation-panel { flex: 1 1 auto; min-height: 0; }
|
|
2896
|
+
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); }
|
|
2897
|
+
.header-actions { display: flex; align-items: center; gap: 8px; }
|
|
2898
|
+
project-list, workspace-list { flex: 0 0 auto; max-height: 26%; min-height: 0; overflow: hidden; border-bottom: 1px solid var(--pi-border-muted); }
|
|
2899
|
+
session-list { flex: 1 1 auto; min-height: 0; overflow: hidden; }
|
|
2900
|
+
main { grid-column: 3; display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }
|
|
2901
|
+
.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); }
|
|
2902
|
+
.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; }
|
|
2903
|
+
.context-bar::before { left: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
2904
|
+
.context-bar::after { right: 0; background: linear-gradient(270deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
2905
|
+
.context-bar.can-scroll-left::before, .context-bar.can-scroll-right::after { opacity: 1; }
|
|
2906
|
+
.context-bar-label { display: none; }
|
|
2907
|
+
.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; }
|
|
2908
|
+
.context-bar.has-context-actions .context-items { padding-right: 52px; scroll-padding-inline: 8px 52px; }
|
|
2909
|
+
.context-item { flex: 0 0 auto; min-width: 0; display: flex; }
|
|
2910
|
+
.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; }
|
|
2911
|
+
.context-actions::after { content: ""; position: absolute; top: 0; right: 0; bottom: 0; z-index: 0; width: 26px; background: var(--pi-bg); pointer-events: none; }
|
|
2912
|
+
.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; }
|
|
2913
|
+
.context-chip:hover { background: var(--pi-surface-hover); }
|
|
2914
|
+
.context-chip:focus-visible { outline: 2px solid var(--pi-accent); outline-offset: 2px; }
|
|
2915
|
+
.context-chip.empty { border-style: dashed; color: var(--pi-muted); }
|
|
2916
|
+
.context-kind { display: none; }
|
|
2917
|
+
.context-value { min-width: 0; overflow: visible; text-overflow: clip; white-space: nowrap; }
|
|
2918
|
+
app-mobile-main-tabs { display: none; }
|
|
2919
|
+
.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); }
|
|
2920
|
+
.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; }
|
|
2921
|
+
.mobile-tabs-frame::before { left: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
2922
|
+
.mobile-tabs-frame::after { right: 0; background: linear-gradient(270deg, color-mix(in srgb, var(--pi-shadow-strong) 55%, transparent) 0%, transparent 100%); }
|
|
2923
|
+
.mobile-tabs-frame.can-scroll-left::before, .mobile-tabs-frame.can-scroll-right::after { opacity: 1; }
|
|
2924
|
+
.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; }
|
|
2925
|
+
.mobile-tabs button { flex: 0 0 auto; white-space: nowrap; }
|
|
2926
|
+
.mobile-navigation-tab, .mobile-navigation-panel { display: none; }
|
|
2927
|
+
.mobile-tabs button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
|
|
2928
|
+
.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; }
|
|
2929
|
+
.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; }
|
|
2930
|
+
.navigation-panel-edge { grid-column: 2; }
|
|
2931
|
+
.workspace-panel-edge { grid-column: 4; }
|
|
2932
|
+
.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; }
|
|
2933
|
+
.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; }
|
|
2934
|
+
.shell.navigation-panel-collapsed .navigation-panel-edge-button { transform: translateX(calc(50% - .5px)); }
|
|
2935
|
+
.shell.workspace-panel-collapsed .workspace-panel-edge-button { transform: translateX(calc(-50% + .5px)); }
|
|
2936
|
+
.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; }
|
|
2937
|
+
workspace-panel { grid-column: 5; min-width: 0; min-height: 0; overflow: hidden; }
|
|
2938
|
+
@media (min-width: 1181px) {
|
|
2939
|
+
.shell > aside, .shell > .navigation-panel-edge, .shell > main, .shell > .workspace-panel-edge, .shell > workspace-panel { grid-row: 1; height: 100%; max-height: 100%; }
|
|
2940
|
+
.shell.navigation-panel-collapsed { --navigation-panel-width: 0px; }
|
|
2941
|
+
.shell.navigation-panel-collapsed > aside { display: none; }
|
|
2942
|
+
.shell.workspace-panel-collapsed { --workspace-panel-width: 0px; }
|
|
2943
|
+
.shell.workspace-panel-collapsed > workspace-panel { display: none; }
|
|
2944
|
+
}
|
|
2945
|
+
@media (max-width: 1180px) {
|
|
2946
|
+
.shell { grid-template-columns: var(--navigation-panel-width) 1px minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
|
|
2947
|
+
.shell.navigation-panel-collapsed { --navigation-panel-width: 0px; }
|
|
2948
|
+
.shell.navigation-panel-collapsed > aside { display: none; }
|
|
2949
|
+
aside { grid-row: 1 / 3; }
|
|
2950
|
+
.navigation-panel-edge { grid-row: 1 / 3; }
|
|
2951
|
+
main { grid-column: 3; grid-row: 1 / 3; }
|
|
2952
|
+
app-mobile-main-tabs { display: block; flex: 0 0 auto; min-width: 0; }
|
|
2953
|
+
.mobile-tabs-frame { display: flex; }
|
|
2954
|
+
.shell.workspace-view main { grid-row: 1; min-height: auto; }
|
|
2955
|
+
.shell.workspace-view > workspace-panel { grid-column: 3; grid-row: 2; display: flex; border-left: 0; }
|
|
2956
|
+
.shell:not(.workspace-view) > workspace-panel { display: none; }
|
|
2957
|
+
.workspace-panel-edge { display: none; }
|
|
2958
|
+
main.workspace-view chat-view, main.workspace-view prompt-editor, main.workspace-view status-bar,
|
|
2959
|
+
main.workspace-view .empty { display: none; }
|
|
2960
|
+
main.workspace-view { overflow: hidden; }
|
|
2961
|
+
}
|
|
2962
|
+
@media (max-width: 760px) {
|
|
2963
|
+
.shell { grid-template-columns: minmax(0, 1fr); }
|
|
2964
|
+
aside, .navigation-panel-edge { display: none; }
|
|
2965
|
+
main, .shell.workspace-view > workspace-panel { grid-column: 1; }
|
|
2966
|
+
.context-bar { display: flex; }
|
|
2967
|
+
.mobile-navigation-tab { display: block; }
|
|
2968
|
+
main.navigation-view chat-view, main.navigation-view prompt-editor, main.navigation-view status-bar,
|
|
2969
|
+
main.navigation-view .empty { display: none; }
|
|
2970
|
+
main.navigation-view .mobile-navigation-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
|
|
2971
|
+
main.navigation-view .mobile-navigation-panel app-navigation-panel { flex: 1 1 auto; min-height: 0; }
|
|
2972
|
+
main.navigation-view .mobile-navigation-panel project-list,
|
|
2973
|
+
main.navigation-view .mobile-navigation-panel workspace-list,
|
|
2974
|
+
main.navigation-view .mobile-navigation-panel session-list { flex: 1 1 auto; max-height: none; min-height: 0; overflow: hidden; }
|
|
2975
|
+
main.navigation-view .mobile-navigation-panel project-list[collapsed],
|
|
2976
|
+
main.navigation-view .mobile-navigation-panel workspace-list[collapsed],
|
|
2977
|
+
main.navigation-view .mobile-navigation-panel session-list[collapsed] { flex: 0 0 auto; min-height: auto; overflow: hidden; }
|
|
2978
|
+
}
|
|
2979
|
+
status-bar { flex: 0 0 auto; }
|
|
2980
|
+
chat-view { flex: 1 1 0; min-height: 0; max-height: 100%; overflow: hidden; contain: size layout; }
|
|
2981
|
+
prompt-editor { flex: 0 0 auto; }
|
|
2982
|
+
button { border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-surface); color: var(--pi-text); padding: 7px 9px; cursor: pointer; }
|
|
2983
|
+
.empty { margin: auto; color: var(--pi-muted); }
|
|
2984
|
+
.error { padding: 10px 16px; border-bottom: 1px solid var(--pi-border); color: var(--pi-danger); }
|
|
2985
|
+
`,eS=900*1e3,tS=750,nS=[1e3,3e3,8e3,15e3,3e4],rS={capture:!0},iS=`auto:on`,aS=`auto:off`,oS=`theme:`,sS=Ba(`core:workspace.files`),cS=Ba(`core:workspace.git`),lS=Ba(`core:workspace.terminal`),uS=320,dS=2,fS=`(min-width: 1181px)`,$=class extends v{constructor(...e){super(...e),this.state=ka(),this.apiScope=mS(),this.sessions=new nl(()=>this.state,e=>{this.setState(e)},()=>{this.updateUrl()},new Kc,{socket:new Tc(this.apiScope)}),this.activity=new Fa(()=>this.state,e=>{this.setState(e)}),this.auth=new Ra(()=>this.state,e=>{this.setState(e)},e=>{this.sessions.applySessionStatus(e)},{scope:this.apiScope}),this.workspaces=new Al(()=>this.state,e=>{this.setState(e)},()=>{this.updateUrl()},this.sessions,new Ol),this.projects=new fo(()=>this.state,e=>{this.setState(e)},this.workspaces),this.machines=new co(()=>this.state,e=>{this.setState(e)},()=>{this.updateUrl()},this.projects),this.piWebStatusController=new po(()=>this.state,e=>{this.setState(e)},{onRefreshError:(e,t)=>{console.warn(`Failed to refresh PI WEB status for ${e}`,t)}}),this.files=new $a(()=>this.state,e=>{this.setState(e)},()=>{this.updateUrl()}),this.git=new so(()=>this.state,e=>{this.setState(e)},()=>{this.updateUrl()}),this.keyboard=new Ql,this.realtime=new Ec(this.apiScope),this.machineActivitySockets=new Map,this.activeTerminalIds=new Set,this.machineNavigation=new Pl,this.terminalSelection=new ql,this.appShell=new Kf(this),this.browserResume=new Xf({onResumeSignal:()=>{this.handleBrowserResumeSignal()},refreshAfterResume:()=>this.refreshAfterBrowserResume(),onRefreshError:e=>{console.warn(`Failed to refresh after browser resume`,e)}}),this.panelCollapse=new fp(this),this.panelResize=new gp(this),this.navigationSections=new lp(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=pS(),this.loadedMachinePluginIds=new Set,this.machinePluginLoadPromises=new Map,this.themePreference=Bu()??Iu,this.activeThemeId=Fu,this.isRefreshingApp=!1,this.settingsSection=Lp(),this.normalAuthLoading=!0,this.normalAuthError=``,this.shortcutConfig={},this.workspaceUploadDefaultFolder=la(void 0),this.appStartupStarted=!1,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.previousStackedWorkspaceLayout=this.appShell.isStackedWorkspaceLayout,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.handleSelectModel=()=>{this.openModelDialog()},this.handleSelectThinking=()=>{this.openThinkingDialog()}}get routeRestoreInProgress(){return this.routeRestoreDepth>0}willUpdate(){this.toggleAttribute(`pwa-display-mode`,this.appShell.isPwaDisplayMode),this.normalizeMainViewForLayoutChange()}connectedCallback(){super.connectedCallback(),window.addEventListener(`popstate`,this.onPopState),window.addEventListener(`pageshow`,this.onPageShow),this.browserResume.connect(),window.addEventListener(`keydown`,this.onKeyDown,rS),this.systemLightThemeMedia?.addEventListener(`change`,this.onSystemLightThemeChange),this.applyPreferredTheme(!1),this.initializeNormalAuth()}startAuthenticatedApp(){this.appStartupStarted||(this.appStartupStarted=!0,this.connectRealtime(),this.piWebStatusTimer=window.setInterval(()=>{this.schedulePiWebStatusRefresh()},eS),this.refreshWorkspaceActivity(),this.loadClientConfig(),this.ensureGatewayPluginsLoaded(),this.loadProjectsAndRestoreRoute().finally(()=>{this.schedulePiWebStatusRefresh()}))}async initializeNormalAuth(){if(this.apiScope===`management`){this.normalAuthStatus={configured:!0,authenticated:!0},this.normalAuthLoading=!1,this.startAuthenticatedApp();return}this.normalAuthLoading=!0,this.normalAuthError=``;try{let e=await zi.status();this.normalAuthStatus=e,e.authenticated&&this.startAuthenticatedApp()}catch(e){this.normalAuthError=`检查普通模式密码失败:${TS(e)}`}finally{this.normalAuthLoading=!1}}disconnectedCallback(){window.removeEventListener(`popstate`,this.onPopState),window.removeEventListener(`pageshow`,this.onPageShow),this.browserResume.disconnect(),window.removeEventListener(`keydown`,this.onKeyDown,rS),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(!yS(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),gS(t,this.state)&&this.syncMachineActivitySubscriptions()}async loadProjectsAndRestoreRoute(){this.restoreSettingsRoute();let e=Mp();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=tS){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=L(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?[L(this.state)]:this.state.machines.filter(e=>vS(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 Ri.config()).effectiveConfig)}catch(e){console.warn(`Failed to load PI WEB config`,e)}}applyClientConfig(e){this.shortcutConfig=e.shortcuts??{},this.workspaceUploadDefaultFolder=la(e)}async submitNormalAuth(e){let t=this.normalAuthDialogMode??this.normalAuthGateMode();if(!(t===void 0||this.normalAuthLoading)){this.normalAuthLoading=!0,this.normalAuthError=``;try{t===`setup`?await zi.setup(e.password):t===`change`?await zi.changePassword(e.currentPassword??``,e.password):await zi.login(e.password);let n=await zi.status();this.normalAuthStatus=n,this.normalAuthDialogMode=void 0,n.authenticated&&this.startAuthenticatedApp()}catch(e){this.normalAuthError=TS(e)}finally{this.normalAuthLoading=!1}}}normalAuthGateMode(){if(this.apiScope!==`management`&&this.normalAuthStatus?.authenticated!==!0)return this.normalAuthStatus?.configured===!0?`login`:`setup`}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(Mp(),e),this.rememberCurrentMachineNavigation()}async restoreRouteFor(e,t,n=this.readWorkspaceRouteSurface(e),r){let i=L(this.state),a=e.projectId===void 0||e.projectId===``?SS():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:this.appShell.normalizedMainView(r??e.view,e.sessionId!==void 0),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),L(this.state)!==i&&this.schedulePiWebStatusRefresh()}}isCurrentRouteRestore(e){return e===this.routeRestoreSeq}readWorkspaceRouteSurface(e){return e.projectId===void 0||e.projectId===``?SS():{selectedFilePath:Ha(sS,`file`),selectedDiffPath:Ha(cS,`diff`),selectedTerminalId:Ha(lS,`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){Np(e,{replace:!0}),Ua(sS,`file`,void 0,{replace:!0}),Ua(cS,`diff`,void 0,{replace:!0}),Ua(lS,`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=wS(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>=nS.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 DS(),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()}normalizeMainViewForLayoutChange(){let e=this.previousStackedWorkspaceLayout,t=this.appShell.isStackedWorkspaceLayout;if(this.previousStackedWorkspaceLayout=t,e||!t)return;let n=this.appShell.normalizedMainView(this.state.mainView,this.state.selectedSession!==void 0);n!==this.state.mainView&&(this.setState({mainView:n}),this.updateUrl({replace:!0}))}updateUrl(e){this.rememberCurrentMachineNavigation(),Np({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(Il(this.state))}syncWorkspaceRouteSurfaceToUrl(){this.writeWorkspaceRouteSurfaceToUrl(Il(this.state).surface)}writeMachineNavigationSnapshotToUrl(e,t){Np(Ll(e),t),this.writeWorkspaceRouteSurfaceToUrl(e.surface)}writeWorkspaceRouteSurfaceToUrl(e){Ua(sS,`file`,e.selectedFilePath,{replace:!0}),Ua(cS,`diff`,e.selectedDiffPath,{replace:!0}),Ua(lS,`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(Ll(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=L(this.state)){let n=CS(t,e),r=this.terminalCommandRunRuntimes.get(n);if(r!==void 0)return r;let i=Wp(e,{api:{runTerminalCommand:(e,n)=>Ji.runTerminalCommand(e,n,t),listCommandRuns:e=>Ji.listCommandRuns(e,t),getCommandRun:e=>Ji.getCommandRun(e,t)},openTerminal:(e,n)=>{this.openRuntimeTerminal(t,e,n)}});return this.terminalCommandRunRuntimes.set(n,i),i}async openRuntimeTerminal(e,t,n){if((L(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`),L(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){Ua(lS,`terminal`,e,t)}terminalWorkspaceKey(e){return`${L(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,Rp(e)}closeSettings(){this.settingsSection=void 0,Rp(void 0)}navigateSettings(e){this.settingsSection=e,Rp(e)}restoreSettingsRoute(){this.settingsSection=Lp()}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()},L(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 Ec(this.apiScope);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=L(this.state);return new Set(this.state.machines.filter(t=>t.id!==e).filter(e=>_S(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):xS(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=L(this.state);try{let n=await Ji.terminals(e.projectId,e.id,t);if(L(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=bS(e),r=bS(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`
|
|
2986
|
+
<workspace-panel
|
|
2987
|
+
id="workspace-panel"
|
|
2988
|
+
.workspace=${e}
|
|
2989
|
+
.panelContext=${e===void 0?void 0:this.createWorkspacePanelContext(e)}
|
|
2990
|
+
.emptyState=${e===void 0?this.workspacePanelEmptyState():void 0}
|
|
2991
|
+
.tool=${this.state.workspaceTool}
|
|
2992
|
+
.panels=${this.visibleWorkspacePanels()}
|
|
2993
|
+
.onSelectTool=${e=>{this.openWorkspaceTool(e)}}
|
|
2994
|
+
></workspace-panel>
|
|
2995
|
+
`}renderNavigationPanelEdgeControl(){let e=this.resizablePanelConstraints(`navigation`);return g`
|
|
2996
|
+
<app-panel-edge-control
|
|
2997
|
+
side="navigation"
|
|
2998
|
+
controls="navigation-panel"
|
|
2999
|
+
resizeLabel="调整导航面板大小"
|
|
3000
|
+
expandLabel="展开导航面板"
|
|
3001
|
+
collapseLabel="折叠导航面板"
|
|
3002
|
+
.collapsed=${this.panelCollapse.navigationPanelCollapsed}
|
|
3003
|
+
.resizable=${!this.appShell.isMobileNavigationLayout}
|
|
3004
|
+
.panelWidth=${this.panelResize.panelWidth(`navigation`)}
|
|
3005
|
+
.minWidth=${e.minWidth}
|
|
3006
|
+
.maxWidth=${e.maxWidth}
|
|
3007
|
+
.onToggle=${()=>{this.panelCollapse.toggleNavigationPanel()}}
|
|
3008
|
+
.onResizeStart=${()=>this.startPanelResize(`navigation`)}
|
|
3009
|
+
.onResize=${e=>{this.panelResize.resizePanel(`navigation`,e,{persist:!1})}}
|
|
3010
|
+
.onResizeEnd=${()=>{this.panelResize.persistPanelSizes()}}
|
|
3011
|
+
.onReset=${()=>{this.resetResizablePanel(`navigation`)}}
|
|
3012
|
+
></app-panel-edge-control>
|
|
3013
|
+
`}renderWorkspacePanelEdgeControl(){let e=this.resizablePanelConstraints(`workspace`);return g`
|
|
3014
|
+
<app-panel-edge-control
|
|
3015
|
+
side="workspace"
|
|
3016
|
+
controls="workspace-panel"
|
|
3017
|
+
resizeLabel="调整工作区面板大小"
|
|
3018
|
+
expandLabel="展开工作区面板"
|
|
3019
|
+
collapseLabel="折叠工作区面板"
|
|
3020
|
+
.collapsed=${this.panelCollapse.workspacePanelCollapsed}
|
|
3021
|
+
.resizable=${!this.appShell.isMobileNavigationLayout}
|
|
3022
|
+
.panelWidth=${this.panelResize.panelWidth(`workspace`)}
|
|
3023
|
+
.minWidth=${e.minWidth}
|
|
3024
|
+
.maxWidth=${e.maxWidth}
|
|
3025
|
+
.onToggle=${()=>{this.panelCollapse.toggleWorkspacePanel()}}
|
|
3026
|
+
.onResizeStart=${()=>this.startPanelResize(`workspace`)}
|
|
3027
|
+
.onResize=${e=>{this.panelResize.resizePanel(`workspace`,e,{persist:!1})}}
|
|
3028
|
+
.onResizeEnd=${()=>{this.panelResize.persistPanelSizes()}}
|
|
3029
|
+
.onReset=${()=>{this.resetResizablePanel(`workspace`)}}
|
|
3030
|
+
></app-panel-edge-control>
|
|
3031
|
+
`}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-dS-uS);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(fS).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||en(e,M.sessionsDeleteArchived)}canReloadSessions(){let e=this.selectedMachineRuntime();return e?.ok===!0&&en(e,M.sessionsReload)}canClearServerQueue(){let e=this.selectedMachineRuntime();return e?.ok===!0&&en(e,M.sessionsClearQueue)}canCleanupSessions(){let e=this.selectedMachineRuntime();return e?.ok===!0&&en(e,M.sessionsCleanup)}hasAuthoritativeSessionPersistence(){return Nc(this.selectedMachineRuntime())}supportsWorkspaceFileSuggestions(e=L(this.state)){if(e===`local`)return!0;let t=this.state.machineRuntimes[e];return t?.ok===!0&&en(t,M.workspaceFileSuggestions)}archivedDeleteUnavailableMessage(){return`请更新并重启 ${this.state.selectedMachine?.name??`此机器`} 上的 Pi-Web 后再删除已归档会话。`}sessionCleanupUnavailableMessage(){return Nu(this.state.selectedMachine?.name)}selectedMachineRuntime(){return this.state.machineRuntimes[L(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=L(this.state);this.sessionCleanupDialog={...this.sessionCleanupDialog??{},loading:!0,error:``,preview:void 0,previewRequest:void 0,result:void 0};try{let n=await qi.cleanupPreview(e,t);if(L(this.state)!==t)return;this.sessionCleanupDialog={...this.sessionCleanupDialog,preview:n,previewRequest:e,result:void 0,loading:!1,error:``}}catch(e){L(this.state)===t&&(this.sessionCleanupDialog={...this.sessionCleanupDialog,loading:!1,error:`预览清理失败:${TS(e)}`})}}async runSessionCleanup(e){let t=this.sessionCleanupDialog;if(t?.preview===void 0||Eu(t.previewRequest)!==Eu(e)){this.sessionCleanupDialog={...t??{},error:`运行清理前请先预览。`};return}if(!this.canCleanupSessions()){this.sessionCleanupDialog={...t,error:this.sessionCleanupUnavailableMessage(),running:!1};return}let n=L(this.state);this.sessionCleanupDialog={...t,running:!0,error:``};try{let t=await qi.cleanup(e,n);if(L(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){L(this.state)===n&&(this.sessionCleanupDialog={...this.sessionCleanupDialog,running:!1,error:`运行清理失败:${TS(e)}`})}}renderNavigationPanel(){return g`
|
|
3032
|
+
<app-navigation-panel
|
|
3033
|
+
.machines=${this.state.machines}
|
|
3034
|
+
.selectedMachine=${this.state.selectedMachine}
|
|
3035
|
+
.machineStatuses=${this.state.machineStatuses}
|
|
3036
|
+
.machineActivities=${this.state.machineActivities}
|
|
3037
|
+
.machinesCollapsed=${this.navigationSections.isCollapsed(`machines`)}
|
|
3038
|
+
.onToggleMachines=${()=>{this.navigationSections.toggle(`machines`)}}
|
|
3039
|
+
.onSelectMachine=${e=>this.selectNavigationItem(`machines`,`projects`,()=>this.selectMachineWithMemory(e))}
|
|
3040
|
+
.onRemoveMachine=${e=>{this.removeMachine(e)}}
|
|
3041
|
+
.projects=${this.state.projects}
|
|
3042
|
+
.selectedProject=${this.state.selectedProject}
|
|
3043
|
+
.workspaceActivities=${this.state.workspaceActivities}
|
|
3044
|
+
.workspacesByProjectId=${this.state.workspacesByProjectId}
|
|
3045
|
+
.workspaces=${this.state.workspaces}
|
|
3046
|
+
.selectedWorkspace=${this.state.selectedWorkspace}
|
|
3047
|
+
.deletingWorkspaceIds=${td(this.state.workspaceDeletionRuns)}
|
|
3048
|
+
.sessions=${this.state.sessions}
|
|
3049
|
+
.sessionStatuses=${this.state.sessionStatuses}
|
|
3050
|
+
.sessionActivities=${this.state.sessionActivities}
|
|
3051
|
+
.sendingPrompts=${this.state.sendingPrompts}
|
|
3052
|
+
.selectedSession=${this.state.selectedSession}
|
|
3053
|
+
.startingSessionCount=${this.state.startingSessionCount}
|
|
3054
|
+
.canStartSession=${!!this.state.selectedWorkspace}
|
|
3055
|
+
.canDeleteArchivedSessions=${this.canDeleteArchivedSessions()}
|
|
3056
|
+
.canReloadSessions=${this.canReloadSessions()}
|
|
3057
|
+
.canCleanupSessions=${this.canCleanupSessions()}
|
|
3058
|
+
.authoritativeSessionPersistence=${this.hasAuthoritativeSessionPersistence()}
|
|
3059
|
+
.archivedDeleteUnavailableMessage=${this.archivedDeleteUnavailableMessage()}
|
|
3060
|
+
.cleanupUnavailableMessage=${this.sessionCleanupUnavailableMessage()}
|
|
3061
|
+
.collapsible=${!0}
|
|
3062
|
+
.compact=${this.appShell.isMobileNavigationLayout}
|
|
3063
|
+
.projectsCollapsed=${this.navigationSections.isCollapsed(`projects`)}
|
|
3064
|
+
.workspacesCollapsed=${this.navigationSections.isCollapsed(`workspaces`)}
|
|
3065
|
+
.sessionsCollapsed=${this.navigationSections.isCollapsed(`sessions`)}
|
|
3066
|
+
.workspaceLabelItems=${e=>this.workspaceLabelItems(e)}
|
|
3067
|
+
.refreshControl=${this.appShell.shouldShowAppRefreshInHeader()?this.renderAppRefresh():void 0}
|
|
3068
|
+
.onShowActions=${()=>{this.setState({actionPaletteOpen:!0})}}
|
|
3069
|
+
.onToggleProjects=${()=>{this.navigationSections.toggle(`projects`)}}
|
|
3070
|
+
.onToggleWorkspaces=${()=>{this.navigationSections.toggle(`workspaces`)}}
|
|
3071
|
+
.onToggleSessions=${()=>{this.navigationSections.toggle(`sessions`)}}
|
|
3072
|
+
.onSelectProject=${e=>this.selectNavigationItem(`projects`,`workspaces`,()=>this.workspaces.selectProject(e))}
|
|
3073
|
+
.onCloseProject=${e=>this.projects.closeProject(e.id)}
|
|
3074
|
+
.onSelectWorkspace=${e=>this.selectNavigationItem(`workspaces`,`sessions`,()=>this.workspaces.selectWorkspace(e))}
|
|
3075
|
+
.onDeleteWorkspace=${e=>{this.deleteWorkspace(e)}}
|
|
3076
|
+
.onArchivedCollapsed=${()=>{this.sessions.clearSelectionAfterArchivedCollapse()}}
|
|
3077
|
+
.onStartSession=${()=>this.startSessionFromNavigation()}
|
|
3078
|
+
.onSelectSession=${e=>this.selectNavigationItem(`sessions`,`chat`,()=>this.sessions.selectSession(e))}
|
|
3079
|
+
.onArchiveSession=${e=>this.sessions.archiveSession(e)}
|
|
3080
|
+
.onArchiveSessionWithDescendants=${e=>this.sessions.archiveSessionWithDescendants(e)}
|
|
3081
|
+
.onArchiveSessions=${e=>this.sessions.archiveSessions(e)}
|
|
3082
|
+
.onRestoreSession=${e=>this.selectNavigationItem(`sessions`,`chat`,()=>this.sessions.restoreSession(e))}
|
|
3083
|
+
.onDeleteCachedNewSession=${e=>this.sessions.deleteCachedNewSession(e)}
|
|
3084
|
+
.onDeleteArchivedSession=${e=>this.sessions.deleteArchivedSessions([e])}
|
|
3085
|
+
.onDeleteArchivedSessions=${e=>this.sessions.deleteArchivedSessions(e)}
|
|
3086
|
+
.onRenameSession=${(e,t)=>this.sessions.renameSession(e,t)}
|
|
3087
|
+
.onDetachParentSession=${e=>this.sessions.detachParent(e)}
|
|
3088
|
+
.onReloadSession=${e=>this.sessions.reloadSession(e)}
|
|
3089
|
+
.onCleanupSessions=${()=>{this.openSessionCleanupDialog()}}
|
|
3090
|
+
.onFocusNavigationTarget=${e=>{this.focusNavigationTarget(e)}}
|
|
3091
|
+
.onCancelKeyboardNavigation=${()=>{this.focusChatComposer()}}
|
|
3092
|
+
></app-navigation-panel>
|
|
3093
|
+
`}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`&&!Gx(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 DS(),await this.navigationPanel?.focusSection(e)}async focusChatComposer(){this.state.mainView!==`chat`&&this.selectMainView(`chat`),await this.updateComplete,await DS(),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:`正在加载项目…`,body:`正在查找你已添加到 PI WEB 的项目。`}:e===void 0?this.state.projects.length===0?{title:`还没有项目`,body:`使用“操作 → 添加项目”添加文件夹。选择工作区后,工作区工具会显示在这里。`}:{title:`选择项目`,body:`从侧边栏选择一个项目,然后选择工作区来查看文件、Git 或终端。`}:this.state.isLoadingWorkspaces?{title:`正在加载工作区…`,body:`正在为 ${e.name} 准备工作区工具。`}:this.state.workspaces.length===0?{title:`未找到工作区`,body:`${e.name} 没有可用工作区。请尝试重新选择该项目,或重新添加它。`}:{title:`选择工作区`,body:`选择 ${e.name} 中的工作区,以查看文件、Git 或终端。`}}sessionEmptyMessage(){return this.state.isLoadingProjects?`正在加载项目…`:this.state.selectedWorkspace===void 0?this.state.selectedProject===void 0?this.state.projects.length===0?`添加项目以启动会话。`:`选择项目和工作区以开始会话。`:`选择工作区以启动会话。`:`选择或启动会话。`}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=hS(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=>Ki.workspaceFile(e.projectId,e.id,n,t),readOptionalFile:n=>Ki.optionalWorkspaceFile(e.projectId,e.id,n,t),writeFile:async(n,r,i)=>{let a=await Ki.writeWorkspaceFile(e.projectId,e.id,n,r,i,t);return this.files.refreshFiles(),a},deleteFile:async n=>{let r=await Ki.deleteWorkspaceFile(e.projectId,e.id,n,t);return this.files.refreshFiles(),r},moveFile:async(n,r,i)=>{let a=await Ki.moveWorkspaceFile(e.projectId,e.id,n,r,i,t);return this.files.refreshFiles(),a}}}createWorkspaceHost(){return{requestRender:()=>{this.requestUpdate()}}}createWorkspacePanelContext(e){let t=hS(this.state),n=t.id,r=i=>{let a=this.terminalCommandRunsForOrigin(i,n);return Nf({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:ua(e.effectiveConfig,this.workspaceUploadDefaultFolder),onRefreshFiles:()=>{this.files.refreshFiles()},onCreateFile:e=>{this.files.createFile(e)},onCreateDirectory:e=>{this.files.createDirectory(e)},onMoveSelectedPath:e=>{this.files.moveSelectedPath(e)},onDeleteSelectedPath:()=>{this.files.deleteSelectedPath()},onDownloadSelectedFile:()=>{this.files.downloadSelectedFile()},onExpandDir:e=>{this.files.expandDir(e)},onSelectDirectory:e=>{this.files.selectDirectory(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 Vp(this.getDefaultActions(),this.shortcutConfig)}getDefaultActions(){return[...this.plugins.getActions(this.createPluginRuntimeContext()),...this.normalAuthActions(),...this.sessionActions(),...this.navigationFocusActions(),...this.panelLayoutActions()]}normalAuthActions(){return this.apiScope===`management`?[]:[{id:`app.normal-auth.change-password`,title:`修改普通模式密码`,description:`更改进入普通模式所需的本地密码`,group:`偏好设置`,enabled:this.normalAuthStatus?.authenticated===!0,run:()=>{this.normalAuthDialogMode=`change`,this.normalAuthError=``}}]}sessionActions(){return[{id:`app.sessions.cleanup`,title:`清理会话`,description:`预览并手动清理所选机器上的空闲或已归档会话`,group:`Sessions`,...this.canCleanupSessions()?{}:{enabled:!1,disabledReason:this.sessionCleanupUnavailableMessage()},run:()=>{this.openSessionCleanupDialog()}}]}panelLayoutActions(){return[{id:`app.layout.reset-navigation-panel-size`,title:`重置导航面板宽度`,description:`将导航面板恢复为默认宽度`,group:`视图`,run:()=>{this.resetResizablePanel(`navigation`)}},{id:`app.layout.reset-workspace-panel-size`,title:`重置工作区面板宽度`,description:`将工作区面板恢复为默认宽度`,group:`视图`,run:()=>{this.resetResizablePanel(`workspace`)}},{id:`app.layout.reset-panel-sizes`,title:`重置面板宽度`,description:`将所有侧边面板恢复为默认宽度`,group:`视图`,run:()=>{this.resetResizablePanels()}}]}navigationFocusActions(){return[{id:`app.navigation.focus-machines`,title:`聚焦机器`,description:`将键盘焦点移到机器选择器`,shortcut:`mod+g m`,group:`导航`,run:()=>this.focusNavigationSection(`machines`)},{id:`app.navigation.focus-projects`,title:`聚焦项目`,description:`将键盘焦点移到项目列表`,shortcut:`mod+g p`,group:`导航`,run:()=>this.focusNavigationSection(`projects`)},{id:`app.navigation.focus-workspaces`,title:`聚焦工作区`,description:`将键盘焦点移到工作区列表`,shortcut:`mod+g w`,group:`导航`,run:()=>this.focusNavigationSection(`workspaces`)},{id:`app.navigation.focus-sessions`,title:`聚焦会话`,description:`将键盘焦点移到会话列表`,shortcut:`mod+g s`,group:`导航`,run:()=>this.focusNavigationSection(`sessions`)}]}ensureGatewayPluginsLoaded(){return this.gatewayPluginLoadPromise??=this.loadExternalPlugins(),this.gatewayPluginLoadPromise}async loadExternalPlugins(){await this.registerExternalPlugins(`PI WEB plugins`,()=>gf())}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}`,()=>gf(`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=>Mf({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(!jl(e)){this.setState({error:`Only secondary Git worktrees can be deleted`});return}if(nd(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=L(this.state);try{let t=await Ki.deleteWorkspace(e.projectId,e.id,n);if(L(this.state)!==n)return;this.recordWorkspaceDeletionRun(t,n);let r=await this.workspaceForCommandRun(t);if(L(this.state)!==n)return;r!==void 0&&this.openRuntimeTerminal(n,r,{terminalId:t.terminalId})}catch(e){L(this.state)===n&&this.setState({error:`启动工作区删除失败:${TS(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(L(this.state)!==t)return;let n=rd(e);n!==void 0&&(this.setState({workspaceDeletionRuns:{...this.state.workspaceDeletionRuns,[n]:e}}),this.updateWorkspaceDeletionPolling())}async refreshWorkspaceDeletionRuns(){if(this.refreshingWorkspaceDeletionRuns)return;let e=L(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($u(t.id));if(L(this.state)!==e)return;let r=ed(n);this.setState({workspaceDeletionRuns:r});for(let t of Object.values(r))id(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(id);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=L(this.state)){if(L(this.state)!==t)return;let n=CS(t,e.id);if(this.handledWorkspaceDeletionRunIds.has(n))return;let r=rd(e);if(r!==void 0){if(this.handledWorkspaceDeletionRunIds.add(n),e.status===`succeeded`){if(await this.workspaces.refreshAfterWorkspaceDeleted(e.projectId,r),L(this.state)!==t)return;this.setState({workspaceDeletionRuns:ES(this.state.workspaceDeletionRuns,r)}),this.updateWorkspaceDeletionPolling();return}e.status===`failed`&&(this.setState({error:`工作区删除失败。请查看终端输出。`}),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(`移除 ${e.name}?\n\n这只会从当前 PI WEB 网关移除它。`))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:`操作失败:${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:`选择模型`,...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?` ✓ 当前`:``}`,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?aS:iS;this.setState({themeDialog:{title:`选择主题`,selectedValue:n===void 0?r:`${oS}${n}`,options:[{value:r,label:`自动 ${this.themePreference.auto?`✓ 开启`:`关闭`}`,description:this.autoThemeDescription(t)},...e.map(e=>({value:`${oS}${e.id}`,label:this.themeOptionLabel(e,n),description:this.themeOptionDescription(e)}))]}})}pickTheme(e){if(this.setState({themeDialog:void 0}),e===iS||e===aS){let t=this.resolveCurrentThemePreference().selectedTheme?.id;if(t===void 0)return;this.themePreference={themeId:t,auto:e===iS},this.applyPreferredTheme(!0);return}if(!e.startsWith(oS))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,Hu(t),e&&Vu(this.themePreference))}resolveCurrentThemePreference(e=this.plugins.getThemes()){return Uu({themes:e,themePairs:this.plugins.getThemePairs(),preference:this.themePreference,prefersLight:this.systemPrefersLight()})}themePairForTheme(e){return Gu(this.plugins.getThemePairs(),e)}systemPrefersLight(){return this.systemLightThemeMedia?.matches??!1}autoThemeDescription(e){return!this.themePreference.auto||e.selectedTheme===void 0?`当所选主题有配对主题时,跟随系统明暗偏好。`:e.selectedThemePair===void 0?`已开启,但所选主题没有明暗配对,因此会保持当前主题。`:`已开启 · ${e.selectedThemePair.name} 跟随系统${this.systemPrefersLight()?`浅色`:`深色`}偏好。`}themeOptionLabel(e,t){let n=[...e.id===t?[`已选择`]:[],...e.id===this.activeThemeId&&e.id!==t?[`生效中`]:[]];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(`自动配对`),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:`选择思考级别`,selectedValue:t,options:e.map(e=>{let n=OS(e);return{value:e,label:`${e}${e===t?` ✓ 当前`:``}`,...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`
|
|
3094
|
+
<chat-view .sessionId=${t.id} .messages=${e.messages} .messageStart=${e.messagePageStart} .messageEnd=${e.messagePageEnd} .messageTotal=${e.messagePageTotal} .hasMore=${e.messagePageStart>0} .loadingMore=${e.isLoadingEarlierMessages} .isReceivingPartialStream=${e.isReceivingPartialStream} .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} .onLoadMore=${()=>this.withChatPrependTransition(()=>this.sessions.loadEarlierMessages())}></chat-view>
|
|
3095
|
+
`}renderContextBar(){return this.appShell.isMobileNavigationLayout?g`
|
|
3096
|
+
<app-context-bar
|
|
3097
|
+
.machines=${this.state.machines}
|
|
3098
|
+
.machine=${this.state.selectedMachine}
|
|
3099
|
+
.project=${this.state.selectedProject}
|
|
3100
|
+
.workspace=${this.state.selectedWorkspace}
|
|
3101
|
+
.session=${this.state.selectedSession}
|
|
3102
|
+
.refreshControl=${this.appShell.shouldShowAppRefreshInContextBar()?this.renderAppRefresh():void 0}
|
|
3103
|
+
.onOpenSection=${e=>{this.openNavigationSection(e)}}
|
|
3104
|
+
.onShowActions=${()=>{this.setState({actionPaletteOpen:!0})}}
|
|
3105
|
+
></app-context-bar>
|
|
3106
|
+
`:null}renderMobileMainTabs(){return g`
|
|
3107
|
+
<app-mobile-main-tabs
|
|
3108
|
+
.tabs=${this.mobileMainTabs()}
|
|
3109
|
+
.selectedView=${this.state.mainView}
|
|
3110
|
+
.onSelect=${e=>{this.selectMainView(e)}}
|
|
3111
|
+
></app-mobile-main-tabs>
|
|
3112
|
+
`}mobileMainTabs(){return[{id:`navigation`,label:`会话`,icon:`navigation`,className:`navigation-tab`},{id:`chat`,label:`聊天`,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,t=this.normalAuthGateMode();return this.apiScope===`normal`&&(t!==void 0||this.normalAuthStatus===void 0)?this.renderNormalAuthDialog(t??`login`):g`
|
|
3113
|
+
<div class=${this.panelCollapse.shellClass(e.mainView)} style=${this.panelResize.shellStyle({navigation:this.resizablePanelConstraints(`navigation`),workspace:this.resizablePanelConstraints(`workspace`)})}>
|
|
3114
|
+
<aside id="navigation-panel">${this.appShell.isMobileNavigationLayout?null:this.renderNavigationPanel()}</aside>
|
|
3115
|
+
${this.renderNavigationPanelEdgeControl()}
|
|
3116
|
+
<main class=${pp(e.mainView)}>
|
|
3117
|
+
${this.renderContextBar()}
|
|
3118
|
+
${this.renderMobileMainTabs()}
|
|
3119
|
+
${e.error?g`<div class="error">${e.error}</div>`:null}
|
|
3120
|
+
<div class="mobile-navigation-panel">${this.appShell.isMobileNavigationLayout?this.renderNavigationPanel():null}</div>
|
|
3121
|
+
${e.selectedSession?g`
|
|
3122
|
+
${this.renderChatView(e,e.selectedSession)}
|
|
3123
|
+
<prompt-editor .sessionId=${e.selectedSession.id} .cwd=${e.selectedWorkspace?.path} .machineId=${L(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>
|
|
3124
|
+
<status-bar .status=${e.status}></status-bar>
|
|
3125
|
+
${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>`}
|
|
3126
|
+
${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>`}
|
|
3127
|
+
${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>`}
|
|
3128
|
+
${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>`}
|
|
3129
|
+
`:g`<div class="empty">${this.sessionEmptyMessage()}</div>`}
|
|
3130
|
+
</main>
|
|
3131
|
+
${this.renderWorkspacePanelEdgeControl()}
|
|
3132
|
+
${this.renderWorkspacePanel()}
|
|
3133
|
+
${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}
|
|
3134
|
+
${e.projectDialogOpen?g`<project-dialog .machineId=${L(e)} .onSubmit=${(e,t)=>this.projects.addProject(e,t)} .onCancel=${()=>{this.setState({projectDialogOpen:!1})}}></project-dialog>`:null}
|
|
3135
|
+
${e.machineDialogOpen?g`<machine-dialog .error=${e.error} .onSubmit=${e=>this.submitMachineDialog(e)} .onCancel=${()=>{this.setState({machineDialogOpen:!1})}}></machine-dialog>`:null}
|
|
3136
|
+
${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>`}
|
|
3137
|
+
${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>`}
|
|
3138
|
+
${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)}}></settings-dialog>`}
|
|
3139
|
+
${this.normalAuthDialogMode===`change`?this.renderNormalAuthDialog(`change`):null}
|
|
3140
|
+
</div>
|
|
3141
|
+
`}renderNormalAuthDialog(e){return g`
|
|
3142
|
+
<normal-auth-dialog
|
|
3143
|
+
.mode=${e}
|
|
3144
|
+
.loading=${this.normalAuthLoading}
|
|
3145
|
+
.error=${this.normalAuthError}
|
|
3146
|
+
.onSubmit=${e=>{this.submitNormalAuth(e)}}
|
|
3147
|
+
.onCancel=${()=>{this.normalAuthDialogMode=void 0,this.normalAuthError=``}}
|
|
3148
|
+
></normal-auth-dialog>
|
|
3149
|
+
`}static{this.styles=$x}};z([x()],$.prototype,`state`,void 0),z([S(`chat-view`)],$.prototype,`chatView`,void 0),z([S(`prompt-editor`)],$.prototype,`promptEditor`,void 0),z([S(`app-navigation-panel`)],$.prototype,`navigationPanel`,void 0),z([S(`#navigation-panel`)],$.prototype,`navigationPanelFrame`,void 0),z([S(`#workspace-panel`)],$.prototype,`workspacePanelFrame`,void 0),z([x()],$.prototype,`activeThemeId`,void 0),z([x()],$.prototype,`isRefreshingApp`,void 0),z([x()],$.prototype,`sessionCleanupDialog`,void 0),z([x()],$.prototype,`settingsSection`,void 0),z([x()],$.prototype,`normalAuthStatus`,void 0),z([x()],$.prototype,`normalAuthLoading`,void 0),z([x()],$.prototype,`normalAuthError`,void 0),z([x()],$.prototype,`normalAuthDialogMode`,void 0),z([x()],$.prototype,`shortcutConfig`,void 0),z([x()],$.prototype,`workspaceUploadDefaultFolder`,void 0),$=z([y(`pi-web-app`)],$);function pS(){let e=new kf;return e.register({id:`core`,plugin:of}),e.register({id:`themes`,plugin:uf}),e}function mS(){let e=vt()?`management`:`normal`;return Mt(e),e}function hS(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 gS(e,t){return e.machines!==t.machines||e.machineStatuses!==t.machineStatuses||(e.selectedMachine?.id??`local`)!==(t.selectedMachine?.id??`local`)}function _S(e,t){return vS(e,t)}function vS(e,t){if(e.kind===`local`)return!0;let n=t?.status??e.status;return n===void 0||n===`unknown`||n===`online`}function yS(e,t){return Object.entries(t).some(([t,n])=>Reflect.get(e,t)!==n)}function bS(e){return Aa(e.status,e.activity)}function xS(e){return e.type===`terminal.created`||e.type===`terminal.exited`||e.type===`terminal.closed`}function SS(){return{}}function CS(e,t){return JSON.stringify([e,t])}function wS(e){return nS[Math.min(e,nS.length-1)]??3e4}function TS(e){return e instanceof Error?e.message:String(e)}function ES(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>e!==t))}function DS(){return new Promise(e=>requestAnimationFrame(()=>{e()}))}function OS(e){switch(e){case`off`:return`不使用推理`;case`minimal`:return`极简推理(约 1k tokens)`;case`low`:return`轻量推理(约 2k tokens)`;case`medium`:return`中等推理(约 8k tokens)`;case`high`:return`深度推理(约 16k tokens)`;case`xhigh`:return`最大推理(约 32k tokens)`;default:return}}export{h as _,z as a,ra as c,x as d,b as f,g,Ye as h,Km as i,Ji as l,v as m,qm as n,Yl as o,y as p,Jm as r,Jl as s,bh as t,S as u};
|