@chainingintention/pi-web-cn 2.202610.2 → 2.202610.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/client/assets/CommandPicker-gK2biReF.js +70 -0
  2. package/dist/client/assets/PiWebApp-Do_8tp5d.js +3761 -0
  3. package/dist/client/assets/SettingsDialog-vGDo1-BJ.js +1015 -0
  4. package/dist/client/assets/index-Ura0RJyr.js +2 -0
  5. package/dist/client/assets/managementEmbed-Bx8Mwzdw.js +2 -0
  6. package/dist/client/assets/preload-helper-XpATwJ5c.js +1 -0
  7. package/dist/client/index.html +3 -2
  8. package/dist/pi-web-plugins/custom-ui-codex/LICENSE-icons +35 -0
  9. package/dist/pi-web-plugins/custom-ui-codex/README.md +25 -0
  10. package/dist/pi-web-plugins/custom-ui-codex/chat-settings.css +251 -0
  11. package/dist/pi-web-plugins/custom-ui-codex/codex.css +77 -0
  12. package/dist/{client/assets/graphite-DquaqFXU.css → pi-web-plugins/custom-ui-codex/graphite.css} +4 -2
  13. package/dist/pi-web-plugins/custom-ui-codex/package.json +10 -0
  14. package/dist/{client/assets/paper-CB1oLuRr.css → pi-web-plugins/custom-ui-codex/paper.css} +7 -5
  15. package/dist/pi-web-plugins/custom-ui-codex/pi-web-plugin.js +56 -0
  16. package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +29 -29
  17. package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +3 -3
  18. package/dist/pi-web-plugins/zh-cn/components.json +6 -1
  19. package/dist/plugin-api.d.ts +48 -0
  20. package/dist/server/terminals/requiredTerminalService.js +2 -53
  21. package/dist/server/terminals/requiredTerminalService.js.map +1 -1
  22. package/dist/shared/terminalCommandRun.js +56 -0
  23. package/dist/shared/terminalCommandRun.js.map +1 -0
  24. package/docs/config.md +6 -2
  25. package/docs/plugins.md +22 -1
  26. package/package.json +2 -2
  27. package/dist/client/assets/PiWebApp-BVnLs9Kj.js +0 -4938
  28. package/dist/client/assets/external-B9K8duyP.js +0 -2
  29. package/dist/client/assets/index-pOnX1cs_.js +0 -2
@@ -0,0 +1,1015 @@
1
+ import{$ as e,$t as t,G as n,Gt as r,M as i,P as a,Q as o,Qt as s,R as c,V as l,W as u,X as d,Z as f,_ as p,cn as m,et as h,g,h as ee,ht as _,it as v,l as te,ln as y,mt as ne,n as re,p as ie,qt as ae,sn as b,st as oe,t as se,tt as ce,u as x,v as S,xt as C,y as w,yt as T}from"./CommandPicker-gK2biReF.js";import{$ as E,J as D,R as O,U as k,W as A,j as le,o as ue}from"./managementEmbed-Bx8Mwzdw.js";var j=c(`.ui-settings-section{border-bottom:1px solid var(--pi-border-muted);gap:14px;min-width:0;padding:16px;display:grid}.ui-settings-heading{gap:6px;min-width:0;display:grid}.ui-settings-heading h3{margin:0;font-size:14px;line-height:1.4}.ui-settings-heading p{color:var(--pi-muted);margin:0;line-height:1.45}.ui-settings-fields{gap:14px;min-width:0;display:grid}.ui-settings-actions{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;min-width:0;display:flex}.ui-settings-path{background:var(--pi-bg);min-width:0;color:var(--pi-muted);overflow-wrap:anywhere;gap:5px;padding:12px;display:grid}.ui-settings-summary{background:var(--pi-bg);gap:10px;min-width:0;padding:12px;display:grid}.ui-settings-list{gap:0;min-width:0;display:grid}.ui-settings-row{border-bottom:1px solid var(--pi-border-muted);flex-wrap:wrap;align-items:center;gap:12px;min-width:0;padding:12px 16px;display:flex}@media (width<=480px){.ui-settings-actions{grid-template-columns:minmax(0,1fr);display:grid}}`),de=c(`.ui-notice{border-inline-start:3px solid var(--pi-border);background:var(--pi-surface);overflow-wrap:anywhere;min-width:0;padding:12px 16px;line-height:1.45}.ui-notice.error{border-color:var(--pi-danger);color:var(--pi-danger);background:color-mix(in srgb, var(--pi-danger) 10%, var(--pi-surface))}.ui-notice.success{border-color:var(--pi-success-border);color:var(--pi-success);background:var(--pi-success-surface)}.ui-notice.warning{border-color:var(--pi-warning-border);color:var(--pi-text);background:var(--pi-warning-surface)}.ui-notice.info{color:var(--pi-muted)}`),fe={availability:`error`,error:`error`,success:`success`,security:`warning`,warning:`warning`,info:`info`};function pe(e){return e.tone??fe[e.type]}var M=class extends k{constructor(){super(),this.heading=``,this.description=``,this.actionLabel=``,this.actionTitle=``,this.actionDisabled=!1,this.notices=[],i.createController(this)}render(){return D`
2
+ <section class="panel" aria-label=${this.heading||O(`ui.settingsPanelFrame.settingsPanel`,`Settings panel`)}>
3
+ <header class="section-heading">
4
+ <div class="heading-copy">
5
+ ${this.heading===``?A:D`<h2>${this.heading}</h2>`}
6
+ <div class="description"><slot name="description">${this.description}</slot></div>
7
+ </div>
8
+ <div class="heading-actions"><slot name="actions">${this.renderDefaultAction()}</slot></div>
9
+ </header>
10
+ ${this.renderNoticeStack()}
11
+ <div class="content"><slot></slot></div>
12
+ </section>
13
+ `}renderDefaultAction(){return this.actionLabel===``?A:D`
14
+ <button
15
+ class="secondary ui-button ui-button--action"
16
+ title=${this.actionTitle||this.actionLabel}
17
+ ?disabled=${this.actionDisabled}
18
+ @click=${()=>{this.onAction?.()}}
19
+ >${this.actionLabel}</button>
20
+ `}renderNoticeStack(){return this.notices.length===0?A:D`
21
+ <div class="notice-stack" aria-label=${O(`ui.settingsPanelFrame.settingsNotices`,`Settings notices`)}>
22
+ ${this.notices.map(e=>this.renderNotice(e))}
23
+ </div>
24
+ `}renderNotice(e){let t=pe(e),n=e.role??me(t),r=e.title;return D`
25
+ <article class=${`notice ui-notice ${t}`} role=${n}>
26
+ ${r===void 0||r===``?A:D`<strong class="notice-title">${r}</strong>`}
27
+ <div class="notice-content">${e.content}</div>
28
+ </article>
29
+ `}static{this.styles=[a,de,E`
30
+ @layer pi-web-base {
31
+ :host { display: block; }
32
+ .panel { display: block; }
33
+ .section-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 16px; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-surface); }
34
+ .heading-copy { display: grid; gap: 6px; min-width: 0; }
35
+ .heading-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
36
+ h2 { margin: 0; font-size: 17px; line-height: 1.25; }
37
+ .description { color: var(--pi-muted); line-height: 1.45; }
38
+ .description ::slotted(*) { margin: 0; }
39
+ .secondary { flex: 0 0 auto; }
40
+ .notice-stack { display: grid; gap: 1px; }
41
+ .notice-title { display: block; margin-bottom: 4px; color: inherit; }
42
+ .notice-content { min-width: 0; }
43
+ code { border: 1px solid var(--pi-border-muted); border-radius: 5px; background: var(--pi-bg); padding: 1px 4px; color: var(--pi-text); font: 12px var(--pi-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); overflow-wrap: anywhere; }
44
+ .content { display: grid; gap: 0; min-width: 0; }
45
+ .content ::slotted(*) { min-width: 0; }
46
+
47
+ @media (max-width: 760px) {
48
+ .section-heading { display: grid; gap: 12px; }
49
+ .heading-actions { justify-self: start; }
50
+ }
51
+
52
+ }
53
+ `]}};w([m()],M.prototype,`heading`,void 0),w([m({attribute:!1})],M.prototype,`description`,void 0),w([m()],M.prototype,`actionLabel`,void 0),w([m()],M.prototype,`actionTitle`,void 0),w([m({type:Boolean})],M.prototype,`actionDisabled`,void 0),w([m({attribute:!1})],M.prototype,`notices`,void 0),w([m({attribute:!1})],M.prototype,`onAction`,void 0),M=w([y(`settings-panel-frame`)],M);function me(e){switch(e){case`error`:return`alert`;case`success`:return`status`;case`warning`:case`info`:return`note`}}var N=class extends k{constructor(){super(),this.targetLabel=`this machine`,this.servers=[],this.loading=!1,this.error=``,this.generation=0,i.createController(this)}connectedCallback(){super.connectedCallback(),this.hasUpdated&&this.reload()}disconnectedCallback(){this.generation+=1,this.servers=[],this.error=``,this.loading=!1,super.disconnectedCallback()}willUpdate(e){e.has(`context`)&&this.reload()}isCurrent(e,t){return this.isConnected&&e===this.generation&&t.machineId===this.context?.machineId&&t.session.id===this.context.session.id&&t.session.cwd===this.context.session.cwd}async reload(){let e=++this.generation;if(this.servers=[],this.error=``,this.loading=!1,!this.isConnected||this.context===void 0)return;let t={machineId:this.context.machineId,session:{...this.context.session}};this.loading=!0;try{let n=await ne.mcpAuthServers(t.session,t.machineId);this.isCurrent(e,t)&&(this.servers=n.servers)}catch(n){this.isCurrent(e,t)&&(this.error=O(`ui.mcp.loadServersError`,`Could not load MCP servers: {error}`,{error:he(n)}))}finally{this.isCurrent(e,t)&&(this.loading=!1)}}async authenticate(e,t,n){let r=this.generation;try{await this.onMcpAuth?.(e,t,n)}catch(e){this.isCurrent(r,n)&&(this.error=O(`ui.mcp.openAuthenticationError`,`Could not open MCP authentication: {error}`,{error:he(e)}))}}render(){let e=this.context===void 0?void 0:{machineId:this.context.machineId,session:{...this.context.session}};return D`
54
+ <settings-panel-frame
55
+ heading="MCP"
56
+ .description=${O(`ui.mcp.settingsDescription`,`Manage authentication for enabled MCP servers that support OAuth in the selected session.`)}
57
+ actionLabel=${O(`ui.mcp.refreshServers`,`Refresh servers`)}
58
+ .actionDisabled=${e===void 0||this.loading}
59
+ .onAction=${()=>this.reload()}
60
+ .notices=${this.error===``?[]:[{type:`error`,content:this.error}]}
61
+ >
62
+ <section class="ui-settings-section">
63
+ ${e===void 0?D`
64
+ <p role="status">${O(`ui.mcp.selectNonarchivedSession`,`Select a nonarchived session on {machine} to manage MCP authentication.`,{machine:this.targetLabel})}</p>
65
+ `:D`
66
+ <div class="ui-settings-heading"><h3>${O(`ui.mcp.sessionContext`,`Session context`)}</h3></div>
67
+ <div class="ui-settings-summary session-context" aria-label=${O(`ui.mcp.sessionContextLabel`,`MCP session context`)}>
68
+ <span><strong>${O(`ui.mcp.machineLabel`,`Machine:`)}</strong> ${this.targetLabel}</span>
69
+ <span><strong>${O(`ui.mcp.sessionLabel`,`Session:`)}</strong> ${e.session.id}</span>
70
+ <span><strong>${O(`ui.mcp.workspaceLabel`,`Workspace:`)}</strong> ${e.session.cwd}</span>
71
+ </div>
72
+ <p>${O(`ui.mcp.logoutWarning`,`Logout removes Pi’s saved credentials. It does not disable the server or revoke access at the provider. Other sessions using those credentials are also affected.`)}</p>
73
+ ${this.loading?D`<p role="status">${O(`ui.mcp.loadingServers`,`Loading MCP servers…`)}</p>`:this.error===``?this.servers.length===0?D`
74
+ <p role="status">${O(`ui.mcp.noServers`,`No enabled MCP servers with OAuth support are available in this session.`)}</p>
75
+ `:D`
76
+ <ul class="ui-settings-list server-list" aria-label=${O(`ui.mcp.serversLabel`,`MCP servers`)}>
77
+ ${this.servers.map(t=>D`
78
+ <li class="ui-settings-row">
79
+ <div class="server-copy ui-settings-heading">
80
+ <h3>${t.name}</h3>
81
+ ${t.description===void 0?null:D`<p class="server-description">${t.description}</p>`}
82
+ </div>
83
+ <div class="ui-settings-actions">
84
+ <button class="ui-button ui-button--action" aria-label=${O(`ui.mcp.loginTo`,`Login to {server}`,{server:t.name})} ?disabled=${this.onMcpAuth===void 0} @click=${()=>{this.authenticate(`login`,t.name,e)}}>${O(`ui.mcp.login`,`Login`)}</button>
85
+ <button class="ui-button ui-button--action" aria-label=${O(`ui.mcp.logoutFrom`,`Logout from {server}`,{server:t.name})} ?disabled=${this.onMcpAuth===void 0} @click=${()=>{this.authenticate(`logout`,t.name,e)}}>${O(`ui.mcp.logout`,`Logout`)}</button>
86
+ </div>
87
+ </li>
88
+ `)}
89
+ </ul>
90
+ `:null}
91
+ `}
92
+ </section>
93
+ </settings-panel-frame>
94
+ `}static{this.styles=[a,j,E`
95
+ @layer pi-web-base {
96
+ :host { display: block; }
97
+ p { line-height: 1.45; }
98
+ .ui-settings-section > p { margin: 0; }
99
+ .session-context { overflow-wrap: anywhere; }
100
+ .server-list { margin: 0; padding: 0; list-style: none; }
101
+ .server-copy { flex: 1 1 240px; min-width: 0; }
102
+ .server-description { white-space: pre-wrap; overflow-wrap: anywhere; }
103
+ }
104
+ `]}};w([m({attribute:!1,hasChanged:(e,t)=>e?.machineId!==t?.machineId||e?.session.id!==t?.session.id||e?.session.cwd!==t?.session.cwd})],N.prototype,`context`,void 0),w([m()],N.prototype,`targetLabel`,void 0),w([m({attribute:!1})],N.prototype,`onMcpAuth`,void 0),w([b()],N.prototype,`servers`,void 0),w([b()],N.prototype,`loading`,void 0),w([b()],N.prototype,`error`,void 0),N=w([y(`settings-mcp-panel`)],N);function he(e){return e instanceof Error?e.message:String(e)}function ge(e,t,n){let r={...e};for(let i in n)e[i]===t[i]&&(r[i]=n[i]);return r}function _e(){return{host:``,port:``,allowedHostsMode:`list`,allowedHostsText:``}}function P(){return{allowedPathsText:``,uploadDefaultFolder:``,attachmentDefaultFolder:``}}function F(){return{command:``,dir:``}}function ve(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(`
105
+ `):``}}function ye(e){return{allowedPathsText:e.pathAccess?.allowedPaths?.join(`
106
+ `)??``,uploadDefaultFolder:e.uploads?.defaultFolder??``,attachmentDefaultFolder:e.attachments?.defaultFolder??``}}function be(e){return{command:e.agent?.command??``,dir:e.agent?.dir??``}}function xe(e){let t=e.command.trim(),n=e.dir.trim();return{agent:{...t===``?{}:{command:t},...n===``?{}:{dir:n}}}}function Se(e,t){let n=xe(e).agent??{},r=t.agent??{};return n.command===r.command&&n.dir===r.dir}function Ce(e,t={}){let n=Te(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(O(`ui.settingsConfigDraft.portMustBeAnIntegerFrom1To`,`Port must be an integer from 1 to 65535.`));n.port=e}return n.allowedHosts=e.allowedHostsMode===`all`||Ee(e.allowedHostsText),n}function we(e){let t=De(e.allowedPathsText),n=Oe(e.uploadDefaultFolder,O(`ui.main.d70e26e84489`,`Upload default folder`)),r=Oe(e.attachmentDefaultFolder,O(`ui.main.14cfd18bd406`,`Attachment default folder`));return{pathAccess:{allowedPaths:t},uploads:n===``?{}:{defaultFolder:n},attachments:r===``?{}:{defaultFolder:r}}}function Te(e){return{...e.shortcuts===void 0?{}:{shortcuts:e.shortcuts},...e.defaultTheme===void 0?{}:{defaultTheme:e.defaultTheme},...e.defaultStreamingBehavior===void 0?{}:{defaultStreamingBehavior:e.defaultStreamingBehavior},...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.attachments===void 0?{}:{attachments:e.attachments},...e.maxUploadBytes===void 0?{}:{maxUploadBytes:e.maxUploadBytes},...e.spawnSessions===void 0?{}:{spawnSessions:e.spawnSessions},...e.subsessions===void 0?{}:{subsessions:e.subsessions},...e.askUser===void 0?{}:{askUser:e.askUser},...e.agent===void 0?{}:{agent:e.agent},...e.sessionNaming===void 0?{}:{sessionNaming:e.sessionNaming},...e.sessionArchive===void 0?{}:{sessionArchive:e.sessionArchive}}}function Ee(e){return e.split(/[\n,]/u).map(e=>e.trim()).filter(e=>e!==``)}function De(e){let t=e.split(`
107
+ `).map(e=>e.trim()).filter(e=>e!==``),n=t.find(e=>!ke(e));if(n!==void 0)throw Error(O(`ui.settingsConfigDraft.allowedExternalPathsMustBeAbsoluteOrStart`,`Allowed external paths must be absolute or start with ~: {invalid}`,{invalid:n}));return t}function Oe(e,t){let n=e.trim();if(n===``)return``;if(Ae(n))throw Error(O(`ui.main.4b7d0c261f32`,`{arg0} must be a workspace-relative path.`,{arg0:t}));let r=n.split(/[\\/]+/u).filter(e=>e!==``&&e!==`.`);if(r.length===0)return``;if(r.some(e=>e===`..`))throw Error(O(`ui.main.36766761e71a`,`{arg0} must not contain path traversal.`,{arg0:t}));return r.join(`/`)}function ke(e){return e===`~`||e.startsWith(`~/`)||e.startsWith(`~\\`)||e.startsWith(`/`)||e.startsWith(`\\`)||/^[A-Za-z]:[\\/]/u.test(e)}function Ae(e){let t=e.replace(/\\/g,`/`);return t.startsWith(`/`)||/^[A-Za-z]:\//u.test(t)}function je(e){return D`${O(`ui.settingsGeneralPanel.settingsScope`,`Gateway server fields edit the current local gateway; file access and upload defaults edit {machine}.`,{machine:e})}`}var I=class extends k{constructor(){super(),this.loading=!1,this.machineLoading=!1,this.saving=!1,this.error=``,this.machineError=``,this.savedMessage=``,this.targetLabel=`selected machine`,this.targetId=`local`,this.gatewayDraft=_e(),this.machineDraft=P(),this.gatewayLocalError=``,this.machineLocalError=``,this.gatewayBaseline=_e(),this.machineBaseline=P(),i.createController(this)}get hasUnsavedMachineChanges(){return!R(this.machineDraft,this.machineBaseline)}discardMachineChanges(){this.machineDraft={...this.machineBaseline},this.machineLocalError=``}willUpdate(e){if(e.has(`configResponse`)&&this.configResponse!==void 0){let e=ve(this.configResponse.config),t=this.gatewaySubmission,n=t!==void 0&&R(e,t.expected);this.gatewayDraft=ge(this.gatewayDraft,n?t.draft:this.gatewayBaseline,e),this.gatewayBaseline=e,n&&(this.gatewaySubmission=void 0)}if((e.has(`targetId`)||e.has(`targetLabel`)||e.has(`machineConfigResponse`)&&this.machineConfigResponse===void 0)&&(this.machineDraft=P(),this.machineBaseline=P(),this.machineSubmission=void 0,this.machineLocalError=``),(e.has(`machineConfigResponse`)||e.has(`targetId`)||e.has(`targetLabel`))&&this.machineConfigResponse!==void 0){let e=ye(this.machineConfigResponse.config),t=this.machineSubmission,n=t!==void 0&&R(e,t.expected);this.machineDraft=ge(this.machineDraft,n?t.draft:this.machineBaseline,e),this.machineBaseline=e,n&&(this.machineSubmission=void 0)}}render(){return D`
108
+ <settings-panel-frame
109
+ heading=${O(`ui.settingsGeneralPanel.generalConfiguration`,`General configuration`)}
110
+ .description=${je(this.targetLabel)}
111
+ actionLabel=${O(`ui.settingsGeneralPanel.reload`,`Reload`)}
112
+ .actionDisabled=${this.loading||this.machineLoading}
113
+ .notices=${this.panelNotices()}
114
+ .onAction=${()=>{this.reloadAll()}}
115
+ >
116
+ <div class="settings-sections ui-settings-list">
117
+ <slot name="appearance"></slot>
118
+ ${this.renderGatewayServerSettings()}
119
+ ${this.renderSelectedMachineAccessSettings()}
120
+ </div>
121
+ </settings-panel-frame>
122
+ `}renderGatewayServerSettings(){let e=this.configResponse;return D`
123
+ <section class="settings-card ui-settings-section" aria-label=${O(`ui.settingsGeneralPanel.gatewayServerSettings`,`Gateway server settings`)}>
124
+ <div class="card-heading ui-settings-heading">
125
+ <h3>${O(`ui.settingsGeneralPanel.gatewayServer`,`Gateway server`)}</h3>
126
+ <p>${O(`ui.settingsGeneralPanel.hostPortAndAllowedHostsAreSavedTo`,`Host, port, and allowed hosts are saved to gateway configuration. Restart the web service after address changes for the running server to bind to the new address.`)}</p>
127
+ </div>
128
+ ${e===void 0?D`<div class="loading-card">${this.loading?O(`ui.settingsGeneralPanel.loadingGatewayConfiguration`,`Loading gateway configuration…`):O(`ui.settingsGeneralPanel.gatewayUnavailable`,`Gateway configuration is unavailable. Reload settings to try again.`)}</div>`:D`
129
+ <div class="config-path-card ui-settings-path">
130
+ <span>${O(`ui.settingsGeneralPanel.gatewayConfigurationFile`,`Gateway configuration file`)}</span>
131
+ <code>${e.path}</code>
132
+ <small>${e.exists?O(`ui.settingsGeneralPanel.existingFile`,`Existing file`):O(`ui.settingsGeneralPanel.fileWillBeCreatedOnSave`,`File will be created on save`)}</small>
133
+ </div>
134
+ <form class="config-form ui-settings-fields" @submit=${e=>{this.saveGatewayConfig(e)}}>
135
+ <label class="field ui-form-field">
136
+ <span class="field-heading">
137
+ <span>${O(`ui.settingsGeneralPanel.hostAddress`,`Host address`)}</span>
138
+ ${this.renderOverrideBadge(`host`)}
139
+ </span>
140
+ <input class="ui-input" .value=${this.gatewayDraft.host} placeholder="127.0.0.1" autocomplete="off" spellcheck="false" @input=${e=>{this.updateGatewayDraft({host:L(e)})}}>
141
+ <small>${O(`ui.settingsGeneralPanel.addressTheWebServerBindsToLeaveBlank`,`Address the web server binds to. Leave blank for the PI WEB default.`)}</small>
142
+ </label>
143
+
144
+ <label class="field ui-form-field">
145
+ <span class="field-heading">
146
+ <span>${O(`ui.settingsGeneralPanel.port`,`Port`)}</span>
147
+ ${this.renderOverrideBadge(`port`)}
148
+ </span>
149
+ <input class="ui-input" .value=${this.gatewayDraft.port} inputmode="numeric" pattern="[0-9]*" placeholder="8504" autocomplete="off" @input=${e=>{this.updateGatewayDraft({port:L(e)})}}>
150
+ <small>${O(`ui.settingsGeneralPanel.tcpPortFrom1To65535LeaveBlank`,`TCP port from 1 to 65535. Leave blank for the PI WEB default.`)}</small>
151
+ </label>
152
+
153
+ <div class="field ui-form-field">
154
+ <span class="field-heading">
155
+ <label for="allowed-hosts-mode">${O(`ui.settingsGeneralPanel.allowedHosts`,`Allowed hosts`)}</label>
156
+ ${this.renderOverrideBadge(`allowedHosts`)}
157
+ </span>
158
+ <select class="ui-input" id="allowed-hosts-mode" aria-describedby="allowed-hosts-help" .value=${this.gatewayDraft.allowedHostsMode} @change=${e=>{this.updateGatewayDraft({allowedHostsMode:Pe(e)===`all`?`all`:`list`})}}>
159
+ <option value="list">${O(`ui.settingsGeneralPanel.allowListedHostsOnly`,`Allow listed hosts only`)}</option>
160
+ <option value="all">${O(`ui.settingsGeneralPanel.allowAllHosts`,`Allow all hosts`)}</option>
161
+ </select>
162
+ <label for="allowed-hosts-list">${O(`ui.settingsGeneralPanel.hostList`,`Host list`)}</label>
163
+ <textarea class="ui-input" id="allowed-hosts-list" aria-describedby="allowed-hosts-help" .value=${this.gatewayDraft.allowedHostsText} ?disabled=${this.gatewayDraft.allowedHostsMode===`all`} rows="4" placeholder="example.local&#10;192.168.1.20" spellcheck="false" @input=${e=>{this.updateGatewayDraft({allowedHostsText:Fe(e)})}}></textarea>
164
+ <small id="allowed-hosts-help">${O(`ui.settingsGeneralPanel.allowedHostsHint`,`Enter one host per line, or select "Allow all hosts" to write true.`)}</small>
165
+ </div>
166
+
167
+ ${this.renderGatewayEffectiveConfig()}
168
+
169
+ <footer class="form-actions ui-settings-actions">
170
+ ${R(this.gatewayDraft,this.gatewayBaseline)?null:D`<small>${O(`ui.settingsGeneralPanel.unsavedChanges`,`Unsaved changes`)}</small>`}
171
+ <button class="primary ui-button ui-button--action ui-button--primary" ?disabled=${this.loading||this.saving}>${this.saving?O(`ui.settingsGeneralPanel.saving`,`Saving…`):O(`ui.settingsGeneralPanel.saveGatewayServerConfiguration`,`Save gateway server configuration`)}</button>
172
+ </footer>
173
+ </form>
174
+ `}
175
+ </section>
176
+ `}renderSelectedMachineAccessSettings(){let e=this.machineConfigResponse;return D`
177
+ <section class="settings-card ui-settings-section" aria-label=${O(`ui.settingsGeneralPanel.selectedMachineFileAccessAndUploadSettings`,`Selected machine file access and upload settings`)}>
178
+ <div class="card-heading ui-settings-heading">
179
+ <h3>${O(`ui.settingsGeneralPanel.selectedMachineFileAccessAndUploads`,`Selected machine file access and uploads`)}</h3>
180
+ <p>${O(`ui.settingsGeneralPanel.fileSettingsScope`,`External filesystem roots and upload defaults are saved to {machine}.`,{machine:this.targetLabel})}</p>
181
+ </div>
182
+ ${this.renderMachineMessages()}
183
+ ${e===void 0?D`<div class="loading-card">${this.machineLoading?O(`ui.settingsGeneralPanel.loadingSelectedMachineFileAccessConfiguration`,`Loading selected machine file access configuration…`):O(`ui.settingsGeneralPanel.selectedMachineFileAccessConfigurationIsUnavailableReload`,`Selected machine file access configuration is unavailable. Reload before saving file/upload settings.`)}</div>`:D`
184
+ <div class="config-path-card ui-settings-path">
185
+ <span>${O(`ui.settingsGeneralPanel.selectedMachineConfigurationFile`,`Selected machine configuration file`)}</span>
186
+ <code>${e.path}</code>
187
+ <small>${e.exists?O(`ui.settingsGeneralPanel.existingFile`,`Existing file`):O(`ui.settingsGeneralPanel.fileWillBeCreatedOnSave`,`File will be created on save`)}</small>
188
+ </div>
189
+ <form class="config-form ui-settings-fields" @submit=${e=>{this.saveMachineAccessConfig(e)}}>
190
+ <label class="field ui-form-field">
191
+ <span class="field-heading">
192
+ <span>${O(`ui.settingsGeneralPanel.externalFilesystemRoots`,`External filesystem roots`)}</span>
193
+ </span>
194
+ <textarea class="ui-input" .value=${this.machineDraft.allowedPathsText} rows="4" placeholder="~/SDKs&#10;/opt/reference" spellcheck="false" @input=${e=>{this.updateMachineDraft({allowedPathsText:Fe(e)})}}></textarea>
195
+ <small>${O(`ui.settingsGeneralPanel.allowedPathsHint`,`Directories on {machine} allowed for absolute-path @ completion and file reads outside the workspace. Enter one absolute path, Windows absolute path, or ~ path per line. Leave blank to deny external paths by default.`,{machine:this.targetLabel})}</small>
196
+ </label>
197
+
198
+ <label class="field ui-form-field">
199
+ <span class="field-heading">
200
+ <span>${O(`ui.settingsGeneralPanel.defaultUploadFolder`,`Default upload folder`)}</span>
201
+ </span>
202
+ <input class="ui-input" .value=${this.machineDraft.uploadDefaultFolder} placeholder=${oe} autocomplete="off" spellcheck="false" @input=${e=>{this.updateMachineDraft({uploadDefaultFolder:L(e)})}}>
203
+ <small>${this.targetLabel} ${O(`ui.main.6c59b22a428d`,`. Leave empty to use PI WEB's default`)} <code>${oe}</code>。</small>
204
+ </label>
205
+
206
+ <label class="field ui-form-field">
207
+ <span class="field-heading">
208
+ <span>${O(`ui.main.43cec1f44f0e`,`Default attachments folder`)}</span>
209
+ </span>
210
+ <input class="ui-input" .value=${this.machineDraft.attachmentDefaultFolder} placeholder=${v} autocomplete="off" spellcheck="false" @input=${e=>{this.updateMachineDraft({attachmentDefaultFolder:L(e)})}}>
211
+ <small>${this.targetLabel} ${O(`ui.main.8d63c65c6988`,`. Leave empty to use PI WEB's default`)} <code>${v}</code>。</small>
212
+ </label>
213
+
214
+ ${this.renderMachineEffectiveConfig()}
215
+
216
+ <footer class="form-actions ui-settings-actions">
217
+ ${R(this.machineDraft,this.machineBaseline)?null:D`<small>${O(`ui.settingsGeneralPanel.unsavedChanges`,`Unsaved changes`)}</small>`}
218
+ <button class="primary ui-button ui-button--action ui-button--primary" ?disabled=${this.machineLoading||this.saving}>${this.saving?O(`ui.settingsGeneralPanel.saving`,`Saving…`):O(`ui.settingsGeneralPanel.saveFileUploadConfiguration`,`Save file/upload configuration`)}</button>
219
+ </footer>
220
+ </form>
221
+ `}
222
+ </section>
223
+ `}panelNotices(){let e=[],t=this.gatewayLocalError||this.error;return t!==``&&e.push({type:`error`,title:O(`ui.settingsGeneralPanel.gatewayServer`,`Gateway server`),content:t}),this.savedMessage!==``&&e.push({type:`success`,content:this.savedMessage}),e}renderMachineMessages(){let e=this.machineLocalError||this.machineError;return e===``?null:D`<div class="message error-message ui-form-error" role="alert">${e}</div>`}renderOverrideBadge(e){return this.configResponse?.envOverrides[e]===!0?D`<span class="override-badge">${O(`ui.settingsGeneralPanel.environmentOverrides`,`Environment overrides`)}</span>`:null}renderGatewayEffectiveConfig(){let e=this.configResponse?.effectiveConfig??{};return D`
224
+ <section class="effective-card ui-settings-summary" aria-label=${O(`ui.settingsGeneralPanel.effectiveConfigurationSummary`,`Effective configuration summary`)}>
225
+ <h3>${O(`ui.settingsGeneralPanel.effectiveGatewayConfigurationAfterEnvironmentOverrides`,`Effective gateway configuration after environment overrides`)}</h3>
226
+ <dl>
227
+ <div><dt>${O(`ui.settingsGeneralPanel.hostAddress`,`Host address`)}</dt><dd>${e.host??D`<span class="muted">${O(`ui.settingsGeneralPanel.default127001`,`Default 127.0.0.1`)}</span>`}</dd></div>
228
+ <div><dt>${O(`ui.settingsGeneralPanel.port`,`Port`)}</dt><dd>${e.port??D`<span class="muted">${O(`ui.settingsGeneralPanel.default8504`,`Default 8504`)}</span>`}</dd></div>
229
+ <div><dt>${O(`ui.settingsGeneralPanel.allowedHosts`,`Allowed hosts`)}</dt><dd>${Me(e.allowedHosts)}</dd></div>
230
+ </dl>
231
+ </section>
232
+ `}renderMachineEffectiveConfig(){let e=this.machineConfigResponse?.effectiveConfig??{};return D`
233
+ <section class="effective-card ui-settings-summary" aria-label=${O(`ui.settingsGeneralPanel.selectedMachineEffectiveFileAccessAndUploadSummary`,`Selected machine effective file access and upload summary`)}>
234
+ <h3>${O(`ui.settingsGeneralPanel.selectedMachineEffectiveConfiguration`,`Selected machine effective configuration`)}</h3>
235
+ <dl>
236
+ <div><dt>${O(`ui.settingsGeneralPanel.externalRoots`,`External roots`)}</dt><dd>${Ne(e.pathAccess?.allowedPaths)}</dd></div>
237
+ <div><dt>${O(`ui.settingsGeneralPanel.uploadFolder`,`Upload folder`)}</dt><dd>${e.uploads?.defaultFolder??D`<span class="muted">${O(`ui.settingsShortcutsPanel.default`,`Default`)} ${`.pi-web/uploads`}</span>`}</dd></div>
238
+ <div><dt>${O(`ui.main.c7057e130dae`,`Attachments folder`)}</dt><dd>${e.attachments?.defaultFolder??D`<span class="muted">${O(`ui.settingsShortcutsPanel.default`,`Default`)} ${`.pi-web/attachments`}</span>`}</dd></div>
239
+ </dl>
240
+ </section>
241
+ `}reloadAll(){this.onReload?.(),this.onReloadMachine?.()}async saveGatewayConfig(e){if(e.preventDefault(),!(this.configResponse===void 0||this.loading||this.saving||this.onSave===void 0)){this.gatewayLocalError=``;try{let e=Ce(this.gatewayDraft,this.configResponse.config),t={draft:this.gatewayDraft,expected:ve(e)};this.gatewaySubmission=t;try{await this.onSave(e),this.isConnected&&await this.updateComplete}finally{this.gatewaySubmission===t&&(this.gatewaySubmission=void 0)}}catch(e){this.gatewayLocalError=Ie(e)}}}async saveMachineAccessConfig(e){if(e.preventDefault(),this.machineConfigResponse===void 0||this.machineLoading||this.saving||this.onSaveMachineConfig===void 0)return;this.machineLocalError=``;let t=this.targetId;try{let e=we(this.machineDraft),t={draft:this.machineDraft,expected:ye(e)};this.machineSubmission=t;try{await this.onSaveMachineConfig(e),this.isConnected&&await this.updateComplete}finally{this.machineSubmission===t&&(this.machineSubmission=void 0)}}catch(e){this.targetId===t&&(this.machineLocalError=Ie(e))}}updateGatewayDraft(e){this.gatewayDraft={...this.gatewayDraft,...e},this.gatewayLocalError=``}updateMachineDraft(e){this.machineDraft={...this.machineDraft,...e},this.machineLocalError=``}static{this.styles=[a,g,j,E`
242
+ @layer pi-web-base {
243
+ :host { display: block; }
244
+ h3, p { margin: 0; }
245
+ h3 { font-size: 13px; line-height: 1.3; }
246
+ p { color: var(--pi-muted); line-height: 1.45; }
247
+ .loading-card { color: var(--pi-muted); }
248
+ .config-path-card span, .field-heading, dt { color: var(--pi-muted); font-size: 12px; font-weight: 600; }
249
+ code { border: 1px solid var(--pi-border-muted); border-radius: 5px; background: var(--pi-bg); padding: 1px 4px; color: var(--pi-text); font: 12px var(--pi-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); overflow-wrap: anywhere; }
250
+ .config-path-card small, .field small { color: var(--pi-muted); }
251
+ .field-heading { display: flex; align-items: center; gap: 8px; }
252
+ textarea { resize: vertical; min-height: 94px; --ui-input-font-family: var(--pi-control-monospace-font-family, var(--pi-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)); }
253
+ textarea:disabled { opacity: .55; }
254
+ .override-badge { border: 1px solid var(--pi-warning-border); border-radius: 999px; color: var(--pi-warning); background: var(--pi-warning-surface); padding: 2px 7px; font-size: 11px; font-weight: 600; text-transform: none; }
255
+ .effective-card dl { display: grid; gap: 8px; margin: 0; }
256
+ .effective-card dl > div { display: grid; grid-template-columns: 130px minmax(0, 1fr); gap: 12px; align-items: baseline; }
257
+ dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
258
+ .muted { color: var(--pi-muted); }
259
+ .form-actions small { align-self: center; color: var(--pi-muted); padding-inline-end: 12px; }
260
+
261
+ @media (max-width: 760px) {
262
+ .effective-card dl > div { grid-template-columns: minmax(0, 1fr); gap: 3px; }
263
+ }
264
+ }
265
+ `]}};w([m({attribute:!1})],I.prototype,`configResponse`,void 0),w([m({attribute:!1})],I.prototype,`machineConfigResponse`,void 0),w([m({type:Boolean})],I.prototype,`loading`,void 0),w([m({type:Boolean})],I.prototype,`machineLoading`,void 0),w([m({type:Boolean})],I.prototype,`saving`,void 0),w([m()],I.prototype,`error`,void 0),w([m()],I.prototype,`machineError`,void 0),w([m()],I.prototype,`savedMessage`,void 0),w([m()],I.prototype,`targetLabel`,void 0),w([m()],I.prototype,`targetId`,void 0),w([m({attribute:!1})],I.prototype,`onReload`,void 0),w([m({attribute:!1})],I.prototype,`onReloadMachine`,void 0),w([m({attribute:!1})],I.prototype,`onSave`,void 0),w([m({attribute:!1})],I.prototype,`onSaveMachineConfig`,void 0),w([b()],I.prototype,`gatewayDraft`,void 0),w([b()],I.prototype,`machineDraft`,void 0),w([b()],I.prototype,`gatewayLocalError`,void 0),w([b()],I.prototype,`machineLocalError`,void 0),I=w([y(`settings-general-panel`)],I);function Me(e){return e===!0?O(`ui.settingsGeneralPanel.anyHost`,`Any host`):Array.isArray(e)?e.length===0?D`<span class="muted">${O(`ui.settingsGeneralPanel.noneListed`,`None listed`)}</span>`:e.join(`, `):D`<span class="muted">${O(`ui.settingsGeneralPanel.notSet`,`Not set`)}</span>`}function Ne(e){return e===void 0||e.length===0?D`<span class="muted">${O(`ui.settingsGeneralPanel.externalPathsDenied`,`External paths denied`)}</span>`:e.join(`, `)}function L(e){return e.target instanceof HTMLInputElement?e.target.value:``}function Pe(e){return e.target instanceof HTMLSelectElement?e.target.value:``}function Fe(e){return e.target instanceof HTMLTextAreaElement?e.target.value:``}function R(e,t){for(let n in e)if(e[n]!==t[n])return!1;return!0}function Ie(e){return e instanceof Error?e.message:String(e)}var z=class extends k{constructor(){super(),this.themes=[],this.preference=l,this.defaultPreference=l,this.activeThemeId=``,this.hasLocalOverride=!1,this.loading=!1,this.saving=!1,this.draft={...l},i.createController(this)}willUpdate(e){e.has(`preference`)&&(this.draft={...this.preference})}updated(){let e=this.renderRoot.querySelector(`select`);e!==null&&(e.value=n(this.themes,this.draft.themeId)?.id??this.draft.themeId)}render(){let e=n(this.themes,this.draft.themeId),t=e!==void 0,r={...this.draft,themeId:e?.id??this.draft.themeId},i=this.loading||this.saving;return D`
266
+ <section class="theme-card ui-settings-section" aria-labelledby="theme-heading">
267
+ <header class="ui-settings-heading">
268
+ <h3 id="theme-heading">${O(`ui.settingsThemePanel.title`,`Theme`)}</h3>
269
+ <p>${O(`ui.settingsThemePanel.scope`,`Choose a theme for this browser, or save the gateway default.`)}</p>
270
+ </header>
271
+ <div class="current-theme ui-settings-summary" role="status">
272
+ <strong>${this.hasLocalOverride?O(`ui.settingsThemePanel.local`,`Using a theme saved in this browser`):O(`ui.settingsThemePanel.default`,`Using the default theme`)}</strong>
273
+ <span>${O(`ui.settingsThemePanel.current`,`Current: {theme}`,{theme:this.themeName(this.activeThemeId||this.preference.themeId)})}</span>
274
+ <span>${O(`ui.settingsThemePanel.defaultName`,`Default: {theme}`,{theme:this.themeName(this.defaultPreference.themeId)})}${this.defaultPreference.auto?O(`ui.settingsThemePanel.systemSuffix`,` · Follows system appearance`):``}</span>
275
+ </div>
276
+ <label class="field ui-form-field">
277
+ <span>${O(`ui.settingsThemePanel.title`,`Theme`)}</span>
278
+ <select class="ui-input" aria-label=${O(`ui.settingsThemePanel.title`,`Theme`)} aria-describedby=${t?`theme-scope-help`:`theme-unavailable-help theme-scope-help`} ?disabled=${i} @change=${e=>{e.target instanceof HTMLSelectElement&&(this.draft={...this.draft,themeId:e.target.value})}}>
279
+ ${t?null:D`<option value=${this.draft.themeId}>${O(`ui.settingsThemePanel.unavailable`,`{theme} (unavailable)`,{theme:this.draft.themeId})}</option>`}
280
+ ${this.themes.map(e=>D`<option value=${e.id}>${e.name}</option>`)}
281
+ </select>
282
+ </label>
283
+ ${t?null:D`<p id="theme-unavailable-help" role="status">${O(`ui.settingsThemePanel.unavailableHelp`,`This theme is unavailable. Choose an available theme, or enable the plugin that provides it.`)}</p>`}
284
+ <label class="auto-field ui-checkbox-field">
285
+ <input type="checkbox" .checked=${this.draft.auto} ?disabled=${i} @change=${e=>{e.target instanceof HTMLInputElement&&(this.draft={...this.draft,auto:e.target.checked})}}>
286
+ <span>${O(`ui.settingsThemePanel.auto`,`Follow system appearance`)} <small>${O(`ui.settingsThemePanel.autoHelp`,`Switch between light and dark versions when this theme supports both.`)}</small></span>
287
+ </label>
288
+ <div class="theme-actions ui-settings-actions">
289
+ <button class="primary ui-button ui-button--action ui-button--primary" ?disabled=${i||!t} @click=${()=>this.onUseLocal?.({...r})}>${O(`ui.settingsThemePanel.useLocal`,`Use in this browser`)}</button>
290
+ <button class="ui-button ui-button--action" ?disabled=${i||!t} @click=${()=>{this.onSetDefault?.({...r})}}>${O(`ui.settingsThemePanel.setDefault`,`Set gateway default`)}</button>
291
+ <button class="ui-button ui-button--action" ?disabled=${i||!this.hasLocalOverride} @click=${()=>this.onUseDefault?.()}>${O(`ui.settingsThemePanel.useDefault`,`Use the default`)}</button>
292
+ </div>
293
+ <p class="hint" id="theme-scope-help">${O(`ui.settingsThemePanel.scopeHelp`,`Setting a default leaves saved browser choices unchanged. Use the default to remove this browser's override.`)}</p>
294
+ </section>
295
+ `}themeName(e){return n(this.themes,e)?.name??O(`ui.settingsThemePanel.unavailable`,`{theme} (unavailable)`,{theme:e})}static{this.styles=[a,g,j,E`
296
+ :host { display: block; }
297
+ p { margin: 0; }
298
+ p, small { color: var(--pi-muted); line-height: 1.45; }
299
+ .current-theme span { color: var(--pi-text-secondary); font-size: 12px; overflow-wrap: anywhere; }
300
+ .auto-field span { display: grid; gap: 3px; }
301
+ .hint { font-size: 12px; }
302
+ `]}};w([m({attribute:!1})],z.prototype,`themes`,void 0),w([m({attribute:!1})],z.prototype,`preference`,void 0),w([m({attribute:!1})],z.prototype,`defaultPreference`,void 0),w([m()],z.prototype,`activeThemeId`,void 0),w([m({type:Boolean})],z.prototype,`hasLocalOverride`,void 0),w([m({type:Boolean})],z.prototype,`loading`,void 0),w([m({type:Boolean})],z.prototype,`saving`,void 0),w([m({attribute:!1})],z.prototype,`onUseLocal`,void 0),w([m({attribute:!1})],z.prototype,`onSetDefault`,void 0),w([m({attribute:!1})],z.prototype,`onUseDefault`,void 0),w([b()],z.prototype,`draft`,void 0),z=w([y(`settings-theme-panel`)],z);function Le(e){return{spawnSessions:e}}function Re(e){return{subsessions:e}}function ze(e){return{askUser:e}}function Be(e,t){let n=e?.effectiveConfig.agent;return n?.dir===void 0||t===void 0?`unavailable`:n.dir===t.dir?`active`:`restart-required`}function Ve(e,t){return e?.agentDirSource===`pi-web`||e?.agentDirSource===`pi-compatibility`||e?.agentDir===!0}function He(e,t){let n={...e.envOverrides,spawnSessions:t.envOverrides.spawnSessions,subsessions:t.envOverrides.subsessions,askUser:t.envOverrides.askUser,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}}var B=class extends k{constructor(){super(),this.loading=!1,this.saving=!1,this.error=``,this.savedMessage=``,this.targetLabel=O(`ui.settingsSessiondPanel.localLocalGateway`,`Local (local gateway)`),this.agentProfileSupport={state:`supported`},this.targetId=`local`,this.namingContextKey=``,this.namingModels=[],this.namingModelsLoading=!1,this.namingModelsError=``,this.namingPickerOpen=!1,this.agentDraft=F(),this.agentDraftDirty=!1,this.agentLocalError=``,i.createController(this)}willUpdate(e){(e.has(`targetId`)||e.has(`targetLabel`)||e.has(`namingContextKey`)||e.has(`loading`)&&this.loading||e.has(`namingModelsLoading`)&&this.namingModelsLoading)&&(this.namingPickerOpen=!1),e.has(`targetId`)&&(this.agentDraft=F(),this.agentDraftDirty=!1,this.agentLocalError=``),e.has(`configResponse`)&&(this.configResponse===void 0?(this.agentDraft=F(),this.agentDraftDirty=!1,this.agentLocalError=``):(!this.agentDraftDirty||Se(this.agentDraft,this.configResponse.config))&&(this.agentDraft=be(this.configResponse.config),this.agentDraftDirty=!1,this.agentLocalError=``))}render(){let e=this.configResponse,n=this.targetId,r=this.namingContextKey,i=this.namingModels.flatMap(e=>{if(e.provider===void 0||e.provider===``||e.id===void 0||e.id===``)return[];let t=`${e.provider}/${e.id}`;return[{value:t,label:e.name??e.id,description:t}]}),a=e?.envOverrides.spawnSessions===!0,o=e?.effectiveConfig.spawnSessions!==!1,c=e?.envOverrides.subsessions===!0,l=e?.effectiveConfig.subsessions===!0&&o,u=e?.effectiveConfig.askUser!==void 0,d=e?.envOverrides.askUser===!0,f=e?.effectiveConfig.askUser===!0,p=e?.envOverrides.agentCommand===!0,m=this.agentProfileSupport.state===`supported`,h=p?e.effectiveConfig.agent?.command??this.agentDraft.command:this.agentDraft.command,g=Ve(e?.envOverrides,h),ee=e?.envOverrides.agentDir===!0,_=e?.effectiveConfig.agent,v=Be(e,this.activeAgentProfile);return D`
303
+ <settings-panel-frame
304
+ heading="${O(`bundled.updates.session.daemon.757666`,`Session daemon`)}"
305
+ .description=${Ke(this.targetLabel)}
306
+ actionLabel="${O(`ui.settingsPackagesPanel.reload`,`Reload`)}"
307
+ .actionDisabled=${this.loading}
308
+ .notices=${this.panelNotices(e)}
309
+ .onAction=${this.onReload}
310
+ >
311
+ <section class="ui-settings-section">
312
+ ${e===void 0?this.renderUnavailableConfigState():D`
313
+ <div class="config-path-card ui-settings-path">
314
+ <span>${O(`ui.settingsShortcutsPanel.configurationFile`,`Configuration file`)}</span>
315
+ <code>${e.path}</code>
316
+ </div>
317
+ <form class="profile-form ui-settings-fields" aria-label="${O(`ui.settingsSessiondPanel.piCompatibleAgentProfile`,`Pi-compatible agent profile`)}" @submit=${e=>{this.saveAgentProfile(e,n)}}>
318
+ ${m?null:D`<div class="profile-support-message">${this.agentProfileSupport.message??O(`ui.settingsSessiondPanel.thisMachineDoesNotSupportEditingPiCompatible`,`This machine does not support editing Pi-compatible agent profiles.`)}</div>`}
319
+ <label class="field ui-form-field">
320
+ <span class="field-heading">
321
+ <span>${O(`ui.settingsSessiondPanel.companionCliCommand`,`Companion CLI command`)}</span>
322
+ ${p?D`<span class="override-badge">${O(`ui.settingsGeneralPanel.environmentOverrides`,`Environment overrides`)}</span>`:null}
323
+ </span>
324
+ <input
325
+ class="text-input ui-input"
326
+ type="text"
327
+ autocomplete="off"
328
+ spellcheck="false"
329
+ .value=${this.agentDraft.command}
330
+ placeholder="pi"
331
+ ?disabled=${this.loading||this.saving||!m||p}
332
+ @input=${e=>{this.updateAgentDraft({command:We(e)})}}
333
+ >
334
+ <small>${O(`ui.settingsSessiondPanel.setThePiCompatibleCompanionCliUsedFor`,`Set the Pi-compatible companion CLI used for diagnostics and update checks. Embedded sessions still use the Pi SDK bundled with PI WEB.`)}</small>
335
+ </label>
336
+ <label class="field ui-form-field">
337
+ <span class="field-heading">
338
+ <span>${O(`ui.settingsSessiondPanel.profileStateDirectory`,`Profile state directory`)}</span>
339
+ ${ee?D`<span class="override-badge">${O(`ui.settingsGeneralPanel.environmentOverrides`,`Environment overrides`)}</span>`:null}
340
+ </span>
341
+ <input
342
+ class="text-input ui-input"
343
+ type="text"
344
+ autocomplete="off"
345
+ spellcheck="false"
346
+ .value=${this.agentDraft.dir}
347
+ placeholder="${O(`ui.settingsSessiondPanel.piAgentOrAgentProfilesWork`,`~/.pi/agent or ~/agent-profiles/work`)}"
348
+ ?disabled=${this.loading||this.saving||!m||g}
349
+ @input=${e=>{this.updateAgentDraft({dir:We(e)})}}
350
+ >
351
+ <small>${O(`ui.settingsSessiondPanel.chooseThePiCompatibleAuthenticationModelSettingsAnd`,`Choose the Pi-compatible authentication, model, settings, and session directory PI WEB reads. Alternate commands are saved with their required state directory.`)}</small>
352
+ </label>
353
+ <footer class="form-actions ui-settings-actions">
354
+ <button class="primary ui-button ui-button--action ui-button--primary" type="submit" ?disabled=${this.loading||this.saving||!m||p&&g}>${this.saving?O(`ui.settingsGeneralPanel.saving`,`Saving…`):O(`ui.settingsSessiondPanel.saveAgentProfile`,`Save agent profile`)}</button>
355
+ </footer>
356
+ </form>
357
+ <div class="field ui-form-field">
358
+ <span class="field-heading">
359
+ <span>${O(`ui.settingsSessiondPanel.allowAgentsToStartSessions`,`Allow agents to start sessions`)}</span>
360
+ ${a?D`<span class="override-badge">${O(`ui.settingsGeneralPanel.environmentOverrides`,`Environment overrides`)}</span>`:null}
361
+ </span>
362
+ <label class="toggle ui-checkbox-field">
363
+ <input
364
+ type="checkbox"
365
+ id="spawn-sessions"
366
+ aria-describedby="spawn-sessions-help"
367
+ .checked=${S(o)}
368
+ ?disabled=${this.loading||this.saving||a}
369
+ @change=${e=>{this.toggleSpawnSessions(e)}}
370
+ >
371
+ <span>${O(`ui.settingsSessiondPanel.enable`,`Enable`)} <code>spawn_session</code> ${O(`ui.chatView.tool`,`Tool`)}</span>
372
+ </label>
373
+ <small id="spawn-sessions-help">${O(`ui.settingsSessiondPanel.whenEnabledTheLlmCanStartSessionsWithin`,`When enabled, the LLM can start sessions within workspaces of the same registered project, including any worktree, so every spawned session appears here. Enabled by default.`)}</small>
374
+ </div>
375
+ <div class="field ui-form-field">
376
+ <span class="field-heading">
377
+ <span>${O(`ui.settingsSessiondPanel.allowAgentsToStartTrackedSubsessions`,`Allow agents to start tracked subsessions`)}</span>
378
+ ${c?D`<span class="override-badge">${O(`ui.settingsGeneralPanel.environmentOverrides`,`Environment overrides`)}</span>`:null}
379
+ </span>
380
+ <label class="toggle ui-checkbox-field">
381
+ <input
382
+ type="checkbox"
383
+ id="subsessions"
384
+ aria-describedby="subsessions-help"
385
+ .checked=${S(l)}
386
+ ?disabled=${this.loading||this.saving||c||!o}
387
+ @change=${e=>{this.toggleSubsessions(e)}}
388
+ >
389
+ <span>${O(`ui.settingsSessiondPanel.enable`,`Enable`)} <code>spawn_subsession</code> ${O(`ui.chatView.tool`,`Tool`)}</span>
390
+ </label>
391
+ <small id="subsessions-help">${O(`ui.main.ff88ab94196f`,`Agents can start child sessions they stay attached to (`)}<code>spawn_subsession</code>${O(`bundled.info.list.separator`,`, `)}<code>list_subsessions</code>${O(`bundled.info.list.separator`,`, `)}<code>check_subsession</code>${O(`bundled.info.list.separator`,`, `)}<code>read_subsession</code>${O(`ui.main.c36dc9dce940`,`) and are notified when a child finishes. Requires "Allow agents to start sessions". On by default.`)}</small>
392
+ </div>
393
+ <div class="field ui-form-field">
394
+ <span class="field-heading">
395
+ <span>${O(`ui.settingsSessiondPanel.allowAgentsToAskQuestions`,`Allow agents to ask questions`)}</span>
396
+ ${d?D`<span class="override-badge">${O(`ui.settingsGeneralPanel.environmentOverrides`,`Environment overrides`)}</span>`:null}
397
+ </span>
398
+ <label class="toggle ui-checkbox-field">
399
+ <input
400
+ type="checkbox"
401
+ aria-label="${O(`ui.settingsSessiondPanel.enableAgentQuestions`,`Enable agent questions`)}"
402
+ .checked=${S(f)}
403
+ ?disabled=${this.loading||this.saving||d||!u}
404
+ @change=${e=>{this.toggleAskUser(e)}}
405
+ >
406
+ <span>${O(`ui.settingsSessiondPanel.enable`,`Enable`)} <code>ask_user</code> ${O(`ui.chatView.tool`,`Tool`)}</span>
407
+ </label>
408
+ <small>${u?D`${O(`ui.settingsSessiondPanel.agentsCanPresentStructuredQuestionFormsAndPause`,`Agents can present structured question forms and pause for answers. Enabled by default.`)}`:D`${O(`ui.settingsSessiondPanel.thisMachineDoesNotProvideAgentQuestionSettings`,`This machine does not provide agent question settings. Update and restart PI WEB on that machine.`)}`}</small>
409
+ </div>
410
+ <section class="effective-card ui-settings-summary" aria-label="${O(`ui.settingsGeneralPanel.effectiveConfigurationSummary`,`Effective configuration summary`)}">
411
+ <h3>${O(`ui.settingsSessiondPanel.effectiveConfigurationAfterEnvironmentOverrides`,`Effective configuration after environment overrides`)}</h3>
412
+ <dl>
413
+ <div><dt>${O(`ui.settingsSessiondPanel.desiredCommand`,`Desired command`)}</dt><dd>${_?.command??D`<span class="muted">${O(`bundled.info.unavailable.460b35`,`Unavailable`)}</span>`}</dd></div>
414
+ <div><dt>${O(`ui.settingsSessiondPanel.desiredStateDirectory`,`Desired state directory`)}</dt><dd>${_?.dir??D`<span class="muted">${O(`bundled.info.unavailable.460b35`,`Unavailable`)}</span>`}</dd></div>
415
+ <div><dt>${O(`ui.settingsSessiondPanel.currentStateDirectory`,`Current state directory`)}</dt><dd>${this.activeAgentProfile?.dir??D`<span class="muted">${O(`bundled.info.unavailable.460b35`,`Unavailable`)}</span>`}</dd></div>
416
+ <div><dt>${O(`ui.settingsSessiondPanel.profileStatus`,`Profile status`)}</dt><dd>${Ue(v)}</dd></div>
417
+ <div><dt>${O(`ui.settingsSessiondPanel.spawnedSessions`,`Spawned sessions`)}</dt><dd>${o?O(`ui.settingsSessiondPanel.enabled`,`Enabled`):D`<span class="muted">${O(`ui.settingsShortcutsPanel.disabled`,`Disabled`)}</span>`}</dd></div>
418
+ <div><dt>${O(`ui.settingsSessiondPanel.subsessions`,`Subsessions`)}</dt><dd>${l?O(`ui.settingsSessiondPanel.enabled`,`Enabled`):D`<span class="muted">${O(`ui.settingsShortcutsPanel.disabled`,`Disabled`)}</span>`}</dd></div>
419
+ <div><dt>${O(`ui.settingsSessiondPanel.agentQuestions`,`Agent questions`)}</dt><dd>${u?f?O(`ui.settingsSessiondPanel.enabled`,`Enabled`):D`<span class="muted">${O(`ui.settingsShortcutsPanel.disabled`,`Disabled`)}</span>`:D`<span class="muted">${O(`bundled.info.unavailable.460b35`,`Unavailable`)}</span>`}</dd></div>
420
+ </dl>
421
+ </section>
422
+ <h3>${O(`ui.sessionNaming.heading`,`Session naming`)}</h3>
423
+ <div class="field ui-form-field">
424
+ <span id="session-naming-model-label">${O(`ui.sessionNaming.model`,`Naming model`)}</span>
425
+ <button id="session-naming-model" class="ui-button ui-button--action naming-model"
426
+ type="button" aria-labelledby="session-naming-model-label session-naming-model-value"
427
+ aria-describedby="session-naming-model-help" aria-haspopup="dialog"
428
+ ?disabled=${this.loading||this.saving||this.namingModelsLoading}
429
+ @click=${()=>{this.namingPickerOpen=!0}}>
430
+ <span id="session-naming-model-value">${e.config.sessionNaming?.model??O(`ui.sessionNaming.useSessionModel`,`Use session model`)}</span>
431
+ <span aria-hidden="true">▾</span>
432
+ </button>
433
+ <small id="session-naming-model-help">${O(`ui.sessionNaming.modelHelp`,`Search models available for this authentication context, or use the session model.`)}</small>
434
+ ${this.namingModelsLoading?D`<small role="status">${O(`ui.sessionNaming.modelsLoading`,`Loading naming models…`)}</small>`:null}
435
+ ${this.namingModelsError===``?null:D`<small role="status">${this.namingModelsError} ${O(`ui.sessionNaming.modelsRetry`,`Refresh settings to try again. Your saved model is unchanged.`)}</small>`}
436
+ ${!this.namingModelsLoading&&this.namingModelsError===``&&i.length===0?D`<small role="status">${O(`ui.sessionNaming.noModels`,`No naming models are available. Configure provider authentication, then refresh settings.`)}</small>`:null}
437
+ ${!this.namingModelsLoading&&this.namingModelsError===``&&e.config.sessionNaming?.model!==void 0&&!i.some(t=>t.value===e.config.sessionNaming?.model)?D`<small role="status">${O(`ui.sessionNaming.unavailableModel`,`The saved naming model is unavailable. Choose another model or use the session model.`)}</small>`:null}
438
+ </div>
439
+ <div class="field ui-form-field">
440
+ <label for="session-naming-max-tokens">${O(`ui.sessionNaming.maxTokens`,`Naming token budget`)}</label>
441
+ <input id="session-naming-max-tokens" class="ui-input" type="number" min="1" max="9007199254740991" step="1" placeholder="24"
442
+ aria-describedby="session-naming-max-tokens-help"
443
+ .value=${S(String(e.config.sessionNaming?.maxTokens??``))}
444
+ ?disabled=${this.loading||this.saving}
445
+ @change=${e=>{let t=e.target;t instanceof HTMLInputElement&&t.reportValidity()&&this.saveNamingField(`maxTokens`,t.value===``?void 0:t.valueAsNumber,n)}}>
446
+ <small id="session-naming-max-tokens-help">${O(`ui.sessionNaming.maxTokensHelp`,`Use a positive whole number. Clear to use 24 tokens, regardless of the model.`)}</small>
447
+ </div>
448
+ <div class="field ui-form-field">
449
+ <label for="session-naming-timeout">${O(`ui.sessionNaming.timeout`,`Naming timeout (seconds)`)}</label>
450
+ <input id="session-naming-timeout" class="ui-input" type="number" min="0.001" max="2147483.647" step="0.001" placeholder="10"
451
+ aria-describedby="session-naming-timeout-help"
452
+ .value=${S(e.config.sessionNaming?.timeoutMs===void 0?``:String(e.config.sessionNaming.timeoutMs/1e3))}
453
+ ?disabled=${this.loading||this.saving}
454
+ @change=${e=>{let t=e.target;t instanceof HTMLInputElement&&t.reportValidity()&&this.saveNamingField(`timeoutMs`,t.value===``?void 0:Math.round(t.valueAsNumber*1e3),n)}}>
455
+ <small id="session-naming-timeout-help">${O(`ui.sessionNaming.timeoutHelp`,`Total timeout includes model loading. Increase it for cold local engines. Clear to use 10 seconds.`)}</small>
456
+ </div>
457
+ <div class="field ui-form-field">
458
+ <label for="session-naming-thinking-level">${O(`ui.sessionNaming.thinkingLevel`,`Naming thinking level`)}</label>
459
+ <select id="session-naming-thinking-level" class="ui-select"
460
+ aria-describedby="session-naming-thinking-level-help"
461
+ .value=${S(e.config.sessionNaming?.thinkingLevel??``)}
462
+ ?disabled=${this.loading||this.saving}
463
+ @change=${e=>{let r=e.target;r instanceof HTMLSelectElement&&(r.value===``||t(r.value))&&this.saveNamingField(`thinkingLevel`,r.value===``?void 0:r.value,n)}}>
464
+ <option value="">${O(`ui.sessionNaming.defaultThinking`,`Default (minimal)`)}</option>
465
+ ${s.map(e=>D`<option value=${e}>${e}</option>`)}
466
+ </select>
467
+ <small id="session-naming-thinking-level-help">${O(`ui.sessionNaming.thinkingHelp`,`Controls reasoning for naming only. Off disables optional thinking where supported; model support varies.`)}</small>
468
+ </div>
469
+ <section class="effective-card ui-settings-summary" aria-labelledby="naming-summary-heading" aria-describedby="naming-summary-help">
470
+ <h3 id="naming-summary-heading">${O(`ui.sessionNaming.nextRequestHeading`,`For the next naming request`)}</h3>
471
+ <small id="naming-summary-help">${O(`ui.sessionNaming.nextRequestHelp`,`Saved naming settings apply without a restart. Existing names and in-progress naming requests are unchanged.`)}</small>
472
+ <dl>
473
+ <div><dt>${O(`ui.sessionNaming.model`,`Naming model`)}</dt><dd>${e.effectiveConfig.sessionNaming?.model??O(`ui.sessionNaming.useSessionModel`,`Use session model`)}</dd></div>
474
+ <div><dt>${O(`ui.sessionNaming.maxTokens`,`Naming token budget`)}</dt><dd>${e.effectiveConfig.sessionNaming?.maxTokens??24}</dd></div>
475
+ <div><dt>${O(`ui.sessionNaming.timeoutSummary`,`Naming timeout`)}</dt><dd>${O(`ui.sessionNaming.seconds`,`{seconds} seconds`,{seconds:String((e.effectiveConfig.sessionNaming?.timeoutMs??1e4)/1e3)})}</dd></div>
476
+ <div><dt>${O(`ui.sessionNaming.thinkingLevel`,`Naming thinking level`)}</dt><dd>${e.effectiveConfig.sessionNaming?.thinkingLevel??`minimal`}</dd></div>
477
+ </dl>
478
+ </section>
479
+ `}
480
+ </section>
481
+ </settings-panel-frame>
482
+ ${this.namingPickerOpen?D`
483
+ <command-picker title=${O(`ui.sessionNaming.selectModel`,`Select naming model`)} searchable
484
+ .options=${[{value:``,label:O(`ui.sessionNaming.useSessionModel`,`Use session model`),description:O(`ui.sessionNaming.sessionModelHelp`,`Use the conversation’s model for naming.`)},...this.namingModelsLoading||this.namingModelsError!==``?[]:i]}
485
+ .selectedValue=${e?.config.sessionNaming?.model??``}
486
+ .onCancel=${()=>{this.namingPickerOpen=!1}}
487
+ .onPick=${e=>{this.loading||this.saving||n!==this.targetId||r!==this.namingContextKey||(e===``||!this.namingModelsLoading&&this.namingModelsError===``&&i.some(t=>t.value===e))&&(this.namingPickerOpen=!1,this.saveNamingField(`model`,e===``?void 0:e,n))}}
488
+ ></command-picker>
489
+ `:null}
490
+ `}panelNotices(e){return qe(e,{error:this.agentLocalError||this.error,savedMessage:this.savedMessage,activeProfile:this.activeAgentProfile,targetLabel:this.targetLabel,profileEditingSupported:this.agentProfileSupport.state===`supported`})}renderUnavailableConfigState(){return D`<div class="loading-card">${this.loading?O(`ui.settingsSessiondPanel.loadingConfiguration`,`Loading configuration…`):O(`ui.settingsSessiondPanel.configurationUnavailableReload`,`Configuration unavailable. Reload.`)}</div>`}async saveAgentProfile(e,t=this.targetId){if(e.preventDefault(),!(t!==this.targetId||this.loading||this.saving)){this.agentLocalError=``;try{await this.onSave?.(xe(this.agentDraft))}catch(e){this.agentLocalError=Ge(e)}}}updateAgentDraft(e){this.agentDraft={...this.agentDraft,...e},this.agentDraftDirty=!0,this.agentLocalError=``}async saveNamingField(e,t,n=this.targetId){if(n!==this.targetId||this.loading||this.saving||this.configResponse===void 0)return;let r={...this.configResponse.config.sessionNaming,[e]:t},i={...r.model===void 0?{}:{model:r.model},...r.maxTokens===void 0?{}:{maxTokens:r.maxTokens},...r.thinkingLevel===void 0?{}:{thinkingLevel:r.thinkingLevel},...r.timeoutMs===void 0?{}:{timeoutMs:r.timeoutMs}};await this.onSave?.({sessionNaming:i})}async toggleSpawnSessions(e){let t=e.target instanceof HTMLInputElement&&e.target.checked;await this.onSave?.(Le(t))}async toggleSubsessions(e){let t=e.target instanceof HTMLInputElement&&e.target.checked;await this.onSave?.(Re(t))}async toggleAskUser(e){let t=e.target instanceof HTMLInputElement&&e.target.checked;await this.onSave?.(ze(t))}static{this.styles=[a,g,j,E`
491
+ @layer pi-web-base {
492
+ :host { display: block; }
493
+ h3 { margin: 0; font-size: 13px; line-height: 1.3; }
494
+ .loading-card { color: var(--pi-muted); }
495
+ .config-path-card span, dt { color: var(--pi-muted); font-size: 12px; font-weight: 600; }
496
+ code { border: 1px solid var(--pi-border-muted); border-radius: 5px; background: var(--pi-bg); padding: 1px 4px; color: var(--pi-text); font: 12px var(--pi-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); overflow-wrap: anywhere; }
497
+ .field small, .effective-card small { color: var(--pi-muted); line-height: 1.45; }
498
+ .naming-model { justify-content: space-between; text-align: start; gap: 12px; }
499
+ #session-naming-model-value { min-width: 0; overflow-wrap: anywhere; }
500
+ .effective-card dl { display: grid; gap: 8px; margin: 0; }
501
+ .effective-card dl > div { display: grid; grid-template-columns: 130px minmax(0, 1fr); gap: 12px; align-items: baseline; }
502
+ dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
503
+ .muted { color: var(--pi-muted); }
504
+
505
+ @media (max-width: 760px) {
506
+ .effective-card dl > div { grid-template-columns: minmax(0, 1fr); gap: 3px; }
507
+ }
508
+
509
+ }
510
+ `]}};w([m({attribute:!1})],B.prototype,`configResponse`,void 0),w([m({type:Boolean})],B.prototype,`loading`,void 0),w([m({type:Boolean})],B.prototype,`saving`,void 0),w([m()],B.prototype,`error`,void 0),w([m()],B.prototype,`savedMessage`,void 0),w([m()],B.prototype,`targetLabel`,void 0),w([m({attribute:!1})],B.prototype,`activeAgentProfile`,void 0),w([m({attribute:!1})],B.prototype,`agentProfileSupport`,void 0),w([m({attribute:!1})],B.prototype,`onReload`,void 0),w([m({attribute:!1})],B.prototype,`onSave`,void 0),w([m()],B.prototype,`targetId`,void 0),w([m()],B.prototype,`namingContextKey`,void 0),w([m({attribute:!1})],B.prototype,`namingModels`,void 0),w([m({type:Boolean})],B.prototype,`namingModelsLoading`,void 0),w([m()],B.prototype,`namingModelsError`,void 0),w([b()],B.prototype,`namingPickerOpen`,void 0),w([b()],B.prototype,`agentDraft`,void 0),w([b()],B.prototype,`agentDraftDirty`,void 0),w([b()],B.prototype,`agentLocalError`,void 0),B=w([y(`settings-sessiond-panel`)],B);function Ue(e){return e===`active`?O(`ui.settingsSessiondPanel.applied`,`Applied`):e===`restart-required`?O(`bundled.info.restart.needed.1ffd00`,`Restart needed`):D`<span class="muted">${O(`bundled.info.unavailable.460b35`,`Unavailable`)}</span>`}function We(e){return e.target instanceof HTMLInputElement?e.target.value:``}function Ge(e){return e instanceof Error?e.message:String(e)}function Ke(e){return O(`ui.sessionNaming.description`,`Configure agent permissions and session naming on {targetLabel}. Naming changes apply to the next naming request without a restart. Agent permission changes require that machine's session daemon to restart. Restarting interrupts active sessions and running work.`,{targetLabel:e})}function qe(e,t){let n=[];t.error!==``&&n.push({type:`error`,content:t.error}),t.savedMessage!==``&&n.push({type:`success`,content:t.savedMessage});let r=Be(e,t.activeProfile);return r===`restart-required`?n.push({type:`warning`,title:O(`ui.settingsSessiondPanel.piCompatibleAgentProfileOnRequiresARestart`,`Pi-compatible agent profile on {targetLabel} requires a restart`,{targetLabel:t.targetLabel}),content:D`${O(`ui.main.cbc1edd666c2`,`The desired state directory differs from the running session daemon. On that machine, run `)} <code>pi-web restart</code>${O(`ui.main.44de61cea1d8`,` (or restart its session daemon service) to apply the state directory.`)}`}):e!==void 0&&r===`unavailable`&&t.profileEditingSupported&&n.push({type:`info`,title:O(`ui.settingsSessiondPanel.unableToGetTheActivePiCompatibleAgent`,`Unable to get the active Pi-compatible agent profile on {targetLabel}`,{targetLabel:t.targetLabel}),content:O(`ui.settingsSessiondPanel.piWebCannotCompareTheDesiredProfileWith`,`PI WEB cannot compare the desired profile with the running session daemon profile. Reload when the daemon is available.`)}),n}function Je(e){return e===void 0?{id:`local`,name:O(`ui.piPackageSettings.local`,`Local`),kind:`local`}:{id:e.id,name:e.name,kind:e.kind}}function V(e){return e.kind===`local`?O(`ui.settingsMachineTarget.localGateway`,`{name} (local gateway)`,{name:e.name}):O(`ui.settingsMachineTarget.remoteMachine`,`{name} (remote machine)`,{name:e.name})}function Ye(e,t){return e.kind===`local`||t?.ok===!0?{state:`supported`}:{state:`unknown`}}function Xe(e){return`${e.state}:${e.message??``}`}function H(e){return e?.state===`unsupported`}function Ze(e){return O(`ui.piPackageSettings.doesNotSupportPiPackageManagementUpdateAnd`,`{name} does not support Pi package management. Update and restart PI WEB on that machine, then retry.`,{name:e.name})}function Qe(e){return e.kind===`local`}function $e(e){return e.trim()}function et(e){if($e(e)===``)return O(`ui.piPackageSettings.enterAPiSupportedPackageSourceSuchAs`,`Enter a Pi-supported package source, such as npm:@scope/package, a Git/URL source, or a local path.`)}function tt(e){return e.scope===`project`?O(`bundled.updates.project.scope.0d9798`,`Project scope`):O(`bundled.updates.user.scope.7baed5`,`User scope`)}function nt(e){return e.filtered?O(`ui.piPackageSettings.filteredByCurrentPiPackageSettings`,`Filtered by current Pi package settings`):O(`ui.piPackageSettings.availableToThisPiWebProcess`,`Available to this PI WEB process`)}function rt(e){return e.installedPath??O(`ui.piPackageSettings.piDidNotReportAnInstallationPath`,`Pi did not report an installation path`)}function it(e){return{packages:e.packages,...e.installableKnownPackages===void 0?{}:{installableKnownPackages:e.installableKnownPackages}}}function at(e){return e.scope===`user`}function ot(e){if(!at(e))return O(`ui.piPackageSettings.projectScopedPiPackagesAreListedHereBut`,`Project-scoped Pi packages are listed here, but PI WEB can only safely update user-scoped Pi packages in this interface.`)}function st(e){return e.length>0&&e.every(at)}function ct(e){if(e.length===0)return O(`ui.piPackageSettings.noPiPackagesConfigured`,`No Pi packages configured.`);if(!st(e))return O(`ui.piPackageSettings.theListIncludesProjectScopedPiPackagesSo`,`The list includes project-scoped Pi packages, so update-all is unavailable. Update user-scoped packages individually.`)}function U(e,t,n){return e?.kind===t?n===void 0||e.source===n:!1}function lt(e,t=Je(void 0)){let n=e===`install`?O(`ui.piPackageSettings.installed`,`installed`):e===`remove`?O(`ui.piPackageSettings.removed`,`removed`):O(`ui.piPackageSettings.updated`,`updated`),r=t.kind===`local`?``:`(${t.name})`,i=t.kind===`local`?O(`ui.piPackageSettings.everyIdlePiWebSession`,`every idle PI WEB session`):O(`ui.piPackageSettings.everyIdlePiWebSessionOn`,`every idle PI WEB session on {name}`,{name:t.name}),a=t.kind===`local`?O(`ui.piPackageSettings.piWebBrowserPluginChanges`,`PI WEB browser plugin changes`):O(`ui.piPackageSettings.piWebBrowserPluginChangesFrom`,`PI WEB browser plugin changes from {name}`,{name:t.name});return O(`ui.piPackageSettings.piPackageEnterReloadInToRediscoverPi`,`Pi package {verb}{targetSuffix}. Enter /reload in {sessionScope} to rediscover Pi runtime resources: extensions, skills, prompt templates, themes, and context/system prompt files. For {pluginScope}, also reload the browser page.`,{verb:n,targetSuffix:r,sessionScope:i,pluginScope:a})}function ut(e,t){let n=e.trim();return t.kind===`remote`?dt(n)?Ze(t):n===`Remote machine timeout`?O(`ui.piPackageSettings.timedOutContactingForPiPackageManagementThe`,`Timed out contacting {name} for Pi package management. The operation may still be running remotely; reload the package list before retrying.`,{name:t.name}):n===`Remote machine unavailable`?O(`ui.piPackageSettings.unableToConnectToForPiPackageManagement`,`Unable to connect to {name} for Pi package management. Check the machine connection and retry.`,{name:t.name}):n:n}function dt(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 W=class extends k{constructor(){super(),this.loading=!1,this.error=``,this.operationMessage=``,this.installSource=``,this.validationMessage=``,i.createController(this)}render(){let e=this.packagesResponse?.packages??[],t=this.packageTarget,n=V(t),r=this.packageManagementUnavailable,i=this.packagesResponse!==void 0&&!r;return D`
511
+ <settings-panel-frame
512
+ heading=${O(`ui.settingsPackagesPanel.piPackages`,`Pi packages`)}
513
+ .description=${ft(n)}
514
+ actionLabel=${O(`ui.settingsPackagesPanel.reload`,`Reload`)}
515
+ actionTitle=${r?this.packageManagementUnavailableMessage(n):O(`ui.settingsPackagesPanel.reloadPiPackagesFrom`,`Reload Pi packages from {targetLabel}`,{targetLabel:n})}
516
+ .actionDisabled=${this.loading||this.isOperating||r}
517
+ .notices=${this.panelNotices(n,i)}
518
+ .onAction=${this.onReload}
519
+ >
520
+ <p><a href="https://pi-web.dev/community-plugins" target="_blank" rel="noopener noreferrer">${O(`ui.settingsPackagesPanel.findCommunityPlugins`,`Find community plugins`)} ↗</a></p>
521
+ ${this.renderPanelContent(e,t,n)}
522
+ </settings-panel-frame>
523
+ `}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:D`<strong>${O(`ui.settingsPackagesPanel.trustedCodeWarning`,`Trusted code warning:`)}</strong>${O(`ui.settingsPackagesPanel.piPackagesAndPiWebPluginsCanRun`,`Pi packages and PI WEB plugins can run with your user permissions. Only install or enable trusted sources.`)}`}),n}renderPanelContent(e,t,n){return this.packageManagementUnavailable?null:this.packagesResponse===void 0?D`<div class="loading-card ui-settings-summary">${this.loading?O(`ui.settingsPackagesPanel.loadingPiPackagesFrom`,`Loading Pi packages from {targetLabel}…`,{targetLabel:n}):O(`ui.settingsPackagesPanel.piPackageListForIsUnavailableReload`,`Pi package list for {targetLabel} is unavailable. Reload.`,{targetLabel:n})}</div>`:D`
524
+ ${this.renderInstallableKnownPackages(n)}
525
+ ${this.renderInstallForm(n)}
526
+ ${this.renderPackageList(e,t)}
527
+ `}renderInstallableKnownPackages(e){let t=this.packagesResponse?.installableKnownPackages??[];return t.length===0?null:D`
528
+ <section class="known-package-section ui-settings-section" aria-label="${O(`ui.main.232934a9166e`,`Available known Pi packages`)}">
529
+ <div class="ui-settings-heading">
530
+ <h3>${O(`ui.main.fe790e3f4139`,`Available packages`)}</h3>
531
+ <p>${O(`ui.main.645753db4480`,`PI WEB ships these packages so you can install them on`)} ${e}${O(`ui.main.1d1f715fbd86`,`with one click, with no path to type — including one you previously removed.`)}</p>
532
+ </div>
533
+ <div class="known-package-list ui-settings-list">
534
+ ${t.map(e=>this.renderInstallableKnownPackage(e))}
535
+ </div>
536
+ </section>
537
+ `}renderInstallableKnownPackage(e){let t=U(this.operation,`install`,e.source);return D`
538
+ <article class="known-package-card ui-settings-row">
539
+ <div class="package-main">
540
+ <strong>${e.label}</strong>
541
+ <small>${e.description}</small>
542
+ </div>
543
+ <button class="ui-button ui-button--action ui-button--primary" title=${O(`ui.main.f3c72686db75`,`Install {arg0}`,{arg0:e.label})} ?disabled=${this.isOperating} @click=${()=>{this.installKnownPackage(e.source)}}>${t?O(`ui.settingsPackagesPanel.installing`,`Installing…`):O(`ui.settingsPackagesPanel.install`,`Install`)}</button>
544
+ </article>
545
+ `}renderInstallForm(e){return D`
546
+ <form class="install-card ui-settings-section" @submit=${e=>{this.installPackage(e)}}>
547
+ <label class="ui-form-field" for="package-source">${O(`ui.settingsPackagesPanel.piPackageSource`,`Pi package source`)}</label>
548
+ <div class="install-row">
549
+ <input class="ui-input" id="package-source" aria-describedby="package-source-help package-source-error" aria-invalid=${this.validationMessage===``?`false`:`true`} .value=${this.installSource} ?disabled=${this.isOperating} placeholder=${O(`ui.settingsPackagesPanel.npmScopePackageGitUrlOrLocalPath`,`npm:@scope/package, Git URL, or local path`)} @input=${e=>{this.updateInstallSource(e)}}>
550
+ <button class="ui-button ui-button--action ui-button--primary" type="submit" title=${O(`ui.settingsPackagesPanel.installThisPiPackage`,`Install this Pi package`)} ?disabled=${this.isOperating}>${U(this.operation,`install`)?O(`ui.settingsPackagesPanel.installing`,`Installing…`):O(`ui.settingsPackagesPanel.install`,`Install`)}</button>
551
+ </div>
552
+ <div class="field-error" id="package-source-error" role="alert">${this.validationMessage}</div>
553
+ <small id="package-source-help">${O(`ui.settingsPackagesPanel.installationScope`,`Installation runs on {machine} using Pi's default package location, equivalent to pi install <source>. PI WEB does not ask you to choose an installation location.`,{machine:e})}</small>
554
+ </form>
555
+ `}renderPackageList(e,t){let n=V(t),r=ct(e),i=r!==void 0&&e.length>0,a=r??O(`ui.settingsPackagesPanel.updateAllUserScopedPiPackages`,`Update all user-scoped Pi packages`);return D`
556
+ <section class="package-section ui-settings-section" aria-label=${O(`ui.settingsPackagesPanel.configuredPiPackages`,`Configured Pi packages`)}>
557
+ <div class="package-toolbar">
558
+ <div class="ui-settings-heading">
559
+ <h3>${O(`ui.settingsPackagesPanel.configuredPiPackages`,`Configured Pi packages`)}</h3>
560
+ <p>${O(`ui.settingsPackagesPanel.listScope`,`This list comes from Pi package manager settings on {machine}.`,{machine:n})}</p>
561
+ </div>
562
+ <button class="secondary ui-button ui-button--action" title=${a} ?disabled=${this.isOperating||r!==void 0} @click=${()=>{this.updatePackage()}}>
563
+ ${U(this.operation,`update-all`)?O(`ui.settingsPackagesPanel.updating`,`Updating…`):O(`ui.settingsPackagesPanel.updateAll`,`Update all`)}
564
+ </button>
565
+ </div>
566
+ ${i?D`<div class="action-note">${r}</div>`:null}
567
+ ${this.loading&&e.length>0?D`<div class="action-note">${O(`ui.settingsPackagesPanel.refreshingPackages`,`Refreshing Pi packages from {machine}…`,{machine:n})}</div>`:null}
568
+ ${this.renderPackageListContent(e,n)}
569
+ </section>
570
+ `}renderPackageListContent(e,t){return this.loading&&e.length===0?D`<div class="loading-card ui-settings-summary">${O(`ui.settingsPackagesPanel.loadingPackages`,`Loading Pi packages from {machine}…`,{machine:t})}</div>`:e.length===0?D`<div class="loading-card ui-settings-summary">${O(`ui.settingsPackagesPanel.noPackages`,`No Pi packages are configured in Pi settings on {machine}.`,{machine:t})}</div>`:D`
571
+ <div class="package-list ui-settings-list">
572
+ ${e.map(e=>this.renderPackage(e))}
573
+ </div>
574
+ `}renderPackage(e){let t=V(this.packageTarget),n=this.packageManagementUnavailable,r=n?this.packageManagementUnavailableMessage(t):ot(e),i=n?this.packageManagementUnavailableMessage(t):O(`ui.settingsPackagesPanel.removeThisPiPackage`,`Remove this Pi package`),a=U(this.operation,`update`,e.source),o=U(this.operation,`remove`,e.source);return D`
575
+ <article class=${`package-card ui-settings-row${e.filtered?` filtered`:``}`}>
576
+ <div class="package-main">
577
+ <strong>${e.source}</strong>
578
+ <small>${tt(e)} · ${nt(e)}</small>
579
+ <small>${O(`ui.settingsPackagesPanel.installationPath`,`Installation path: `)}<code>${rt(e)}</code></small>
580
+ ${r===void 0?null:D`<small class="action-note">${r}</small>`}
581
+ </div>
582
+ <div class="package-actions ui-settings-actions">
583
+ <button class="secondary ui-button ui-button--action" title=${r??O(`ui.settingsPackagesPanel.updateThisPiPackage`,`Update this Pi package`)} ?disabled=${this.isOperating||r!==void 0} @click=${()=>{this.updatePackage(e.source)}}>${a?O(`ui.settingsPackagesPanel.updating`,`Updating…`):O(`ui.settingsPackagesPanel.update`,`Update`)}</button>
584
+ <button class="danger ui-button ui-button--action" title=${i} ?disabled=${this.isOperating||n} @click=${()=>{this.removePackage(e)}}>${o?O(`ui.settingsPackagesPanel.removing`,`Removing…`):O(`ui.settingsPackagesPanel.remove`,`Remove`)}</button>
585
+ </div>
586
+ </article>
587
+ `}updateInstallSource(e){this.installSource=e.target instanceof HTMLInputElement?e.target.value:``,this.validationMessage=``}async installPackage(e){e.preventDefault();let t=et(this.installSource);if(t!==void 0){this.validationMessage=t;return}let n=$e(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 installKnownPackage(e){try{await this.onInstallPackage?.(e)}catch{}}async updatePackage(e){try{await this.onUpdatePackage?.(e)}catch{}}get packageTarget(){return this.targetMachine??Je(void 0)}get packageManagementUnavailable(){return H(this.managementSupport)}packageManagementUnavailableMessage(e){return this.managementSupport?.message??O(`ui.settingsPackagesPanel.doesNotSupportPiPackageManagement`,`{targetLabel} does not support Pi package management.`,{targetLabel:e})}get isOperating(){return this.operation!==void 0}static{this.styles=[a,g,j,E`
588
+ @layer pi-web-base {
589
+ :host { display: block; }
590
+ .package-toolbar { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 14px; }
591
+ .package-toolbar > div { flex: 1 1 240px; min-width: 0; }
592
+ .package-main { flex: 1 1 240px; display: grid; gap: 6px; min-width: 0; }
593
+ small { color: var(--pi-muted); line-height: 1.45; }
594
+ .secondary { flex: 0 0 auto; }
595
+ .field-error { color: var(--pi-danger); font-size: 12px; }
596
+ .field-error:empty { display: none; }
597
+ .install-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: center; }
598
+ .known-package-section, .package-section { padding: 0; gap: 0; }
599
+ .known-package-section > .ui-settings-heading, .package-toolbar { padding: 16px; }
600
+ .loading-card, .action-note { color: var(--pi-muted); }
601
+ .action-note { font-size: 12px; }
602
+ .package-section > .action-note { padding: 0 16px 12px; }
603
+ .package-card, .known-package-card { align-items: center; }
604
+ .package-card.filtered { opacity: .82; }
605
+ .package-main strong, .package-main small { overflow-wrap: anywhere; }
606
+ code { color: var(--pi-text); font: 12px var(--pi-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); overflow-wrap: anywhere; }
607
+
608
+ @media (max-width: 760px) {
609
+ .install-row { grid-template-columns: minmax(0, 1fr); }
610
+ .install-row > .ui-button { justify-self: start; }
611
+ .package-main { flex-basis: 100%; }
612
+ }
613
+
614
+ }
615
+ `]}};w([m({attribute:!1})],W.prototype,`packagesResponse`,void 0),w([m({type:Boolean})],W.prototype,`loading`,void 0),w([m({attribute:!1})],W.prototype,`operation`,void 0),w([m({attribute:!1})],W.prototype,`targetMachine`,void 0),w([m({attribute:!1})],W.prototype,`managementSupport`,void 0),w([m()],W.prototype,`error`,void 0),w([m()],W.prototype,`operationMessage`,void 0),w([m({attribute:!1})],W.prototype,`onReload`,void 0),w([m({attribute:!1})],W.prototype,`onInstallPackage`,void 0),w([m({attribute:!1})],W.prototype,`onRemovePackage`,void 0),w([m({attribute:!1})],W.prototype,`onUpdatePackage`,void 0),w([b()],W.prototype,`installSource`,void 0),w([b()],W.prototype,`validationMessage`,void 0),W=w([y(`settings-packages-panel`)],W);function ft(e){return D`${O(`ui.settingsPackagesPanel.manage`,`Manage `)} <strong>${e}</strong> ${O(`ui.settingsPackagesPanel.piPackagesInstallRemoveAndUpdatePiManaged`,` Pi packages. Install, remove, and update Pi-managed packages on the selected machine. Pi packages can provide extensions, skills, prompt templates, themes, context/system prompt files, and PI WEB browser plugins.`)}`}var G=class extends k{constructor(){super(),this.loading=!1,this.saving=!1,this.recoveryCommandsSupported=!1,this.error=``,this.savedMessage=``,this.targetLabel=O(`ui.settingsSessiondPanel.localLocalGateway`,`Local (local gateway)`),i.createController(this)}render(){let e=pt(this.pluginsResponse,this.configResponse),t=this.pluginsResponse!==void 0;return D`
616
+ <settings-panel-frame
617
+ heading="${O(`client.machinePluginLoadCoordinator.pi.web.plugins.54b78f`,`PI WEB plugins`)}"
618
+ .description=${_t(this.targetLabel)}
619
+ actionLabel="${O(`ui.settingsPackagesPanel.reload`,`Reload`)}"
620
+ actionTitle=${O(`ui.settingsPluginsPanel.reloadPiWebPluginsFrom`,`Reload PI WEB plugins from {targetLabel}`,{targetLabel:this.targetLabel})}
621
+ .actionDisabled=${this.loading}
622
+ .notices=${this.panelNotices(e.length>0)}
623
+ .onAction=${this.onReload}
624
+ >
625
+ ${this.renderPanelContent(e,t)}
626
+ </settings-panel-frame>
627
+ `}panelNotices(e){let t=[];this.error!==``&&t.push({type:`error`,content:this.error}),this.shouldShowConfigUnavailableNotice(e)&&t.push({type:`availability`,content:O(`ui.settingsPluginsPanel.configurationUnavailableReloadBeforeChangingPluginActivation`,`Configuration unavailable. Reload before changing plugin activation.`)}),this.savedMessage!==``&&t.push({type:`success`,content:this.savedNotice()});let n=this.pluginsResponse?.serverRuntime;n?.status===`unavailable`?t.push({type:`availability`,title:O(`ui.main.a82125df2e73`,`Active server-plugin state unavailable`),content:D`${O(`ui.main.6287fc62588d`,`Desired config remains editable, but PI WEB cannot verify the sessiond snapshot. `)}${n.message??O(`ui.main.2cf299cf47cb`,`Restart or reconnect sessiond, then reload.`)}`}):n?.status===`incompatible`&&t.push({type:`error`,title:O(`ui.main.712114e46934`,`Plugin lifecycle version mismatch`),content:D`${n.message??O(`ui.main.9b21bc233c7c`,`The web process and session daemon do not support the same plugin lifecycle protocol.`)}${O(`ui.main.b080e2709663`,` Update and restart both components before loading server-backed browser plugins.`)}`}),n?.safeStart!==void 0&&t.push({type:`warning`,title:O(`ui.main.0a4319cf8398`,`Server-plugin safe mode active`),content:n.safeStart===`bundled-only`?D`${O(`ui.main.b9dae93a22c0`,`Only bundled server plugins were imported. Clear safe mode with`)} <code>${n.recovery.clearSafeStart}</code>.`:D`${O(`ui.main.66b054df2b58`,`No server plugins were imported; Terminal is unavailable and the kernel folder workspace remains available for diagnosis. Clear safe mode with`)} <code>${n.recovery.clearSafeStart}</code>.`}),n?.desiredSafeStart!==void 0&&n.desiredSafeStart!==(n.safeStart??`off`)&&t.push({type:`warning`,title:O(`ui.main.298ed29158e3`,`Safe-mode restart pending`),content:n.desiredSafeStart===`off`?O(`ui.main.49a77159c6e3`,`Safe start is cleared in offline config but remains active until sessiond restarts.`):O(`ui.main.d2ac58b29d16`,`Offline configuration requests safe-start mode {arg0}; it takes effect before plugin imports on the next sessiond restart.`,{arg0:n.desiredSafeStart})}),n?.restartRequired===!0&&t.push({type:`warning`,title:O(`ui.main.612b234166d8`,`Session-daemon restart required`),content:O(`ui.main.484f6a3d0361`,`Desired plugin config or package revisions differ from sessiond's active startup snapshot. Restarting sessiond may interrupt active sessions.`)});for(let e of this.pluginsResponse?.diagnostics??[])t.push({type:e.kind===`conflict`?`error`:`warning`,title:e.kind===`conflict`?O(`ui.main.609dbc2f0e1d`,`Plugin id conflict`):O(`ui.main.35e12ff16006`,`Plugin discovery diagnostic`),content:`${e.snapshot===`active`?O(`ui.main.54f92b108f4c`,`Active snapshot`):O(`ui.main.7431e6af59cf`,`Desired catalog`)}: ${e.message}`});return e&&t.push({type:`security`,content:D`<strong>${O(`ui.settingsPackagesPanel.trustedCodeWarning`,`Trusted code warning:`)}</strong>${O(`ui.settingsPluginsPanel.piWebPluginsAndPiPackagesCanRun`,`PI WEB plugins and Pi packages can run with your user permissions. Only enable plugins from trusted sources.`)}`}),t}savedNotice(){return this.pluginsResponse?.serverRuntime.status!==`available`||this.pluginsResponse.serverRuntime.restartRequired?O(`ui.main.2e4750a31e03`,`{arg0} Restart the session daemon to apply server plugin changes; browser-only changes take effect after reloading this tab.`,{arg0:this.savedMessage}):O(`ui.main.ccf27b0f4ff9`,`{arg0} Reload the browser tab to apply browser-only plugin changes.`,{arg0:this.savedMessage})}shouldShowConfigUnavailableNotice(e){return e&&this.configResponse===void 0&&!this.loading&&this.error===``}renderPanelContent(e,t){return!t&&e.length===0?D`
628
+ <div class="loading-card ui-settings-summary">${this.loading?O(`ui.settingsPluginsPanel.loadingPiWebPlugins`,`Loading PI WEB plugins…`):O(`ui.settingsPluginsPanel.piWebPluginListForIsUnavailableReload`,`PI WEB plugin list for {targetLabel} is unavailable. Reload.`,{targetLabel:this.targetLabel})}</div>
629
+ ${this.renderRecoveryCommands()}
630
+ `:e.length===0?D`
631
+ <div class="loading-card ui-settings-summary">${O(`ui.main.686b703f41f3`,`No PI WEB plugins are discovered or active on`)} ${this.targetLabel} ${O(`ui.main.b7ad7cf69387`,`.`)}</div>
632
+ ${this.renderRecoveryCommands()}
633
+ `:D`
634
+ <div class="plugin-note ui-settings-summary">${this.targetLabel} ${O(`ui.main.2432ea1a4c8b`,`:`)} <code>plugins</code>${O(`ui.main.8ccf013eb3c2`,`. Browser-only changes apply after a tab reload; server-backed changes follow sessiond's startup snapshot and can require a manual restart.`)}</div>
635
+ <div class="plugin-list ui-settings-list">
636
+ ${e.map(e=>this.renderPlugin(e))}
637
+ </div>
638
+ ${this.renderRecoveryCommands()}
639
+ `}renderPlugin(e){let t=this.configResponse?.config.plugins?.[e.id],n=e.required===!0?O(`ui.main.fb76852a3fdc`,`Required · ordinary config cannot disable`):!e.discovered&&t===void 0?O(`ui.main.ccf65fb6a4e5`,`Desired package/config absent`):t?.enabled===!1?O(`ui.settingsPluginsPanel.disabledByConfiguration`,`Disabled by configuration`):t?.enabled===!0?O(`ui.settingsPluginsPanel.enabledByConfiguration`,`Enabled by configuration`):O(`ui.settingsPluginsPanel.enabledByDefault`,`Enabled by default`);return D`
640
+ <article class=${`plugin-card ui-settings-row${e.enabled?``:` disabled`}`}>
641
+ <div class="plugin-main">
642
+ <strong>${e.id}</strong>
643
+ <small>${e.configOnly?O(`ui.main.40098da54072`,`configured only · package not discovered`):`${vt(e.source)} · ${yt(e.scope)}${e.machineSpecific?O(`ui.settingsPluginsPanel.machineSpecific`,` · Machine-specific`):``}${e.required===!0?O(`ui.main.5ce75af5c91a`,` · required`):``}${e.discovered?``:O(`ui.main.b00e20aa7b93`,` · active snapshot only`)}`}</small>
644
+ <small>${n}</small>
645
+ ${this.renderPluginStatuses(e)}
646
+ ${e.server?.message===void 0?A:D`<small class="diagnostic">${e.server.message}</small>`}
647
+ ${e.server?.health?.message===void 0?A:D`<small class="diagnostic">${O(`ui.main.cfa349711e67`,`Health:`)}${e.server.health.message}</small>`}
648
+ ${e.server===void 0||e.required===!0?A:D`<small class="command">${O(`ui.main.c54bd03f1522`,`Offline disable:`)} <code>${e.server.disableCommand}</code></small>`}
649
+ </div>
650
+ <label class="toggle ui-checkbox-field">
651
+ <input type="checkbox" aria-label=${e.required===!0?O(`ui.settingsPluginsPanel.requiredLabel`,`{id} is required`,{id:e.id}):O(`ui.settingsPluginsPanel.enableLabel`,`Enable {id}`,{id:e.id})} .checked=${S(e.enabled)} ?disabled=${this.loading||this.saving||this.configResponse===void 0||!e.editable} @change=${t=>{this.togglePlugin(e,t)}}>
652
+ <span>${e.required===!0?O(`ui.main.12ea99f8d0b5`,`Required`):O(`ui.settingsSessiondPanel.enabled`,`Enabled`)}</span>
653
+ </label>
654
+ </article>
655
+ `}renderPluginStatuses(e){let t=e.server;return D`
656
+ <div class="status-list" aria-label=${O(`ui.main.062b4cb6a584`,`{arg0} plugin status`,{arg0:e.id})}>
657
+ ${t===void 0?D`<span class="status neutral">${e.configOnly?O(`ui.main.886efbba295e`,`Configured only`):O(`ui.main.a36380d21dcd`,`Browser only`)}</span>`:D`<span class=${`status ${ht(t.state)}`}>${mt(t.state)}</span>`}
658
+ ${e.conflict?D`<span class="status error">${O(`ui.main.dc60132944dd`,`Conflict`)}</span>`:A}
659
+ ${t?.staleRevision===!0?D`<span class="status warning">${O(`ui.main.4e68d6d5c959`,`Stale revision`)}</span>`:A}
660
+ ${t?.restartRequired===!0?D`<span class="status warning">${O(`bundled.info.restart.needed.1ffd00`,`Restart needed`)}</span>`:A}
661
+ ${t?.health===void 0?A:D`<span class=${`status ${gt(t.health.status)}`}>${O(`ui.main.2e604c06f096`,`Health`)} ${bt(t.health.status)}</span>`}
662
+ </div>
663
+ `}renderRecoveryCommands(){let e=this.pluginsResponse?.serverRuntime,t=(e?.status===`incompatible`&&!this.recoveryCommandsSupported?void 0:e?.recovery)??(this.recoveryCommandsSupported?r:void 0);return t===void 0?A:D`
664
+ <aside class="recovery ui-settings-summary" aria-label="${O(`ui.main.a444df361594`,`Offline server-plugin recovery commands`)}">
665
+ <strong>${this.targetLabel} ${O(`ui.main.ca56f3ca43d1`,` offline recovery`)}</strong>
666
+ <small>${O(`ui.main.277115ec7cae`,`These commands edit config without contacting sessiond or importing plugins. They never include machine credentials.`)}</small>
667
+ <span>${O(`ui.settingsPluginsPanel.checkSafeMode`,`Check safe mode`)}</span><code>${t.showSafeStart}</code>
668
+ <span>${O(`ui.settingsPluginsPanel.bundledOnly`,`Start with bundled server plugins only`)}</span><code>${t.bundledOnly}</code>
669
+ <span>${O(`ui.settingsPluginsPanel.noServerPlugins`,`Start without server plugins (including Terminal)`)}</span><code>${t.noServerPlugins}</code>
670
+ <span>${O(`ui.settingsPluginsPanel.clearSafeMode`,`Clear safe mode and start normally`)}</span><code>${t.clearSafeStart}</code>
671
+ </aside>
672
+ `}async togglePlugin(e,t){if(!e.editable||e.required===!0||e.id===`pi-web.terminal`)return;let n=t.target instanceof HTMLInputElement?t.target.checked:e.enabled;await this.onTogglePlugin?.(e.id,n)}static{this.styles=[g,j,E`
673
+ @layer pi-web-base {
674
+ :host { display: block; }
675
+ .loading-card, .plugin-note { color: var(--pi-muted); }
676
+ code { color: var(--pi-text); font: 12px var(--pi-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); overflow-wrap: anywhere; }
677
+ .plugin-card { align-items: center; }
678
+ .plugin-card.disabled { opacity: .8; }
679
+ .plugin-main { flex: 1 1 280px; min-width: 0; display: grid; gap: 5px; }
680
+ .plugin-main > strong, .plugin-main > small:not(.command) { overflow-wrap: anywhere; }
681
+ .plugin-main small { color: var(--pi-muted); }
682
+ .diagnostic { color: var(--pi-text) !important; }
683
+ .command { line-height: 1.5; }
684
+ .status-list { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 2px; }
685
+ .status { border: 1px solid var(--pi-border-muted); border-radius: 999px; padding: 2px 7px; color: var(--pi-muted); font-size: 11px; line-height: 1.3; }
686
+ .status.success { border-color: var(--pi-success-border); color: var(--pi-success); background: var(--pi-success-surface); }
687
+ .status.warning { border-color: var(--pi-warning-border); color: var(--pi-text); background: var(--pi-warning-surface); }
688
+ .status.error { border-color: var(--pi-danger); color: var(--pi-danger); }
689
+ .toggle { white-space: nowrap; }
690
+ .recovery small { color: var(--pi-muted); line-height: 1.4; }
691
+ .recovery code { display: block; width: fit-content; max-width: 100%; }
692
+
693
+ @media (max-width: 760px) {
694
+ .plugin-main { flex-basis: 100%; }
695
+ }
696
+
697
+ }
698
+ `]}};w([m({attribute:!1})],G.prototype,`pluginsResponse`,void 0),w([m({attribute:!1})],G.prototype,`configResponse`,void 0),w([m({type:Boolean})],G.prototype,`loading`,void 0),w([m({type:Boolean})],G.prototype,`saving`,void 0),w([m({type:Boolean})],G.prototype,`recoveryCommandsSupported`,void 0),w([m()],G.prototype,`error`,void 0),w([m()],G.prototype,`savedMessage`,void 0),w([m()],G.prototype,`targetLabel`,void 0),w([m({attribute:!1})],G.prototype,`onReload`,void 0),w([m({attribute:!1})],G.prototype,`onTogglePlugin`,void 0),G=w([y(`settings-plugins-panel`)],G);function pt(e,t){let n=t?.config.plugins??{},r=(e?.plugins??[]).map(e=>{let t=n[e.id],r=e.required===!0?!0:t?.enabled??e.enabled;return{...e,enabled:r,configOnly:!1,editable:e.required!==!0&&(e.discovered||t!==void 0)}}),i=new Set(r.map(({id:e})=>e));for(let[e,t]of Object.entries(n)){if(i.has(e))continue;let n=e===ue;r.push({id:e,...n?{required:!0}:{},source:`config`,scope:`local`,machineSpecific:!1,enabled:n||t.enabled!==!1,discovered:!1,conflict:!1,configOnly:!0,editable:!n})}return r.sort((e,t)=>e.id.localeCompare(t.id))}function mt(e){switch(e){case`active`:return O(`ui.main.b1eea7b855e6`,`Active`);case`failed`:return O(`ui.toolExecutionView.failed`,`Failed`);case`incompatible`:return O(`ui.main.8d1f2155372e`,`Incompatible`);case`disabled`:return O(`ui.settingsShortcutsPanel.disabled`,`Disabled`);case`missing`:return O(`ui.main.f1ebc7eeb432`,`Not active`);case`unknown`:return O(`ui.main.36946f6e6dec`,`Active state unavailable`)}}function ht(e){switch(e){case`active`:return`success`;case`disabled`:case`missing`:return`warning`;case`failed`:case`incompatible`:return`error`;case`unknown`:return`neutral`}}function gt(e){switch(e){case`healthy`:return`success`;case`degraded`:return`warning`;case`unhealthy`:return`error`}}function _t(e){return D`${O(`ui.main.4bc9cf7ff997`,`Compare desired plugin config with the active sessiond startup snapshot on`)} <strong>${e}</strong>${O(`ui.main.9c96947ff33e`,`. This is separate from installing Pi packages.`)}`}function vt(e){return e===`bundled`?O(`ui.settingsPluginsPanel.bundled`,`Bundled`):e===`local`?O(`ui.settingsPluginsPanel.local`,`Local`):e===`dev`?O(`ui.settingsPluginsPanel.development`,`Development`):e}function yt(e){switch(e){case`bundled`:return O(`ui.settingsPluginsPanel.bundledScope`,`Bundled scope`);case`local`:return O(`ui.settingsPluginsPanel.localScope`,`Local scope`);case`user`:return O(`ui.settingsPluginsPanel.userScope`,`User scope`);case`project`:return O(`ui.settingsPluginsPanel.projectScope`,`Project scope`)}}function bt(e){switch(e){case`healthy`:return O(`ui.main.f78d037abccd`,`Healthy`);case`degraded`:return O(`ui.main.d8518883839d`,`Degraded`);case`unhealthy`:return O(`ui.main.5caf27933926`,`Unhealthy`)}}var xt={capture:!0},St=[{value:`auto`,label:O(`ui.settingsShortcutsPanel.autoDefault`,`Auto/default`),description:O(`ui.settingsShortcutsPanel.enterSendsOnDesktopEnterInsertsANewline`,`Enter sends on wide screens; Enter inserts a newline when the viewport is at most 760px wide.`)},{value:`send`,label:O(`ui.settingsShortcutsPanel.enterSendsMessages`,`Enter sends messages`),description:O(`ui.settingsShortcutsPanel.enterSendsChatMessagesShiftEnterInsertsA`,`Enter sends chat messages; Shift+Enter inserts a newline when supported.`)},{value:`newline`,label:O(`ui.settingsShortcutsPanel.enterInsertsNewline`,`Enter inserts newline`),description:O(`ui.settingsShortcutsPanel.enterInsertsANewlineShiftEnterSendsChat`,`Enter inserts a newline; Shift+Enter sends chat messages when supported.`)}];function Ct(){return D`${O(`ui.main.29da83a15958`,`Edit app shortcuts by action. Type a shortcut such as`)} <code>mod+k</code> ${O(`ui.settingsShortcutsPanel.or`,` or `)} <code>mod+g p</code>${O(`ui.main.1c1a5ce1b6d2`,`, record one from the keyboard, disable it with None, or reset it to the default. Unmodified app shortcuts work outside editable fields. Composer send bindings accept one key combination and take priority inside the editor; unassigned Enter and Shift+Enter insert newlines. Narrow screen applies when the viewport is at most 760px wide; otherwise, desktop applies regardless of pointer type. When app shortcuts conflict, custom shortcuts win before defaults; ties are resolved by action id, and shorter shortcuts shadow longer sequences with the same prefix.`)}`}var K=class extends k{constructor(){super(),this.actions=[],this.loading=!1,this.saving=!1,this.error=``,this.savedMessage=``,this.drafts={},this.localError=``,this.promptEnterPreference=ie(),this.pendingSaves=new Map,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=ce(e);if(n===void 0){this.localError=O(`ui.settingsShortcutsPanel.pressALetterNumberPunctuationFunctionOrNavigation`,`Press a letter, number, punctuation, function, or navigation key. Press Esc to cancel recording.`);return}if(t.tokens.length>0&&x(t.actionId)){this.localError=O(`ui.main.e5fcfdb23aec`,`The send shortcut must be a single key combination, not a sequence.`);return}let r=[...t.tokens,n];this.localError=``,this.drafts={...this.drafts,[t.actionId]:r.join(` `)},this.recording={actionId:t.actionId,tokens:r},x(t.actionId)?this.stopRecording():this.armRecordingTimer()},i.createController(this)}willUpdate(t){if((this.configResponse===void 0||this.loading||this.saving)&&this.stopRecording(),t.has(`configResponse`)&&this.configResponse!==void 0)for(let[t,n]of this.pendingSaves)e(n.action,this.configResponse.config.shortcuts)===n.preference&&(this.drafts[t]===n.draft&&(this.drafts=Object.fromEntries(Object.entries(this.drafts).filter(([e])=>e!==t))),this.pendingSaves.delete(t))}disconnectedCallback(){this.stopRecording(),super.disconnectedCallback()}render(){let e=Dt([...te(),...this.actions]),t=this.shortcutResolutions();return D`
699
+ <settings-panel-frame
700
+ heading="${O(`ui.settingsShortcutsPanel.keyboardShortcuts`,`Keyboard shortcuts`)}"
701
+ .description=${Ct()}
702
+ actionLabel="${O(`ui.settingsPackagesPanel.reload`,`Reload`)}"
703
+ .actionDisabled=${this.loading}
704
+ .notices=${this.panelNotices()}
705
+ .onAction=${this.onReload}
706
+ >
707
+ ${this.renderPromptEnterPreferenceCard()}
708
+ ${this.configResponse===void 0&&!this.loading?D`<p role="status">${O(`ui.settingsShortcutsPanel.unavailable`,`Shortcut settings are unavailable. Reload settings to try again.`)}</p>`:A}
709
+ ${this.configResponse===void 0&&this.loading?D`<div class="loading-card ui-settings-path">${O(`ui.settingsShortcutsPanel.loadingShortcuts`,`Loading shortcuts…`)}</div>`:D`
710
+ <div class="config-path-card ui-settings-path">
711
+ <span>${O(`ui.settingsShortcutsPanel.configurationFile`,`Configuration file`)}</span>
712
+ <code>${this.configResponse?.path??O(`bundled.updates.unknown.4d8c1c`,`Unknown`)}</code>
713
+ <small>${O(`ui.settingsShortcutsPanel.shortcutOverridesAreSavedUnder`,`Shortcut overrides are saved under `)} <code>shortcuts</code> ${O(`ui.settingsShortcutsPanel.aValueOf`,`. A value of `)} <code>null</code> ${O(`ui.settingsShortcutsPanel.disablesTheActionShortcut`,` disables the action shortcut.`)}</small>
714
+ </div>
715
+ <section class="shortcut-group ui-settings-section">
716
+ <div class="ui-settings-heading"><h3>${O(`ui.settingsShortcutsPanel.sendBehavior`,`Send behavior`)}</h3></div>
717
+ <label class="shortcut-input-label ui-form-field">
718
+ <span>${O(`ui.settingsShortcutsPanel.sendWhileRunning`,`Send while agent is running`)}</span>
719
+ <select class="ui-select" aria-label=${O(`ui.settingsShortcutsPanel.sendWhileRunning`,`Send while agent is running`)} .value=${S(this.configResponse?.config.defaultStreamingBehavior??`steer`)} ?disabled=${this.loading||this.saving||this.configResponse===void 0} @change=${e=>{this.saveSendBehavior(e)}}>
720
+ <option value="steer">${O(`ui.settingsShortcutsPanel.steerDefault`,`Steer (default)`)}</option>
721
+ <option value="followUp">${O(`ui.settingsShortcutsPanel.followUp`,`Follow-up`)}</option>
722
+ </select>
723
+ </label>
724
+ </section>
725
+ ${e.length===0?D`<div class="loading-card ui-settings-path">${O(`ui.settingsShortcutsPanel.noRegisteredActions`,`No registered actions.`)}</div>`:e.map(e=>D`
726
+ <section class="shortcut-group ui-settings-section">
727
+ <div class="ui-settings-heading"><h3>${e.name}</h3></div>
728
+ <div class="shortcut-list ui-settings-list">
729
+ ${e.actions.map(e=>this.renderShortcutRow(e,t.get(e.id)))}
730
+ </div>
731
+ </section>
732
+ `)}
733
+ `}
734
+ </settings-panel-frame>
735
+ `}async saveSendBehavior(e){let t=e.target instanceof HTMLSelectElement?e.target.value:void 0;this.loading||this.saving||this.configResponse===void 0||t!==`steer`&&t!==`followUp`||await this.onSave?.({...this.configResponse.config,defaultStreamingBehavior:t})}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 D`
736
+ <section class="prompt-enter-card ui-settings-section" aria-labelledby="prompt-enter-preference-title">
737
+ <div class="prompt-enter-copy ui-settings-heading">
738
+ <span class="card-eyebrow">${O(`ui.settingsShortcutsPanel.chatInput`,`Chat input`)}</span>
739
+ <h3 id="prompt-enter-preference-title">${O(`ui.settingsShortcutsPanel.enterKeyBehavior`,`Enter key behavior`)}</h3>
740
+ <p>${O(`ui.settingsShortcutsPanel.chooseEnterBehaviorInThisBrowserShiftEnter`,`Choose Enter behavior in this browser. Shift+Enter performs the opposite action when supported; touch-keyboard auto-capitalization is ignored to prevent accidental sends.`)}</p>
741
+ </div>
742
+ <div class="prompt-enter-options ui-settings-fields" role="radiogroup" aria-label="${O(`ui.settingsShortcutsPanel.enterAndShiftEnterBehaviorInChatInput`,`Enter and Shift Enter behavior in chat input`)}">
743
+ ${St.map(e=>D`
744
+ <label class="prompt-enter-option ui-checkbox-field">
745
+ <input
746
+ type="radio"
747
+ name="prompt-enter-preference"
748
+ .value=${e.value}
749
+ .checked=${this.promptEnterPreference===e.value}
750
+ @change=${()=>{this.updatePromptEnterPreference(e.value)}}
751
+ >
752
+ <span class="ui-form-field">
753
+ <strong>${e.label}</strong>
754
+ <small>${e.description}</small>
755
+ </span>
756
+ </label>
757
+ `)}
758
+ </div>
759
+ </section>
760
+ `}updatePromptEnterPreference(e){this.promptEnterPreference=e,ee(e)}renderShortcutRow(t,n){let r=this.configResponse?.config.shortcuts,i=e(t,r),a=jt(t,r),o=this.shortcutInputText(t),s=o.trim()===``?void 0:f(o),c=s?.ok===!0?s.shortcut:At(t,r),l=i!==void 0,u=this.drafts[t.id]!==void 0,p=u&&o.trim()!==``?`custom`:a,m=this.recordingHint(t.id),h=Et(n),g=this.loading||this.saving||this.configResponse===void 0;return D`
761
+ <article class=${`ui-settings-row ${wt(n)}`}>
762
+ <div class="shortcut-main">
763
+ <strong>${t.title}</strong>
764
+ ${t.description!==void 0&&t.description!==``?D`<small>${t.description}</small>`:null}
765
+ <small class="shortcut-id">${t.id}</small>
766
+ <small>${t.shortcut!==void 0&&t.shortcut!==``?D`${O(`ui.settingsShortcutsPanel.default2`,`Default:`)}<kbd>${d(t.shortcut)}</kbd>`:O(`ui.settingsShortcutsPanel.noDefaultShortcut`,`No default shortcut`)}</small>
767
+ </div>
768
+ <div class="shortcut-editor">
769
+ <div class="shortcut-status">
770
+ ${c!==void 0&&c!==``?D`<kbd>${d(c)}</kbd>`:D`<span class="unassigned">${a===`disabled`?O(`ui.settingsShortcutsPanel.disabled`,`Disabled`):O(`ui.settingsShortcutsPanel.unassigned`,`Unassigned`)}</span>`}
771
+ <small class=${p}>${Mt(p)}${u?O(`ui.settingsShortcutsPanel.unsaved`,` · Unsaved`):``}</small>
772
+ ${h===void 0?null:D`<small class=${Tt(n)}>${h}</small>`}
773
+ </div>
774
+ <label class="shortcut-input-label ui-form-field">
775
+ <span>${O(`ui.settingsShortcutsPanel.shortcut`,`Shortcut`)}</span>
776
+ <input
777
+ class="shortcut-input ui-input"
778
+ data-action-id=${t.id}
779
+ aria-label=${O(`ui.settingsShortcutsPanel.shortcutFor`,`Shortcut for {title}`,{title:t.title})}
780
+ aria-describedby=${m===``?A:`recording-${t.id}`}
781
+ .value=${o}
782
+ placeholder=${t.shortcut??`mod+k`}
783
+ autocomplete="off"
784
+ autocapitalize="off"
785
+ spellcheck="false"
786
+ ?disabled=${g}
787
+ @input=${e=>{this.updateDraft(t.id,Nt(e))}}
788
+ >
789
+ </label>
790
+ ${m===``?null:D`<small class="recording-hint" id=${`recording-${t.id}`} role="status">${m}</small>`}
791
+ <div class="shortcut-actions ui-settings-actions">
792
+ <button class="primary ui-button ui-button--action ui-button--primary" aria-label=${O(`ui.settingsShortcutsPanel.saveFor`,`Save shortcut for {title}`,{title:t.title})} ?disabled=${g||!u||o.trim()===``} @click=${()=>{this.saveShortcut(t)}}>${O(`ui.settingsShortcutsPanel.save`,`Save`)}</button>
793
+ <button class="ui-button ui-button--action" aria-label=${this.recording?.actionId===t.id?O(`ui.settingsShortcutsPanel.cancelRecordingFor`,`Cancel recording for {title}`,{title:t.title}):O(`ui.settingsShortcutsPanel.recordFor`,`Record shortcut for {title}`,{title:t.title})} ?disabled=${g} @click=${()=>{this.toggleRecording(t.id)}}>${this.recording?.actionId===t.id?O(`ui.settingsShortcutsPanel.cancelRecording`,`Cancel recording`):O(`ui.settingsShortcutsPanel.record`,`Record`)}</button>
794
+ <button class="ui-button ui-button--action" aria-label=${O(`ui.settingsShortcutsPanel.disableFor`,`Disable shortcut for {title}`,{title:t.title})} ?disabled=${g||i===null} @click=${()=>{this.setShortcutNone(t)}}>${O(`ui.settingsShortcutsPanel.none`,`None`)}</button>
795
+ <button class="ui-button ui-button--action" aria-label=${O(`ui.settingsShortcutsPanel.restoreFor`,`Restore default shortcut for {title}`,{title:t.title})} ?disabled=${g||!l} @click=${()=>{this.resetShortcut(t)}}>${O(`ui.settingsShortcutsPanel.reset`,`Reset`)}</button>
796
+ </div>
797
+ </div>
798
+ </article>
799
+ `}shortcutInputText(t){let n=this.drafts[t.id];if(n!==void 0)return n;let r=e(t,this.configResponse?.config.shortcuts);return r===null?``:r??t.shortcut??``}recordingHint(e){let t=this.recording;return t?.actionId===e?t.tokens.length===0?O(`ui.settingsShortcutsPanel.recordingPressCtrlOrAltPlusAKey`,`Recording: press Ctrl/⌘ or Alt plus a key. Press Esc to cancel.`):O(`ui.settingsShortcutsPanel.recordingPressMoreKeysToAddASequence`,`Recording: {join}. Press more keys to add a sequence, or wait to finish.`,{join:d(t.tokens.join(` `))}):``}updateDraft(e,t){this.drafts={...this.drafts,[e]:t},this.localError=``}async saveShortcut(e){this.stopRecording();let t=this.shortcutInputText(e).trim(),n=f(t);n.ok?x(e.id)&&n.tokens.length!==1?this.localError=O(`ui.main.3c6a5ae4d855`,`Composer send shortcuts must be a single key combination, not a sequence.`):(this.localError=``,await this.saveShortcutPreference(e,n.shortcut)):this.localError=n.message}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){if(this.configResponse===void 0||this.onSave===void 0)return;let n={...this.configResponse.config},r=kt(n.shortcuts??{},[e.id,...e.shortcutAliases??[]]);t!==void 0&&(r[e.id]=t),Object.keys(r).length===0?delete n.shortcuts:n.shortcuts=r;let i={action:e,preference:t,draft:this.drafts[e.id]};this.pendingSaves.set(e.id,i);try{await this.onSave(n),this.requestUpdate()}catch(t){this.pendingSaves.get(e.id)===i&&this.pendingSaves.delete(e.id),this.localError=O(`ui.settingsShortcutsPanel.saveFailed`,`Could not save shortcut. {error}`,{error:t instanceof Error?t.message:String(t)})}}shortcutResolutions(){let e=this.previewShortcutConfig(),t=[...o(this.actions.filter(e=>!x(e.id)),e,{enabledOnly:!0}),...te().flatMap(t=>o([t],e))];return new Map(t.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=f(r);i.ok&&(e[t]=i.shortcut)}return Object.keys(e).length===0?void 0:e}async toggleRecording(e){this.recording?.actionId===e?this.stopRecording():(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()},h)}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,xt),!0)}removeRecordingListener(){this.recordingListenerActive&&=(window.removeEventListener(`keydown`,this.onRecordKeyDown,xt),!1)}static{this.styles=[a,g,j,E`
800
+ @layer pi-web-base {
801
+ :host { display: block; }
802
+ h3, p { margin: 0; }
803
+ p { color: var(--pi-muted); line-height: 1.45; }
804
+ .config-path-card span { color: var(--pi-muted); font-size: 12px; font-weight: 600; }
805
+ code { border: 1px solid var(--pi-border-muted); border-radius: 5px; background: var(--pi-bg); padding: 1px 4px; color: var(--pi-text); font: 12px var(--pi-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); overflow-wrap: anywhere; }
806
+ .shortcut-group { margin: 0; }
807
+ .shortcut-group:has(.shortcut-list) { padding: 0; gap: 0; }
808
+ .shortcut-group:has(.shortcut-list) > .ui-settings-heading { padding: 16px; background: var(--pi-surface); }
809
+ .shortcut-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(360px, 48%); align-items: start; }
810
+ .shortcut-row.shadowed { background: color-mix(in srgb, var(--pi-warning) 5%, var(--pi-surface)); }
811
+ .shortcut-row.shadowing { background: color-mix(in srgb, var(--pi-accent) 5%, var(--pi-surface)); }
812
+ .shortcut-row:last-child { border-bottom: 0; }
813
+ .shortcut-main { min-width: 0; display: grid; gap: 4px; }
814
+ .shortcut-main strong, .shortcut-main small { overflow-wrap: anywhere; }
815
+ .shortcut-main small { color: var(--pi-muted); }
816
+ .shortcut-id { font-family: var(--pi-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); }
817
+ .shortcut-editor { min-width: 0; display: grid; gap: 8px; }
818
+ .shortcut-status { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
819
+ .shortcut-status small { color: var(--pi-muted); font-size: 11px; }
820
+ .shortcut-status small.custom { color: var(--pi-accent); }
821
+ .shortcut-status small.disabled { color: var(--pi-warning); }
822
+ .shortcut-status small.conflict.shadowing { color: var(--pi-accent); }
823
+ .shortcut-status small.conflict.shadowed { color: var(--pi-warning); }
824
+ .shortcut-input { --ui-input-font-family: var(--pi-control-monospace-font-family, var(--pi-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)); }
825
+ kbd { border: 1px solid var(--pi-border); border-radius: 6px; background: var(--pi-bg); color: var(--pi-text-secondary); padding: 3px 7px; font: 12px var(--pi-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); white-space: nowrap; }
826
+ .unassigned { color: var(--pi-muted); font-size: 12px; }
827
+ .recording-hint { color: var(--pi-accent); font-size: 12px; }
828
+
829
+ @media (max-width: 760px) {
830
+ .shortcut-row { grid-template-columns: minmax(0, 1fr); align-items: start; }
831
+ .shortcut-status, .shortcut-actions { justify-content: flex-start; }
832
+ }
833
+
834
+ }
835
+ `]}};w([m({attribute:!1})],K.prototype,`actions`,void 0),w([m({attribute:!1})],K.prototype,`configResponse`,void 0),w([m({type:Boolean})],K.prototype,`loading`,void 0),w([m({type:Boolean})],K.prototype,`saving`,void 0),w([m()],K.prototype,`error`,void 0),w([m()],K.prototype,`savedMessage`,void 0),w([m({attribute:!1})],K.prototype,`onReload`,void 0),w([m({attribute:!1})],K.prototype,`onSave`,void 0),w([b()],K.prototype,`drafts`,void 0),w([b()],K.prototype,`localError`,void 0),w([b()],K.prototype,`promptEnterPreference`,void 0),w([b()],K.prototype,`recording`,void 0),K=w([y(`settings-shortcuts-panel`)],K);function wt(e){return e?.active===!1?`shortcut-row shadowed`:e?.active===!0&&e.shadows.length>0?`shortcut-row shadowing`:`shortcut-row`}function Tt(e){return e?.active===!1?`conflict shadowed`:`conflict shadowing`}function Et(e){if(e===void 0)return;if(!e.active)return O(`ui.settingsShortcutsPanel.shadowedBy`,`Shadowed by "{title}"`,{title:e.shadowedBy?.action.title??O(`ui.settingsShortcutsPanel.anotherAction`,`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?O(`ui.settingsShortcutsPanel.plusMore`,`, plus {shadowedCount2} more`,{shadowedCount2:String(t-2)}):``;return O(`ui.settingsShortcutsPanel.shadowsActions`,`Shadows {shadowedCount} actions: {shadowedNames}{suffix}`,{shadowedCount:String(t),shadowedNames:n,suffix:r})}function Dt(e){let t=new Map;for(let n of[...e].sort(Ot)){let e=n.group??O(`ui.settingsShortcutsPanel.other`,`Other`);t.set(e,[...t.get(e)??[],n])}return[...t.entries()].map(([e,t])=>({name:e,actions:t}))}function Ot(e,t){return(e.group??O(`ui.settingsShortcutsPanel.other`,`Other`)).localeCompare(t.group??O(`ui.settingsShortcutsPanel.other`,`Other`))||e.title.localeCompare(t.title)}function kt(e,t){let n=new Set(t);return Object.fromEntries(Object.entries(e).filter(([e])=>!n.has(e)))}function At(t,n){let r=e(t,n);if(r!==null)return r??t.shortcut}function jt(t,n){let r=e(t,n);return r===null?`disabled`:r===void 0?t.shortcut===void 0||t.shortcut===``?`unassigned`:`default`:`custom`}function Mt(e){switch(e){case`default`:return O(`ui.settingsShortcutsPanel.default`,`Default`);case`custom`:return O(`ui.settingsShortcutsPanel.configurationOverride`,`Configuration override`);case`disabled`:return O(`ui.settingsShortcutsPanel.disabledInConfiguration`,`Disabled in configuration`);case`unassigned`:return O(`ui.settingsShortcutsPanel.noDefault`,`No default`)}}function Nt(e){return e.target instanceof HTMLInputElement?e.target.value:``}async function Pt(e){let[t,n]=await Promise.allSettled([e.loadConfig(),e.loadPlugins()]),r={error:``},i=[];return t.status===`fulfilled`?r.config=t.value:i.push(O(`ui.settingsDataLoading.configuration`,`Configuration: {reason}`,{reason:It(t.reason)})),n.status===`fulfilled`?r.plugins=n.value:i.push(O(`ui.settingsDataLoading.piWebPlugins`,`PI WEB plugins: {reason}`,{reason:It(n.reason)})),i.length>0&&(r.error=O(`ui.settingsDataLoading.failedToLoadSettings`,`Failed to load settings: {join}`,{join:i.join(`;`)})),r}async function Ft(e,t,n){if(H(n))return{error:n.message??O(`ui.settingsDataLoading.doesNotSupportPiPackageManagement`,`{piPackageTargetLabeltarget} does not support Pi package management.`,{piPackageTargetLabeltarget:V(e)}),skipped:!0};try{return{packagesResponse:await t(e.id),error:``}}catch(t){return{error:O(`ui.settingsDataLoading.failedToLoadPiPackagesFrom`,`Failed to load Pi packages from {piPackageTargetLabeltarget}: {value2}`,{piPackageTargetLabeltarget:V(e),value2:ut(It(t),e)})}}}function It(e){return e instanceof Error?e.message:String(e)}function Lt(e,t){return{...e,config:Rt(e.config,t.config),effectiveConfig:Rt(e.effectiveConfig,t.effectiveConfig)}}function Rt(e,t){return{...e,...t.pathAccess===void 0?{}:{pathAccess:t.pathAccess},...t.uploads===void 0?{}:{uploads:t.uploads},...t.attachments===void 0?{}:{attachments:t.attachments},...t.maxUploadBytes===void 0?{}:{maxUploadBytes:t.maxUploadBytes}}}function q(e,t){return e.kind===`local`?{state:`supported`}:t?.ok===!0?ae(t,le.pluginLifecycle)?{state:`supported`}:{state:`unsupported`,message:Wt(e)}:{state:`unknown`}}function zt(e){return e===void 0?{id:`local`,name:O(`ui.settingsMachineTarget.local`,`Local`),kind:`local`}:{id:e.id,name:e.name,kind:e.kind}}function J(e){return e.kind===`local`?O(`ui.settingsMachineTarget.localGateway`,`{name} (local gateway)`,{name:e.name}):O(`ui.settingsMachineTarget.remoteMachine`,`{name} (remote machine)`,{name:e.name})}function Bt(e,t){return e.kind===`local`||t?.ok===!0?{state:`supported`}:{state:`unknown`}}function Vt(e,t){return e.kind===`local`||t?.ok===!0?{state:`supported`}:{state:`unknown`,message:O(`ui.settingsMachineTarget.unableToConfirmWhetherSupportsPiCompatibleAgent`,`Unable to confirm whether {name} supports Pi-compatible agent profiles. Reload machine status before changing the profile.`,{name:e.name})}}function Y(e){return`${e.state}:${e.message??``}`}function X(e){return e?.state===`unsupported`}function Ht(e){return e?.state===`supported`}function Ut(e){return O(`ui.settingsMachineTarget.doesNotSupportSelectedMachineSettingsUpdateAnd`,`{name} does not support selected-machine settings. Update and restart PI WEB on that machine, then retry.`,{name:e.name})}function Wt(e){return O(`ui.main.a5ae99c3f3cd`,`{arg0} does not support plugin lifecycle diagnostics. Update and restart PI WEB on that machine before loading server-dependent plugins.`,{arg0:e.name})}function Z(e,t){let n=e.trim();return t.kind===`remote`?Gt(n)?Ut(t):n===`Remote machine timeout`?O(`ui.settingsMachineTarget.timedOutContactingForSelectedMachineSettingsThe`,`Timed out contacting {name} for selected-machine settings. The operation may still be running remotely; reload before retrying.`,{name:t.name}):n===`Remote machine unavailable`?O(`ui.settingsMachineTarget.unableToConnectToForSelectedMachineSettings`,`Unable to connect to {name} for selected-machine settings. Check the machine connection and retry.`,{name:t.name}):n:n}function Gt(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 Kt(e,t,n){let r=e.plugins??{},i=r[t]??{};return{plugins:{...r,[t]:{...i,enabled:n}}}}function qt(e,t){return{...e,config:Jt(e.config,t.config),effectiveConfig:Jt(e.effectiveConfig,t.effectiveConfig)}}function Jt(e,t){return t.plugins===void 0?e:{...e,plugins:t.plugins}}var Q=class extends k{constructor(){super(),this.section=`general`,this.presentationContext={mode:`normal`},this.actions=[],this.themes=[],this.themePreference=l,this.activeThemeId=``,this.hasLocalThemeOverride=!1,this.machines=[],this.machineStatuses={},this.machineRuntimes={},this.loading=!0,this.accessLoading=!0,this.sessiondLoading=!0,this.namingModels=[],this.namingModelsLoading=!1,this.namingModelsError=``,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.namingModelsLoadRequestSeq=0,this.pluginLoadRequestSeq=0,this.packageLoadRequestSeq=0,this.packageMutationSeq=0,i.createController(this)}connectedCallback(){super.connectedCallback(),this.loadConfig(),this.loadAccessConfigForTarget(),this.reloadSessiondState(),this.loadPluginsForTarget(),this.loadPackagesForTarget()}disconnectedCallback(){this.namingModelsLoadRequestSeq+=1,this.savedMessageTimer!==void 0&&window.clearTimeout(this.savedMessageTimer),this.savedMessageTimer=void 0,super.disconnectedCallback()}updated(e){if(e.has(`namingModelsTarget`)&&(!e.has(`machine`)||zt(e.get(`machine`)).id===this.settingsTarget().id)&&this.loadNamingModelsForTarget(),e.has(`section`)&&this.renderRoot.querySelector(`modal-surface`)?.updateComplete.then(()=>{this.isConnected&&this.renderRoot.querySelector(`.settings-nav button.selected`)?.scrollIntoView({block:`nearest`,inline:`nearest`})}),this.isConnected){let e=this.renderRoot.querySelector(`settings-general-panel`);e!==null&&(this.generalPanel=e)}let t=this.settingsTarget();if((e.has(`machine`)||e.has(`machines`))&&zt(this.selectedSettingsMachine(e.has(`machines`)?e.get(`machines`)??[]:this.machines,e.has(`machine`)?e.get(`machine`):this.machine,this.settingsMachineId)).id!==t.id){this.resetAccessStateForTargetChange(),this.isConnected&&this.loadAccessConfigForTarget(t),this.resetSessiondStateForTargetChange(),this.isConnected&&this.reloadSessiondState(t),this.resetPluginStateForTargetChange(),this.isConnected&&this.loadPluginsForTarget(t),this.resetPackageStateForTargetChange(),this.isConnected&&this.loadPackagesForTarget(t);return}if(!e.has(`machineRuntime`)&&!e.has(`machineRuntimes`))return;let n=this.settingsRuntime(e.has(`machineRuntimes`)?e.get(`machineRuntimes`)??{}:this.machineRuntimes,e.has(`machineRuntime`)?e.get(`machineRuntime`):this.machineRuntime,t),r=Y(q(t,n))!==Y(q(t,this.settingsRuntime(this.machineRuntimes,this.machineRuntime,t)));this.selectedMachineSettingsSupportNeedsReload(n,t)&&(this.resetAccessStateForTargetChange(),this.isConnected&&this.loadAccessConfigForTarget(t),this.resetSessiondStateForTargetChange(),this.isConnected&&this.loadSessiondConfigForTarget(t)),r&&(this.resetPluginStateForTargetChange(),this.isConnected&&this.loadPluginsForTarget(t)),this.packageManagementSupportNeedsReload(n,t)&&(this.resetPackageStateForTargetChange(),this.isConnected&&this.loadPackagesForTarget(t))}render(){return D`
836
+ <modal-surface .onClose=${()=>this.onClose?.()} .busy=${this.saving} .label=${O(`ui.settingsDialog.piWebSettings`,`PI WEB settings`)}>
837
+ <header class="settings-header ui-dialog-header">
838
+ <h1 class="ui-dialog-title">${O(`ui.settingsDialog.settings`,`Settings`)}</h1>
839
+ <button type="button" class="close-button ui-button ui-button--icon" title="${O(`ui.settingsDialog.closeSettings`,`Close settings`)}" aria-label="${O(`ui.settingsDialog.closeSettings`,`Close settings`)}" @click=${()=>this.onClose?.()}><span class="settings-back-icon" aria-hidden="true">×</span><span class="settings-back-label">${O(`ui.settingsDialog.backToApp`,`Back to app`)}</span></button>
840
+ </header>
841
+ <div class="settings-body">
842
+ <pi-web-ui-presentation region="settings-navigation" .runtime=${this.presentationRuntime} .context=${this.presentationContext}>
843
+ <nav slot="navigation" class="settings-nav" aria-label="${O(`ui.settingsDialog.settingsSections`,`Settings sections`)}">
844
+ ${this.renderNavButton(`general`,O(`client.actions.general.835b70`,`General`),O(`ui.settingsDialog.gatewayAndSelectedMachine`,`Gateway and selected machine`))}
845
+ ${this.renderNavButton(`sessiond`,O(`bundled.updates.session.daemon.757666`,`Session daemon`),O(`ui.settingsDialog.selectedMachine`,`Selected machine`))}
846
+ ${this.renderNavButton(`packages`,O(`bundled.updates.pi.package.feed18`,`Pi package`),O(`ui.settingsDialog.selectedMachine`,`Selected machine`))}
847
+ ${this.renderNavButton(`plugins`,O(`client.machinePluginLoadCoordinator.pi.web.plugins.54b78f`,`PI WEB plugins`),O(`ui.settingsDialog.selectedMachine`,`Selected machine`))}
848
+ ${this.renderNavButton(`mcp`,`MCP`,O(`ui.mcp.selectedSession`,`Selected session`))}
849
+ ${this.renderNavButton(`shortcuts`,O(`ui.settingsDialog.keyboard`,`Keyboard`),O(`ui.settingsDialog.gatewayShortcuts`,`Gateway shortcuts`))}
850
+ </nav>
851
+ </pi-web-ui-presentation>
852
+ <main class="settings-main">
853
+ ${this.renderMachineSelector()}
854
+ ${this.renderMachineSwitchConfirmation()}
855
+ <div class="settings-content">${p(this.renderActiveSection())}</div>
856
+ </main>
857
+ </div>
858
+ </modal-surface>
859
+ `}renderMachineSelector(){if(this.machines.length<=1)return null;let e=this.settingsTarget(),t=this.machineStatuses[e.id],n=this.machines.find(t=>t.id===e.id),r=this.settingsRuntime(this.machineRuntimes,this.machineRuntime,e),i=t?.status??(t===void 0?n?.status??(r===void 0?`unknown`:r.ok?`online`:`offline`):t.ok?`online`:`offline`),a=i===`online`?O(`ui.settingsDialog.machineConnected`,`Connected`):i===`unknown`?O(`ui.settingsDialog.machineUnchecked`,`Connection not checked`):O(`ui.settingsDialog.machineUnavailable`,`Unavailable`),o=i===`offline`||i===`error`,s=o?t?.error??n?.statusMessage??r?.error:void 0;return D`
860
+ <div class="settings-machine">
861
+ <label for="settings-machine">${O(`ui.settingsDialog.configureMachine`,`Configure machine`)}</label>
862
+ <select class="ui-select" id="settings-machine" aria-describedby=${o?`settings-machine-help settings-machine-status settings-machine-error`:`settings-machine-help settings-machine-status`} .value=${S(e.id)} ?disabled=${this.saving} @change=${e=>{e.target instanceof HTMLSelectElement&&this.requestMachineSwitch(e.target.value)}}>
863
+ ${this.machines.map(e=>D`<option value=${e.id}>${e.name}${e.kind===`local`?O(`ui.settingsDialog.thisGateway`,` (this gateway)`):``}</option>`)}
864
+ </select>
865
+ <small id="settings-machine-status" class=${o?`machine-status unavailable`:`machine-status`} role="status">${a}</small>
866
+ <details class="machine-scope">
867
+ <summary>${O(`ui.settingsDialog.machineScopeTitle`,`What changes?`)}</summary>
868
+ <p id="settings-machine-help">${O(`ui.settingsDialog.machineScope`,`Agent permissions, packages, plugins, file access, and upload settings apply to this machine. Gateway settings, the default theme, and keyboard shortcuts stay on this server. Your browser theme, workspace, and session stay unchanged.`)}</p>
869
+ </details>
870
+ ${o?D`<p id="settings-machine-error" class="machine-connection-error" role="status">${s??O(`ui.settingsDialog.machineUnavailableMessage`,`This machine is unavailable.`)}<br>${O(`ui.settingsDialog.checkMachineConnection`,`Check the machine connection, then refresh settings.`)}</p>`:null}
871
+ </div>
872
+ `}requestMachineSwitch(e){!this.saving&&this.machines.some(t=>t.id===e)&&(e===this.settingsTarget().id?this.pendingMachineId=void 0:this.generalPanel?.hasUnsavedMachineChanges===!0?this.pendingMachineId=e:this.switchSettingsMachine(e),this.requestUpdate())}switchSettingsMachine(e){this.settingsMachineId=e,this.pendingMachineId=void 0,this.reloadForTargetChange(this.settingsTarget())}reloadForTargetChange(e){this.resetAccessStateForTargetChange(),this.resetSessiondStateForTargetChange(),this.resetPluginStateForTargetChange(),this.resetPackageStateForTargetChange(),this.isConnected&&(this.loadAccessConfigForTarget(e),this.reloadSessiondState(e),this.loadPluginsForTarget(e),this.loadPackagesForTarget(e))}renderMachineSwitchConfirmation(){let e=this.machines.find(e=>e.id===this.pendingMachineId);return e===void 0?null:D`
873
+ <section class="machine-switch-confirmation" role="alert" aria-label=${O(`ui.settingsDialog.unsavedMachineSettings`,`Unsaved machine settings`)}>
874
+ <p>${O(`ui.settingsDialog.confirmMachineSwitch`,`You have unsaved file access or upload settings for {current}. Discard them and configure {next}?`,{current:this.settingsTarget().name,next:e.name})}</p>
875
+ <button class="ui-button ui-button--action danger" ?disabled=${this.saving} @click=${()=>{this.generalPanel?.discardMachineChanges(),this.switchSettingsMachine(e.id)}}>${O(`ui.settingsDialog.discardAndSwitch`,`Discard edits and switch`)}</button>
876
+ <button class="ui-button ui-button--action" @click=${()=>{this.pendingMachineId=void 0}}>${O(`ui.settingsDialog.keepEditing`,`Keep editing`)}</button>
877
+ </section>
878
+ `}renderActiveSection(){if(this.section===`mcp`){let e=this.settingsTarget();return D`<settings-mcp-panel
879
+ .context=${this.mcpContext?.machineId===e.id?this.mcpContext:void 0}
880
+ .targetLabel=${J(e)}
881
+ .onMcpAuth=${this.onMcpAuth}
882
+ ></settings-mcp-panel>`}if(this.section===`sessiond`){let e=this.settingsTarget();return D`
883
+ <settings-sessiond-panel
884
+ .configResponse=${this.sessiondConfigResponse}
885
+ .targetId=${e.id}
886
+ .namingContextKey=${JSON.stringify([this.namingModelsTarget?.machineId,this.namingModelsTarget?.projectId])}
887
+ .namingModels=${this.namingModels}
888
+ .namingModelsLoading=${this.namingModelsLoading}
889
+ .namingModelsError=${this.namingModelsError}
890
+ .loading=${this.sessiondLoading}
891
+ .saving=${this.saving}
892
+ .error=${this.sessiondError}
893
+ .savedMessage=${this.savedSection===`sessiond`?this.savedMessage:``}
894
+ .targetLabel=${J(this.settingsTarget())}
895
+ .activeAgentProfile=${this.settingsRuntime(this.machineRuntimes,this.machineRuntime,this.settingsTarget())?.components?.sessiond.activeAgentProfile}
896
+ .agentProfileSupport=${this.agentProfileSettingsSupport()}
897
+ .onReload=${()=>this.reloadSessiondState()}
898
+ .onSave=${t=>this.saveSessiondConfig(t,e)}
899
+ ></settings-sessiond-panel>
900
+ `}return this.section===`shortcuts`?D`
901
+ <settings-shortcuts-panel
902
+ .actions=${this.actions}
903
+ .configResponse=${this.configResponse}
904
+ .loading=${this.loading}
905
+ .saving=${this.saving}
906
+ .error=${this.error}
907
+ .savedMessage=${this.savedSection===`shortcuts`?this.savedMessage:``}
908
+ .onReload=${()=>this.loadConfig()}
909
+ .onSave=${e=>this.saveConfig(e)}
910
+ ></settings-shortcuts-panel>
911
+ `:this.section===`packages`?D`
912
+ <settings-packages-panel
913
+ .packagesResponse=${this.packagesResponse}
914
+ .targetMachine=${this.packageTarget()}
915
+ .managementSupport=${this.packageManagementSupport()}
916
+ .loading=${this.packageLoading}
917
+ .operation=${this.packageOperation}
918
+ .error=${this.packageError}
919
+ .operationMessage=${this.packageMessage}
920
+ .onReload=${()=>this.loadPackagesForTarget()}
921
+ .onInstallPackage=${e=>this.installPiPackage(e)}
922
+ .onRemovePackage=${(e,t)=>this.removePiPackage(e,t)}
923
+ .onUpdatePackage=${e=>this.updatePiPackage(e)}
924
+ ></settings-packages-panel>
925
+ `:this.section===`plugins`?D`
926
+ <settings-plugins-panel
927
+ .configResponse=${this.selectedPluginConfigResponse}
928
+ .pluginsResponse=${this.selectedPluginsResponse}
929
+ .loading=${this.pluginLoading}
930
+ .saving=${this.saving}
931
+ .recoveryCommandsSupported=${q(this.settingsTarget(),this.settingsRuntime(this.machineRuntimes,this.machineRuntime,this.settingsTarget())).state===`supported`}
932
+ .error=${this.pluginError}
933
+ .savedMessage=${this.savedSection===`plugins`?this.savedMessage:``}
934
+ .targetLabel=${J(this.settingsTarget())}
935
+ .onReload=${()=>this.loadPluginsForTarget()}
936
+ .onTogglePlugin=${(e,t)=>this.togglePlugin(e,t)}
937
+ ></settings-plugins-panel>
938
+ `:D`
939
+ <settings-general-panel
940
+ .configResponse=${this.configResponse}
941
+ .machineConfigResponse=${this.accessConfigResponse}
942
+ .loading=${this.loading}
943
+ .machineLoading=${this.accessLoading}
944
+ .saving=${this.saving}
945
+ .error=${this.error}
946
+ .machineError=${this.accessError}
947
+ .savedMessage=${this.savedSection===`general`?this.savedMessage:``}
948
+ .targetLabel=${J(this.settingsTarget())}
949
+ .targetId=${this.settingsTarget().id}
950
+ .onReload=${()=>this.loadConfig()}
951
+ .onReloadMachine=${()=>this.loadAccessConfigForTarget()}
952
+ .onSave=${e=>this.saveConfig(e)}
953
+ .onSaveMachineConfig=${e=>this.saveMachineAccessConfig(e)}
954
+ >
955
+ <settings-theme-panel
956
+ slot="appearance"
957
+ .themes=${this.themes}
958
+ .preference=${this.themePreference}
959
+ .defaultPreference=${u(void 0,this.configResponse?.effectiveConfig.defaultTheme,this.themes)}
960
+ .activeThemeId=${this.activeThemeId}
961
+ .hasLocalOverride=${this.hasLocalThemeOverride}
962
+ .loading=${this.loading||this.configResponse===void 0}
963
+ .saving=${this.saving}
964
+ .onUseLocal=${this.onUseLocalTheme}
965
+ .onUseDefault=${this.onUseDefaultTheme}
966
+ .onSetDefault=${e=>this.saveDefaultTheme(e)}
967
+ ></settings-theme-panel>
968
+ </settings-general-panel>
969
+ `}renderNavButton(e,t,n){let r=this.section===e;return D`
970
+ <button class=${`ui-button ui-selection-option${r?` selected`:``}`} aria-current=${r?`page`:`false`} @click=${()=>{this.navigate(e)}}>
971
+ <strong>${t}</strong>
972
+ <small>${n}</small>
973
+ </button>
974
+ `}navigate(e){this.onNavigate?.(e)}async loadConfig(){let e=++this.loadRequestSeq;this.loading=!0,this.error=``;try{let t=await Pt({loadConfig:()=>_.config(),loadPlugins:()=>C.plugins()});if(!this.isCurrentLoad(e))return;t.config!==void 0&&(this.configResponse=t.config,this.onConfigSaved?.(t.config.effectiveConfig)),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??O(`ui.settingsDialog.doesNotSupportSelectedMachineSettings`,`{value1} does not support selected-machine settings.`,{value1:J(e)});else{this.accessLoading=!0,this.accessError=``;try{let n=await _.config(e.id);if(!this.isCurrentAccessLoad(t,e))return;this.accessConfigResponse=n}catch(n){this.isCurrentAccessLoad(t,e)&&(this.accessError=O(`ui.settingsDialog.failedToLoadFileAccessUploadConfigurationFrom`,`Failed to load file access/upload configuration from {value1}: {value2}`,{value1:J(e),value2:Z($(n),e)}))}finally{this.isCurrentAccessLoad(t,e)&&(this.accessLoading=!1)}}}async reloadSessiondState(e=this.settingsTarget()){await Promise.all([this.loadSessiondConfigForTarget(e),this.loadNamingModelsForTarget(e),this.onRefreshMachineRuntime?.(e.id)])}async loadNamingModelsForTarget(e=this.settingsTarget()){let t=++this.namingModelsLoadRequestSeq;this.namingModels=[],this.namingModelsLoading=!1,this.namingModelsError=``;let n=this.namingModelsTarget;if(n?.machineId!==e.id){this.namingModelsError=O(`ui.sessionNaming.selectProject`,`Select a project on this machine to load naming models.`);return}let r={...n},i=()=>t===this.namingModelsLoadRequestSeq&&this.isCurrentSettingsTarget(e)&&this.namingModelsTarget?.machineId===r.machineId&&this.namingModelsTarget.projectId===r.projectId;this.namingModelsLoading=!0;try{let e=await _.namingModels(r);i()&&(this.namingModels=e.models)}catch(t){i()&&(this.namingModelsError=O(`ui.sessionNaming.loadModelsError`,`Failed to load naming models from {machine}: {error}`,{machine:J(e),error:Z($(t),e)}))}finally{i()&&(this.namingModelsLoading=!1)}}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??O(`ui.settingsDialog.doesNotSupportSelectedMachineSettings`,`{value1} does not support selected-machine settings.`,{value1:J(e)});else{this.sessiondLoading=!0,this.sessiondError=``;try{let n=await _.config(e.id);if(!this.isCurrentSessiondLoad(t,e))return;this.sessiondConfigResponse=n}catch(n){this.isCurrentSessiondLoad(t,e)&&(this.sessiondError=O(`ui.settingsDialog.failedToLoadSessionDaemonConfigurationFrom`,`Failed to load session daemon configuration from {value1}: {value2}`,{value1:J(e),value2:Z($(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??O(`ui.settingsDialog.doesNotSupportSelectedMachineSettings`,`{value1} does not support selected-machine settings.`,{value1:J(e)});else{this.pluginLoading=!0,this.pluginError=``;try{let n=q(e,this.settingsRuntime(this.machineRuntimes,this.machineRuntime,e));if(X(n)){try{let r=await _.config(e.id);if(!this.isCurrentPluginLoad(t,e))return;this.selectedPluginConfigResponse=r,this.selectedPluginsResponse=void 0,this.pluginError=n.message??O(`ui.main.f4f3f5e99cce`,`{arg0} does not support plugin lifecycle diagnostics.`,{arg0:J(e)})}catch(r){if(!this.isCurrentPluginLoad(t,e))return;this.pluginError=O(`ui.main.93db7a95336e`,`Failed to load PI WEB plugin configuration from {arg0}: {arg1}; {arg2}`,{arg0:J(e),arg1:Z($(r),e),arg2:n.message??O(`ui.main.2de7706b69b4`,`plugin lifecycle diagnostics are unsupported`)})}return}let[r,i]=await Promise.allSettled([_.config(e.id),C.plugins(e.id)]);if(!this.isCurrentPluginLoad(t,e))return;let a=[];r.status===`fulfilled`?this.selectedPluginConfigResponse=r.value:a.push(O(`ui.shared.e759c5a58cb4`,`Config: {configPath}`,{configPath:Z($(r.reason),e)})),i.status===`fulfilled`?this.selectedPluginsResponse=i.value:a.push(O(`ui.settingsDataLoading.piWebPlugins`,`PI WEB plugins: {reason}`,{reason:Z($(i.reason),e)})),this.pluginError=a.length===0?``:O(`ui.settingsDialog.failedToLoadPiWebPluginSettingsFrom`,`Failed to load PI WEB plugin settings from {value1}: {join}`,{value1:J(e),join:a.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 Ft(e,e=>T.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(e===`pi-web.terminal`||this.selectedPluginsResponse?.plugins.find(({id:t})=>t===e)?.required===!0||this.saving)return;let n=this.settingsTarget(),r=this.selectedMachineSettingsSupport(n);if(X(r)){this.pluginError=r.message??O(`ui.settingsDialog.doesNotSupportSelectedMachineSettings`,`{value1} does not support selected-machine settings.`,{value1:J(n)});return}if(this.selectedPluginConfigResponse===void 0){this.pluginError=O(`ui.settingsDialog.pluginConfigurationForIsNotLoadedReloadBefore`,`Plugin configuration for {value1} is not loaded. Reload before changing plugin activation.`,{value1:J(n)});return}let i=Kt(this.selectedPluginConfigResponse.config,e,t);this.saving=!0,this.pluginError=``,this.savedMessage=``;try{let e=await _.saveConfig(i,n.id);if(!this.isCurrentSettingsTarget(n))return;this.selectedPluginConfigResponse=e,n.kind===`local`&&this.configResponse!==void 0&&(this.configResponse=qt(this.configResponse,e),this.onConfigSaved?.(this.configResponse.effectiveConfig));let t=q(n,this.settingsRuntime(this.machineRuntimes,this.machineRuntime,n)),r;if(X(t)?(this.selectedPluginsResponse=void 0,r=t.message??O(`ui.main.f4f3f5e99cce`,`{arg0} does not support plugin lifecycle diagnostics.`,{arg0:J(n)})):r=await this.refreshPluginsForTarget(n),!this.isCurrentSettingsTarget(n))return;r!==void 0&&(this.pluginError=r),this.showSavedMessage(O(`ui.settingsDialog.pluginSettingsSaved`,`Plugin settings saved for {machine}.`,{machine:n.name}),`plugins`)}catch(e){this.isCurrentSettingsTarget(n)&&(this.pluginError=O(`ui.settingsDialog.failedToSavePiWebPluginConfigurationOn`,`Failed to save PI WEB plugin configuration on {value1}: {value2}`,{value1:J(n),value2:Z($(e),n)}))}finally{this.saving=!1}}async saveConfig(e){if(this.saving)return;let t=this.section===`shortcuts`?`shortcuts`:`general`;this.saving=!0,this.error=``,this.savedMessage=``;try{let n=await _.saveConfig(e);this.configResponse=n,this.onConfigSaved?.(n.effectiveConfig),this.showSavedMessage(t===`shortcuts`?O(`ui.settingsDialog.keyboardSaved`,`Keyboard settings saved.`):O(`ui.settingsDialog.gatewaySaved`,`Gateway settings saved. Restart the web service to apply address changes.`),t)}catch(e){this.error=O(`ui.settingsDialog.failedToSaveConfiguration`,`Failed to save configuration: {errorMessageerror}`,{errorMessageerror:$(e)})}finally{this.saving=!1}}async saveDefaultTheme(e){if(!this.saving){this.loadRequestSeq+=1,this.loading=!1,this.saving=!0,this.error=``,this.savedMessage=``;try{let t=await _.config(),n=await _.saveConfig({...t.config,defaultTheme:e});this.configResponse=n,this.onConfigSaved?.(n.effectiveConfig),this.showSavedMessage(O(`ui.settingsDialog.configurationSaved`,`Configuration saved.`),`general`)}catch(e){this.error=O(`ui.settingsThemePanel.saveFailed`,`Failed to save default theme: {message}`,{message:$(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??O(`ui.settingsDialog.doesNotSupportSelectedMachineSettings`,`{value1} does not support selected-machine settings.`,{value1:J(t)});else{this.saving=!0,this.accessError=``,this.savedMessage=``;try{let n=await _.saveConfig(e,t.id);if(!this.isCurrentSettingsTarget(t))return;this.accessConfigResponse=n,t.kind===`local`&&this.configResponse!==void 0&&(this.configResponse=Lt(this.configResponse,n),this.onConfigSaved?.(this.configResponse.effectiveConfig)),this.showSavedMessage(O(`ui.settingsDialog.fileSettingsSaved`,`File access and upload settings saved for {machine}.`,{machine:t.name}),`general`)}catch(e){this.isCurrentSettingsTarget(t)&&(this.accessError=O(`ui.settingsDialog.failedToSaveFileAccessUploadConfigurationOn`,`Failed to save file access/upload configuration on {value1}: {value2}`,{value1:J(t),value2:Z($(e),t)}))}finally{this.saving=!1}}}async saveSessiondConfig(e,t=this.settingsTarget()){if(this.saving||!this.isCurrentSettingsTarget(t))return;let n=this.selectedMachineSettingsSupport(t);if(X(n))this.sessiondError=n.message??O(`ui.settingsDialog.doesNotSupportSelectedMachineSettings`,`{value1} does not support selected-machine settings.`,{value1:J(t)});else{if(e.agent!==void 0){let e=this.agentProfileSettingsSupport(t);if(!Ht(e)){this.sessiondError=e.message??O(`ui.settingsDialog.doesNotSupportPiCompatibleAgentProfileSettings`,`{value1} does not support Pi-compatible agent profile settings.`,{value1:J(t)});return}}this.saving=!0,this.sessiondError=``,this.savedMessage=``;try{let n=await _.saveConfig(e,t.id);if(!this.isCurrentSettingsTarget(t))return;this.sessiondConfigResponse=n,t.kind===`local`&&this.configResponse!==void 0&&(this.configResponse=He(this.configResponse,n));let r=Object.keys(e).length===1&&e.sessionNaming!==void 0;this.showSavedMessage(r?O(`ui.sessionNaming.saved`,`Session naming settings saved for {machine}. They apply to the next naming request without a restart. Existing names and in-progress naming requests are unchanged.`,{machine:t.name}):O(`ui.sessionNaming.daemonSaved`,`Session daemon settings saved for {machine}. Restart the session daemon to apply agent permission changes. Restarting interrupts active sessions.{naming}`,{machine:t.name,naming:e.sessionNaming===void 0?``:O(`ui.sessionNaming.nextRequest`,` Naming changes apply to the next naming request without a restart.`)}),`sessiond`)}catch(e){this.isCurrentSettingsTarget(t)&&(this.sessiondError=O(`ui.settingsDialog.failedToSaveSessionDaemonConfigurationOn`,`Failed to save session daemon configuration on {value1}: {value2}`,{value1:J(t),value2:Z($(e),t)}))}finally{this.saving=!1}}}async installPiPackage(e){let t=this.packageTarget();await this.runPiPackageMutation({kind:`install`,source:e},O(`ui.settingsDialog.installPiPackage`,`Install Pi package`),t,()=>T.install(e,t.id))}async removePiPackage(e,t){let n=this.packageTarget();await this.runPiPackageMutation({kind:`remove`,source:e},O(`ui.settingsDialog.removePiPackage`,`Remove Pi package`),n,()=>T.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},O(`ui.settingsDialog.updatePiPackage`,`Update Pi package`),t,()=>T.update(e,t.id))}async runPiPackageMutation(e,t,n,r){let i=this.packageManagementSupport(n);if(H(i))throw this.packageError=i.message??O(`ui.settingsDataLoading.doesNotSupportPiPackageManagement`,`{piPackageTargetLabeltarget} does not support Pi package management.`,{piPackageTargetLabeltarget:V(n)}),Error(this.packageError);if(this.saving)throw Error(O(`ui.settingsDialog.aSettingsOperationIsAlreadyRunning`,`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=it(e);let t=Qe(n)?await this.refreshGatewayPlugins():void 0;if(!this.isCurrentPackageMutation(a,n))return;t!==void 0&&(this.packageError=t),this.packageMessage=lt(e.action,n)}catch(e){throw this.isCurrentPackageMutation(a,n)&&(this.packageError=O(`ui.settingsDialog.failedOn`,`{label} failed on {piPackageTargetLabeltarget}: {value3}`,{piPackageTargetLabeltarget:V(n),label:t,value3:ut($(e),n)})),e}finally{this.packageMutationSeq===a&&(this.packageOperation=void 0,this.saving=!1)}}async refreshGatewayPlugins(){try{this.pluginsResponse=await C.plugins();return}catch(e){return O(`ui.settingsDialog.failedToRefreshGatewayPiWebPlugins`,`Failed to refresh gateway PI WEB plugins: {errorMessageerror}`,{errorMessageerror:$(e)})}}async refreshPluginsForTarget(e){try{let t=await C.plugins(e.id);this.isCurrentSettingsTarget(e)&&(this.selectedPluginsResponse=t);return}catch(t){return this.isCurrentSettingsTarget(e)&&(this.selectedPluginsResponse=void 0),O(`ui.settingsDialog.configurationSavedButFailedToRefreshPiWeb`,`Configuration saved, but failed to refresh PI WEB plugins from {value1}: {value2}`,{value1:J(e),value2:Z($(t),e)})}}selectedSettingsMachine(e,t,n){return e.length===0?t:e.find(e=>e.id===(n??t?.id))??e.find(e=>e.kind===`local`)??e[0]}settingsTarget(){return zt(this.selectedSettingsMachine(this.machines,this.machine,this.settingsMachineId))}settingsRuntime(e,t,n){return e[n.id]??(t?.machineId===n.id?t:void 0)}packageTarget(){return this.settingsTarget()}selectedMachineSettingsSupport(e=this.settingsTarget()){return Bt(e,this.settingsRuntime(this.machineRuntimes,this.machineRuntime,e))}agentProfileSettingsSupport(e=this.settingsTarget()){return Vt(e,this.settingsRuntime(this.machineRuntimes,this.machineRuntime,e))}selectedMachineSettingsSupportNeedsReload(e,t){let n=Bt(t,e),r=this.selectedMachineSettingsSupport(t);return Y(n)!==Y(r)}packageManagementSupport(e=this.packageTarget()){return Ye(e,this.settingsRuntime(this.machineRuntimes,this.machineRuntime,e))}packageManagementSupportNeedsReload(e,t){let n=Ye(t,e),r=this.packageManagementSupport(t);return Xe(n)===Xe(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.namingModelsLoadRequestSeq+=1,this.namingModels=[],this.namingModelsLoading=!1,this.namingModelsError=``,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(e=O(`ui.settingsDialog.configurationSaved`,`Configuration saved.`),t=this.section){this.savedMessage=e,this.savedSection=t,this.savedMessageTimer!==void 0&&window.clearTimeout(this.savedMessageTimer),this.savedMessageTimer=window.setTimeout(()=>{this.savedMessage===e&&(this.savedMessage=``),this.savedMessageTimer=void 0},3e3)}static{this.styles=[se,re,E`
975
+ @layer pi-web-base {
976
+ :host { position: fixed; inset: 0; z-index: 30; color: var(--pi-text); font: 14px var(--pi-font, system-ui, sans-serif); }
977
+ modal-surface { --modal-surface-backdrop-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)); --modal-surface-width: min(980px, 100%); --modal-surface-max-height: min(760px, 100%); --modal-surface-min-height: min(620px, 100%); --modal-surface-radius: 14px; }
978
+ .settings-machine { display: flex; flex: 0 0 auto; flex-wrap: wrap; align-items: center; gap: 8px; padding: 12px 18px; border-bottom: 1px solid var(--pi-border); }
979
+ .settings-machine label { font-size: 12px; font-weight: 700; }
980
+ .settings-machine select { flex: 1 1 160px; max-width: 280px; background: var(--pi-bg); }
981
+ .machine-status { color: var(--pi-muted); line-height: 1.35; }
982
+ .machine-status.unavailable { color: var(--pi-warning); }
983
+ .machine-scope { color: var(--pi-muted); font-size: 12px; }
984
+ .machine-scope summary { cursor: pointer; }
985
+ .machine-scope[open] { flex-basis: 100%; }
986
+ .machine-scope p { margin: 8px 0 0; line-height: 1.45; }
987
+ .machine-connection-error { flex-basis: 100%; margin: 0; font-size: 12px; line-height: 1.45; color: var(--pi-warning); overflow-wrap: anywhere; }
988
+ .machine-scope summary:focus-visible { outline: 2px solid var(--pi-accent); outline-offset: 2px; }
989
+ .machine-switch-confirmation { flex: 0 0 auto; padding: 12px 16px; border-bottom: 1px solid var(--pi-warning-border); background: var(--pi-warning-surface); }
990
+ .machine-switch-confirmation p { margin: 0 0 8px; }
991
+ .machine-switch-confirmation button + button { margin-inline-start: 8px; }
992
+ .settings-body { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: 220px minmax(0, 1fr); }
993
+ .settings-nav { min-height: 0; flex: 1 1 auto; border-inline-end: 1px solid var(--pi-border); background: var(--pi-surface); overflow: auto; }
994
+ .settings-nav button { display: grid; justify-content: stretch; gap: 2px; }
995
+ .settings-nav span, .settings-nav small { min-width: 0; overflow-wrap: anywhere; white-space: normal; }
996
+ .settings-nav small { color: var(--pi-muted); }
997
+ .settings-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
998
+ .settings-content { flex: 1 1 auto; min-width: 0; min-height: 0; overflow: auto; padding: 0; }
999
+ .settings-back-label { display: none; }
1000
+
1001
+ @media (max-width: 760px) {
1002
+ modal-surface { --modal-surface-backdrop-padding: 0; --modal-surface-place-items: stretch; --modal-surface-width: 100%; --modal-surface-max-height: none; --modal-surface-min-height: 0; --modal-surface-border: 0; --modal-surface-radius: 0; }
1003
+ .settings-header { padding-top: env(safe-area-inset-top); }
1004
+ .settings-machine { padding: 10px 12px; }
1005
+ .settings-machine label { flex-basis: 100%; }
1006
+ .settings-machine select { max-width: none; }
1007
+ .machine-scope { flex-basis: 100%; }
1008
+ .settings-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
1009
+ .settings-nav { display: flex; gap: 0; padding: 0; border-inline-end: 0; border-bottom: 1px solid var(--pi-border); overflow-x: auto; overflow-y: hidden; }
1010
+ .settings-nav button { flex: 0 0 auto; width: auto; white-space: nowrap; border-inline-end: 1px solid var(--pi-border-muted); }
1011
+ .settings-nav small { display: none; }
1012
+ .settings-content { padding-bottom: env(safe-area-inset-bottom); }
1013
+ }
1014
+ }
1015
+ `]}};w([m({attribute:!1})],Q.prototype,`section`,void 0),w([m({attribute:!1})],Q.prototype,`presentationRuntime`,void 0),w([m({attribute:!1})],Q.prototype,`presentationContext`,void 0),w([m({attribute:!1})],Q.prototype,`actions`,void 0),w([m({attribute:!1})],Q.prototype,`themes`,void 0),w([m({attribute:!1})],Q.prototype,`themePreference`,void 0),w([m()],Q.prototype,`activeThemeId`,void 0),w([m({type:Boolean})],Q.prototype,`hasLocalThemeOverride`,void 0),w([m({attribute:!1})],Q.prototype,`onUseLocalTheme`,void 0),w([m({attribute:!1})],Q.prototype,`onUseDefaultTheme`,void 0),w([m({attribute:!1})],Q.prototype,`mcpContext`,void 0),w([m({attribute:!1})],Q.prototype,`onMcpAuth`,void 0),w([m({attribute:!1,hasChanged:(e,t)=>e?.machineId!==t?.machineId||e?.projectId!==t?.projectId})],Q.prototype,`namingModelsTarget`,void 0),w([m({attribute:!1})],Q.prototype,`machine`,void 0),w([m({attribute:!1})],Q.prototype,`machineRuntime`,void 0),w([m({attribute:!1})],Q.prototype,`machines`,void 0),w([m({attribute:!1})],Q.prototype,`machineStatuses`,void 0),w([m({attribute:!1})],Q.prototype,`machineRuntimes`,void 0),w([b()],Q.prototype,`settingsMachineId`,void 0),w([b()],Q.prototype,`pendingMachineId`,void 0),w([m({attribute:!1})],Q.prototype,`onNavigate`,void 0),w([m({attribute:!1})],Q.prototype,`onClose`,void 0),w([m({attribute:!1})],Q.prototype,`onConfigSaved`,void 0),w([m({attribute:!1})],Q.prototype,`onRefreshMachineRuntime`,void 0),w([b()],Q.prototype,`configResponse`,void 0),w([b()],Q.prototype,`accessConfigResponse`,void 0),w([b()],Q.prototype,`sessiondConfigResponse`,void 0),w([b()],Q.prototype,`pluginsResponse`,void 0),w([b()],Q.prototype,`selectedPluginConfigResponse`,void 0),w([b()],Q.prototype,`selectedPluginsResponse`,void 0),w([b()],Q.prototype,`packagesResponse`,void 0),w([b()],Q.prototype,`loading`,void 0),w([b()],Q.prototype,`accessLoading`,void 0),w([b()],Q.prototype,`sessiondLoading`,void 0),w([b()],Q.prototype,`namingModels`,void 0),w([b()],Q.prototype,`namingModelsLoading`,void 0),w([b()],Q.prototype,`namingModelsError`,void 0),w([b()],Q.prototype,`pluginLoading`,void 0),w([b()],Q.prototype,`packageLoading`,void 0),w([b()],Q.prototype,`saving`,void 0),w([b()],Q.prototype,`packageOperation`,void 0),w([b()],Q.prototype,`error`,void 0),w([b()],Q.prototype,`accessError`,void 0),w([b()],Q.prototype,`sessiondError`,void 0),w([b()],Q.prototype,`pluginError`,void 0),w([b()],Q.prototype,`packageError`,void 0),w([b()],Q.prototype,`savedMessage`,void 0),w([b()],Q.prototype,`savedSection`,void 0),w([b()],Q.prototype,`packageMessage`,void 0),Q=w([y(`settings-dialog`)],Q);function $(e){return e instanceof Error?e.message:String(e)}function Yt(e){switch(e){case`sessiond`:return`settings-sessiond-panel`;case`packages`:return`settings-packages-panel`;case`plugins`:return`settings-plugins-panel`;case`shortcuts`:return`settings-shortcuts-panel`;case`mcp`:return`settings-mcp-panel`;case`general`:return`settings-general-panel`}}export{Q as SettingsDialog,Yt as activeSettingsPanelTag};