@shawnstack/quickforge 1.5.6 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/README.md +450 -450
  2. package/dist/assets/{AgentProfilesPage-DFUA4KiP.js → AgentProfilesPage-wpt1cJV0.js} +1 -1
  3. package/dist/assets/{ChatPanelHost-CBoFtBvB.js → ChatPanelHost-CnQoAfxW.js} +2 -2
  4. package/dist/assets/{PluginsPage-CKOP-P02.js → PluginsPage-0wwQydcP.js} +1 -1
  5. package/dist/assets/ScheduledTasksPage-qGHyGkjw.js +2 -0
  6. package/dist/assets/{SettingsWorkspacePage-Csr6xu0M.js → SettingsWorkspacePage-CeYg_VJl.js} +306 -306
  7. package/dist/assets/{SharedConversationPage-7I9MiMcj.js → SharedConversationPage-D97o9Ycp.js} +1 -1
  8. package/dist/assets/TerminalDock-D4zLoahb.js +2 -0
  9. package/dist/assets/WorkspaceInspector-Bn-am8g6.js +3 -0
  10. package/dist/assets/{WorkspaceReaderDialog-Dli8GgAq.js → WorkspaceReaderDialog-B2WEMVuF.js} +1 -1
  11. package/dist/assets/{diff-line-counts-Dvz3MNk2.js → diff-line-counts-B60LmPZX.js} +1 -1
  12. package/dist/assets/{icons-DXrzz0RO.js → icons-BlAm_pUr.js} +1 -1
  13. package/dist/assets/{index-BDNDRaPf.css → index-C3bhHGO4.css} +1 -1
  14. package/dist/assets/index-C_DXqhW8.js +69 -0
  15. package/dist/assets/{mcp-servers-dialog-DXR3fnZY.js → mcp-servers-dialog-DEyq3gmP.js} +3 -3
  16. package/dist/assets/{monaco-k8av2MY0.js → monaco-C5Lhy6-h.js} +1 -1
  17. package/dist/assets/{react-vendor-xMa3TUTb.js → react-vendor--m65aOgw.js} +1 -1
  18. package/dist/assets/{skills-dialog-Dax-_Ze5.js → skills-dialog-CZ3CuVtQ.js} +1 -1
  19. package/dist/assets/{useAppTheme-BzB8Q6AC.js → useAppTheme-ChXh3B2c.js} +1 -1
  20. package/dist/index.html +6 -6
  21. package/package.json +4 -1
  22. package/dist/assets/ScheduledTasksPage-CRPvyfmE.js +0 -2
  23. package/dist/assets/TerminalDock-DWZAOy7v.js +0 -2
  24. package/dist/assets/WorkspaceInspector-D4k8zQ4s.js +0 -3
  25. package/dist/assets/index-BIslkXQt.js +0 -69
@@ -1,17 +1,17 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/AgentProfilesPage-DFUA4KiP.js","assets/rolldown-runtime-DWdDZTNf.js","assets/index-BIslkXQt.js","assets/pi-ai-Cx633yhb.js","assets/pi-web-ui-DFNE2m5b.js","assets/lit-vendor-Dr3cpBGF.js","assets/css-utils-rkE68RDy.js","assets/icons-DXrzz0RO.js","assets/react-vendor-xMa3TUTb.js","assets/skills-dialog-Dax-_Ze5.js","assets/logger-B65Akg8A.js","assets/index-BDNDRaPf.css","assets/mcp-servers-dialog-DXR3fnZY.js","assets/PluginsPage-CKOP-P02.js","assets/plugin-api-UKg_cgSG.js","assets/ScheduledTasksPage-CRPvyfmE.js"])))=>i.map(i=>d[i]);
2
- import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from"./icons-DXrzz0RO.js";import{n as r,r as i}from"./react-vendor-xMa3TUTb.js";import{p as a}from"./lit-vendor-Dr3cpBGF.js";import{a as o,u as s}from"./pi-web-ui-DFNE2m5b.js";import{y as c}from"./pi-ai-Cx633yhb.js";import{t as l}from"./logger-B65Akg8A.js";import{$ as u,A as ee,C as d,D as te,E as f,G as ne,H as p,J as re,M as m,S as h,T as ie,U as ae,V as g,X as oe,Y as _,_ as v,b as se,et as y,g as ce,it as b,j as x,k as le,nt as ue,q as de,rt as S,tt as fe,v as pe,w as me,x as he,y as ge}from"./index-BIslkXQt.js";var C=e(t(),1),_e={openai:{name:`OpenAI`,baseUrl:`https://api.openai.com/v1`,protocol:`openai-completions`,modelId:`gpt-4o`},deepseek:{name:`DeepSeek`,baseUrl:`https://api.deepseek.com/v1`,protocol:`openai-completions`,modelId:`deepseek-chat`},glm:{name:`Zhipu GLM`,baseUrl:`https://open.bigmodel.cn/api/paas/v4`,protocol:`openai-completions`,modelId:`glm-4-plus`},ollama:{name:`Ollama`,baseUrl:`http://localhost:11434/v1`,protocol:`openai-completions`,modelId:`llama3.1`},litellm:{name:g.name,baseUrl:g.baseUrl,protocol:`openai-completions`,modelId:g.modelId}},ve=[{key:`openai`,label:b(`presetOpenai`)},{key:`deepseek`,label:b(`presetDeepseek`)},{key:`glm`,label:b(`presetGlm`)},{key:`ollama`,label:b(`presetOllama`)},{key:`litellm`,label:b(`presetLitellm`)},{key:`custom`,label:b(`presetCustom`)}],w=()=>({modelId:``,contextWindow:g.contextWindow,maxTokens:g.maxTokens,reasoning:!0,open:!1}),T=()=>({name:g.name,baseUrl:g.baseUrl,apiKey:``,headerRows:[],protocol:`openai-completions`,models:[w()]}),ye=class extends o{providers=[];form=T();editingProviderId;formOpen=!1;loading=!0;apiKeyVisible=!1;advancedOpen=!1;activePreset=``;testing=!1;testResult=`idle`;testError=``;autoEditProviderName=null;async connectedCallback(){if(super.connectedCallback(),await this.loadProviders(),this.autoEditProviderName){let e=this.providers.find(e=>e.name===this.autoEditProviderName);e&&await this.openEditForm(e),this.autoEditProviderName=null}}getTabName(){return b(`customModels`)}async loadProviders(){this.loading=!0,this.requestUpdate();try{this.providers=await s().customProviders.getAll()}catch(e){l.error(`Failed to load custom providers:`,e),this.providers=[]}finally{this.loading=!1,this.requestUpdate()}}resetTestState(){this.testing=!1,this.testResult=`idle`,this.testError=``}openAddForm(){this.editingProviderId=void 0,this.form=T(),this.apiKeyVisible=!1,this.advancedOpen=!1,this.activePreset=``,this.resetTestState(),this.formOpen=!0,this.requestUpdate()}async openEditForm(e){let t=await s().providerKeys.get(e.name)??e.apiKey??``,n=e.models??[],r=n.length>0?n.map(e=>({modelId:e.id,contextWindow:e.contextWindow??g.contextWindow,maxTokens:e.maxTokens??g.maxTokens,reasoning:e.reasoning===!0,open:!1})):[w()],i=n[0]?.headers??{},a=Object.entries(i).map(([e,t])=>({key:e,value:String(t)}));this.editingProviderId=e.id,this.form={providerId:e.id,id:e.id,name:e.name,baseUrl:e.baseUrl,apiKey:t,headerRows:a,protocol:e.type===`anthropic-messages`?`anthropic-messages`:`openai-completions`,models:r},this.apiKeyVisible=!1,this.advancedOpen=a.length>0||e.type===`anthropic-messages`,this.activePreset=``,this.resetTestState(),this.formOpen=!0,this.requestUpdate()}closeForm(){this.formOpen=!1,this.editingProviderId=void 0,this.form=T(),this.apiKeyVisible=!1,this.advancedOpen=!1,this.activePreset=``,this.resetTestState(),this.requestUpdate()}toggleApiKeyVisibility(){this.apiKeyVisible=!this.apiKeyVisible,this.requestUpdate()}updateForm(e,t){this.form={...this.form,[e]:t},(e===`name`||e===`baseUrl`)&&(this.activePreset=``),this.resetTestState(),this.requestUpdate()}updateModelField(e,t,n){let r=this.form.models.map((r,i)=>i===e?{...r,[t]:n}:r);this.form={...this.form,models:r},t===`modelId`&&(this.activePreset=``,this.resetTestState()),this.requestUpdate()}addModelRow(){this.form={...this.form,models:[...this.form.models,w()]},this.requestUpdate()}removeModelRow(e){let t=this.form.models.filter((t,n)=>n!==e);this.form={...this.form,models:t},this.requestUpdate()}toggleModelExpanded(e){let t=this.form.models.map((t,n)=>n===e?{...t,open:!t.open}:t);this.form={...this.form,models:t},this.requestUpdate()}addHeaderRow(){this.form={...this.form,headerRows:[...this.form.headerRows,{key:``,value:``}]},this.requestUpdate()}updateHeaderRow(e,t,n){let r=this.form.headerRows.map((r,i)=>i===e?{...r,[t]:n}:r);this.form={...this.form,headerRows:r},this.requestUpdate()}removeHeaderRow(e){let t=this.form.headerRows.filter((t,n)=>n!==e);this.form={...this.form,headerRows:t},this.requestUpdate()}applyPreset(e){if(this.activePreset=e,e===`custom`)this.form={...this.form,name:``,baseUrl:``,protocol:`openai-completions`,models:[w()]};else{let t=_e[e];this.form={...this.form,name:t.name,baseUrl:t.baseUrl,protocol:t.protocol,models:[{...w(),modelId:t.modelId,open:!1}]}}this.resetTestState(),this.requestUpdate()}buildHeadersFromRows(){let e={};for(let t of this.form.headerRows){let n=t.key.trim(),r=t.value.trim();n&&r&&(e[n]=r)}return e}buildModel(e,t){let n=this.form.name.trim(),r=this.form.baseUrl.trim(),i=e.reasoning===!0,a=r.includes(`api.deepseek.com`);return de({id:e.modelId,name:`${e.modelId} (${n})`,api:this.form.protocol,provider:n,baseUrl:r.replace(/\/$/,``),reasoning:i,input:[`text`,`image`],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:Number(e.contextWindow)||g.contextWindow,maxTokens:Number(e.maxTokens)||g.maxTokens,headers:Object.keys(t).length>0?t:void 0,thinkingLevelMap:a&&i?{low:`high`,medium:`high`,high:`high`,xhigh:`max`}:void 0,compat:this.form.protocol===`openai-completions`?{supportsStore:!1,supportsDeveloperRole:!1,supportsReasoningEffort:i,supportsUsageInStreaming:!1,supportsStrictMode:!1,maxTokensField:`max_tokens`,...a&&i?{requiresReasoningContentOnAssistantMessages:!0,thinkingFormat:`deepseek`}:{}}:void 0})}async testConnection(){let e=this.form.baseUrl.trim(),t=this.form.models.find(e=>e.modelId.trim());if(!e||!t){this.testing=!1,this.testResult=`fail`,this.testError=b(`testRequiresFields`),this.requestUpdate();return}let n=this.buildHeadersFromRows(),r=this.buildModel(t,n);this.testing=!0,this.testResult=`idle`,this.testError=``,this.requestUpdate();try{let e=await(await fetch(`/api/models/test-connection`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({model:r,apiKey:this.form.apiKey.trim()})})).json().catch(()=>({}));e?.ok?(this.testResult=`ok`,this.testError=``):(this.testResult=`fail`,this.testError=e?.error||b(`connectionFailed`))}catch(e){this.testResult=`fail`,this.testError=e?.message||b(`connectionFailed`)}finally{this.testing=!1,this.requestUpdate()}}async saveModel(){let e=this.form.name.trim(),t=this.form.baseUrl.trim();if(!e||!t){x(b(`fillProviderBaseUrlModel`));return}let n=this.form.models.filter(e=>e.modelId.trim());if(n.length===0){x(b(`atLeastOneModel`));return}let r=n.map(e=>e.modelId.trim());if(new Set(r).size!==r.length){x(b(`duplicateModelId`));return}let i=this.buildHeadersFromRows(),a=n.map(e=>this.buildModel(e,i)),o=this.form.apiKey.trim(),c=this.editingProviderId?this.providers.find(e=>e.id===this.editingProviderId):void 0,u={id:this.editingProviderId??oe(),name:e,type:this.form.protocol,baseUrl:a[0].baseUrl,apiKey:o||void 0,models:a};try{let e=s();await e.customProviders.set(u),c&&c.name!==u.name&&await e.providerKeys.delete(c.name),o?await e.providerKeys.set(u.name,o):await e.providerKeys.delete(u.name),this.closeForm(),await this.loadProviders()}catch(e){l.error(`Failed to save custom model:`,e),x(b(`saveCustomModelFailed`))}}async deleteProvider(e){if(await m({description:b(`confirmDeleteProvider`,{name:e.name}),confirmLabel:b(`confirmDelete`),cancelLabel:b(`cancel`),variant:`destructive`}))try{let t=s();await t.customProviders.delete(e.id),await t.providerKeys.delete(e.name),await this.loadProviders()}catch(e){l.error(`Failed to delete custom provider:`,e),x(b(`deleteFailed`))}}renderProvider(e){let t=e.models??[],n=t.length;return a`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/AgentProfilesPage-wpt1cJV0.js","assets/rolldown-runtime-DWdDZTNf.js","assets/index-C_DXqhW8.js","assets/pi-ai-Cx633yhb.js","assets/pi-web-ui-DFNE2m5b.js","assets/lit-vendor-Dr3cpBGF.js","assets/css-utils-rkE68RDy.js","assets/icons-BlAm_pUr.js","assets/react-vendor--m65aOgw.js","assets/skills-dialog-CZ3CuVtQ.js","assets/logger-B65Akg8A.js","assets/index-C3bhHGO4.css","assets/mcp-servers-dialog-DEyq3gmP.js","assets/PluginsPage-0wwQydcP.js","assets/plugin-api-UKg_cgSG.js","assets/ScheduledTasksPage-qGHyGkjw.js"])))=>i.map(i=>d[i]);
2
+ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,B as n,Dt as r,Mt as i,Ot as a,Tt as o,U as s,b as c,dt as l,f as ee,h as te,k as ne,kt as re,l as ie,ot as ae,s as oe,st as se,z as ce}from"./icons-BlAm_pUr.js";import{n as le,r as ue}from"./react-vendor--m65aOgw.js";import{p as u}from"./lit-vendor-Dr3cpBGF.js";import{a as d,u as f}from"./pi-web-ui-DFNE2m5b.js";import{y as p}from"./pi-ai-Cx633yhb.js";import{t as m}from"./logger-B65Akg8A.js";import{$ as de,A as fe,C as h,D as pe,E as g,G as me,H as _,J as he,M as v,S as y,T as ge,U as _e,V as b,X as ve,Y as x,_ as S,b as ye,et as C,g as be,it as w,j as T,k as xe,nt as Se,q as Ce,rt as E,tt as we,v as Te,w as Ee,x as De,y as Oe}from"./index-C_DXqhW8.js";var D=e(i(),1),ke={openai:{name:`OpenAI`,baseUrl:`https://api.openai.com/v1`,protocol:`openai-completions`,modelId:`gpt-4o`},deepseek:{name:`DeepSeek`,baseUrl:`https://api.deepseek.com/v1`,protocol:`openai-completions`,modelId:`deepseek-chat`},glm:{name:`Zhipu GLM`,baseUrl:`https://open.bigmodel.cn/api/paas/v4`,protocol:`openai-completions`,modelId:`glm-4-plus`},ollama:{name:`Ollama`,baseUrl:`http://localhost:11434/v1`,protocol:`openai-completions`,modelId:`llama3.1`},litellm:{name:b.name,baseUrl:b.baseUrl,protocol:`openai-completions`,modelId:b.modelId}},Ae=[{key:`openai`,label:w(`presetOpenai`)},{key:`deepseek`,label:w(`presetDeepseek`)},{key:`glm`,label:w(`presetGlm`)},{key:`ollama`,label:w(`presetOllama`)},{key:`litellm`,label:w(`presetLitellm`)},{key:`custom`,label:w(`presetCustom`)}],O=()=>({modelId:``,contextWindow:b.contextWindow,maxTokens:b.maxTokens,reasoning:!0,open:!1}),k=()=>({name:b.name,baseUrl:b.baseUrl,apiKey:``,headerRows:[],protocol:`openai-completions`,models:[O()]}),je=class extends d{providers=[];form=k();editingProviderId;formOpen=!1;loading=!0;apiKeyVisible=!1;advancedOpen=!1;activePreset=``;testing=!1;testResult=`idle`;testError=``;autoEditProviderName=null;async connectedCallback(){if(super.connectedCallback(),await this.loadProviders(),this.autoEditProviderName){let e=this.providers.find(e=>e.name===this.autoEditProviderName);e&&await this.openEditForm(e),this.autoEditProviderName=null}}getTabName(){return w(`customModels`)}async loadProviders(){this.loading=!0,this.requestUpdate();try{this.providers=await f().customProviders.getAll()}catch(e){m.error(`Failed to load custom providers:`,e),this.providers=[]}finally{this.loading=!1,this.requestUpdate()}}resetTestState(){this.testing=!1,this.testResult=`idle`,this.testError=``}openAddForm(){this.editingProviderId=void 0,this.form=k(),this.apiKeyVisible=!1,this.advancedOpen=!1,this.activePreset=``,this.resetTestState(),this.formOpen=!0,this.requestUpdate()}async openEditForm(e){let t=await f().providerKeys.get(e.name)??e.apiKey??``,n=e.models??[],r=n.length>0?n.map(e=>({modelId:e.id,contextWindow:e.contextWindow??b.contextWindow,maxTokens:e.maxTokens??b.maxTokens,reasoning:e.reasoning===!0,open:!1})):[O()],i=n[0]?.headers??{},a=Object.entries(i).map(([e,t])=>({key:e,value:String(t)}));this.editingProviderId=e.id,this.form={providerId:e.id,id:e.id,name:e.name,baseUrl:e.baseUrl,apiKey:t,headerRows:a,protocol:e.type===`anthropic-messages`?`anthropic-messages`:`openai-completions`,models:r},this.apiKeyVisible=!1,this.advancedOpen=a.length>0||e.type===`anthropic-messages`,this.activePreset=``,this.resetTestState(),this.formOpen=!0,this.requestUpdate()}closeForm(){this.formOpen=!1,this.editingProviderId=void 0,this.form=k(),this.apiKeyVisible=!1,this.advancedOpen=!1,this.activePreset=``,this.resetTestState(),this.requestUpdate()}toggleApiKeyVisibility(){this.apiKeyVisible=!this.apiKeyVisible,this.requestUpdate()}updateForm(e,t){this.form={...this.form,[e]:t},(e===`name`||e===`baseUrl`)&&(this.activePreset=``),this.resetTestState(),this.requestUpdate()}updateModelField(e,t,n){let r=this.form.models.map((r,i)=>i===e?{...r,[t]:n}:r);this.form={...this.form,models:r},t===`modelId`&&(this.activePreset=``,this.resetTestState()),this.requestUpdate()}addModelRow(){this.form={...this.form,models:[...this.form.models,O()]},this.requestUpdate()}removeModelRow(e){let t=this.form.models.filter((t,n)=>n!==e);this.form={...this.form,models:t},this.requestUpdate()}toggleModelExpanded(e){let t=this.form.models.map((t,n)=>n===e?{...t,open:!t.open}:t);this.form={...this.form,models:t},this.requestUpdate()}addHeaderRow(){this.form={...this.form,headerRows:[...this.form.headerRows,{key:``,value:``}]},this.requestUpdate()}updateHeaderRow(e,t,n){let r=this.form.headerRows.map((r,i)=>i===e?{...r,[t]:n}:r);this.form={...this.form,headerRows:r},this.requestUpdate()}removeHeaderRow(e){let t=this.form.headerRows.filter((t,n)=>n!==e);this.form={...this.form,headerRows:t},this.requestUpdate()}applyPreset(e){if(this.activePreset=e,e===`custom`)this.form={...this.form,name:``,baseUrl:``,protocol:`openai-completions`,models:[O()]};else{let t=ke[e];this.form={...this.form,name:t.name,baseUrl:t.baseUrl,protocol:t.protocol,models:[{...O(),modelId:t.modelId,open:!1}]}}this.resetTestState(),this.requestUpdate()}buildHeadersFromRows(){let e={};for(let t of this.form.headerRows){let n=t.key.trim(),r=t.value.trim();n&&r&&(e[n]=r)}return e}buildModel(e,t){let n=this.form.name.trim(),r=this.form.baseUrl.trim(),i=e.reasoning===!0,a=r.includes(`api.deepseek.com`);return Ce({id:e.modelId,name:`${e.modelId} (${n})`,api:this.form.protocol,provider:n,baseUrl:r.replace(/\/$/,``),reasoning:i,input:[`text`,`image`],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:Number(e.contextWindow)||b.contextWindow,maxTokens:Number(e.maxTokens)||b.maxTokens,headers:Object.keys(t).length>0?t:void 0,thinkingLevelMap:a&&i?{low:`high`,medium:`high`,high:`high`,xhigh:`max`}:void 0,compat:this.form.protocol===`openai-completions`?{supportsStore:!1,supportsDeveloperRole:!1,supportsReasoningEffort:i,supportsUsageInStreaming:!1,supportsStrictMode:!1,maxTokensField:`max_tokens`,...a&&i?{requiresReasoningContentOnAssistantMessages:!0,thinkingFormat:`deepseek`}:{}}:void 0})}async testConnection(){let e=this.form.baseUrl.trim(),t=this.form.models.find(e=>e.modelId.trim());if(!e||!t){this.testing=!1,this.testResult=`fail`,this.testError=w(`testRequiresFields`),this.requestUpdate();return}let n=this.buildHeadersFromRows(),r=this.buildModel(t,n);this.testing=!0,this.testResult=`idle`,this.testError=``,this.requestUpdate();try{let e=await(await fetch(`/api/models/test-connection`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({model:r,apiKey:this.form.apiKey.trim()})})).json().catch(()=>({}));e?.ok?(this.testResult=`ok`,this.testError=``):(this.testResult=`fail`,this.testError=e?.error||w(`connectionFailed`))}catch(e){this.testResult=`fail`,this.testError=e?.message||w(`connectionFailed`)}finally{this.testing=!1,this.requestUpdate()}}async saveModel(){let e=this.form.name.trim(),t=this.form.baseUrl.trim();if(!e||!t){T(w(`fillProviderBaseUrlModel`));return}let n=this.form.models.filter(e=>e.modelId.trim());if(n.length===0){T(w(`atLeastOneModel`));return}let r=n.map(e=>e.modelId.trim());if(new Set(r).size!==r.length){T(w(`duplicateModelId`));return}let i=this.buildHeadersFromRows(),a=n.map(e=>this.buildModel(e,i)),o=this.form.apiKey.trim(),s=this.editingProviderId?this.providers.find(e=>e.id===this.editingProviderId):void 0,c={id:this.editingProviderId??ve(),name:e,type:this.form.protocol,baseUrl:a[0].baseUrl,apiKey:o||void 0,models:a};try{let e=f();await e.customProviders.set(c),s&&s.name!==c.name&&await e.providerKeys.delete(s.name),o?await e.providerKeys.set(c.name,o):await e.providerKeys.delete(c.name),this.closeForm(),await this.loadProviders()}catch(e){m.error(`Failed to save custom model:`,e),T(w(`saveCustomModelFailed`))}}async deleteProvider(e){if(await v({description:w(`confirmDeleteProvider`,{name:e.name}),confirmLabel:w(`confirmDelete`),cancelLabel:w(`cancel`),variant:`destructive`}))try{let t=f();await t.customProviders.delete(e.id),await t.providerKeys.delete(e.name),await this.loadProviders()}catch(e){m.error(`Failed to delete custom provider:`,e),T(w(`deleteFailed`))}}renderProvider(e){let t=e.models??[],n=t.length;return u`
3
3
  <div class="rounded-lg border border-border p-4">
4
4
  <div class="flex items-start justify-between gap-4">
5
5
  <div class="min-w-0 flex-1">
6
6
  <div class="text-sm font-medium text-foreground">${e.name}</div>
7
7
  <div class="mt-1 break-all text-xs text-muted-foreground">${e.baseUrl}</div>
8
8
  <div class="mt-2 text-xs text-muted-foreground">
9
- ${b(`providerProtocol`)}: ${e.type===`anthropic-messages`?`Anthropic Messages`:`OpenAI Compatible`}
9
+ ${w(`providerProtocol`)}: ${e.type===`anthropic-messages`?`Anthropic Messages`:`OpenAI Compatible`}
10
10
  </div>
11
- ${n===0?a`<div class="mt-1 text-xs text-muted-foreground">${b(`noModelAdded`)}</div>`:a`
12
- <div class="mt-2 text-xs text-muted-foreground">${b(`modelsCount`,{count:n})}</div>
11
+ ${n===0?u`<div class="mt-1 text-xs text-muted-foreground">${w(`noModelAdded`)}</div>`:u`
12
+ <div class="mt-2 text-xs text-muted-foreground">${w(`modelsCount`,{count:n})}</div>
13
13
  <div class="mt-1 flex flex-wrap gap-1">
14
- ${t.map(e=>a`
14
+ ${t.map(e=>u`
15
15
  <span class="inline-flex items-center gap-1 rounded-md border border-border bg-muted px-2 py-0.5 text-xs text-foreground">
16
16
  <span class="font-medium">${e.id}</span>
17
17
  <span class="text-muted-foreground">${e.contextWindow}/${e.maxTokens}</span>
@@ -26,23 +26,23 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
26
26
  type="button"
27
27
  @click=${()=>this.openEditForm(e)}
28
28
  >
29
- ${b(`editModel`)}
29
+ ${w(`editModel`)}
30
30
  </button>
31
31
  <button
32
32
  class="rounded-md px-3 py-1.5 text-sm text-destructive hover:bg-secondary"
33
33
  type="button"
34
34
  @click=${()=>this.deleteProvider(e)}
35
35
  >
36
- ${b(`delete`)}
36
+ ${w(`delete`)}
37
37
  </button>
38
38
  </div>
39
39
  </div>
40
40
  </div>
41
- `}renderPresetChips(){return a`
41
+ `}renderPresetChips(){return u`
42
42
  <div class="grid gap-1.5">
43
- <span class="text-xs text-muted-foreground">${b(`presets`)}</span>
43
+ <span class="text-xs text-muted-foreground">${w(`presets`)}</span>
44
44
  <div class="flex flex-wrap gap-1.5">
45
- ${ve.map(e=>a`
45
+ ${Ae.map(e=>u`
46
46
  <button
47
47
  class="rounded-full border px-3 py-1 text-xs ${this.activePreset===e.key?`border-primary bg-primary text-primary-foreground`:`border-border text-muted-foreground hover:border-foreground/40 hover:text-foreground`}"
48
48
  type="button"
@@ -53,13 +53,13 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
53
53
  `)}
54
54
  </div>
55
55
  </div>
56
- `}renderModelRow(e,t){let n=e.open===!0;return a`
56
+ `}renderModelRow(e,t){let n=e.open===!0;return u`
57
57
  <div class="rounded-md border border-border">
58
58
  <div class="flex items-center gap-2 p-2">
59
59
  <button
60
60
  class="shrink-0 inline-flex size-6 items-center justify-center rounded text-xs text-muted-foreground hover:bg-secondary hover:text-foreground"
61
61
  type="button"
62
- title=${b(`expandModel`)}
62
+ title=${w(`expandModel`)}
63
63
  aria-expanded=${n?`true`:`false`}
64
64
  @click=${()=>this.toggleModelExpanded(t)}
65
65
  >
@@ -69,24 +69,24 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
69
69
  class="min-w-0 flex-1 rounded-md border border-input bg-background px-3 py-1.5 text-sm"
70
70
  .value=${e.modelId}
71
71
  @input=${e=>this.updateModelField(t,`modelId`,e.target.value)}
72
- placeholder=${b(`modelIdPlaceholder`)}
72
+ placeholder=${w(`modelIdPlaceholder`)}
73
73
  />
74
- ${this.form.models.length>1?a`
74
+ ${this.form.models.length>1?u`
75
75
  <button
76
76
  class="shrink-0 rounded px-1.5 py-0.5 text-xs text-muted-foreground hover:bg-secondary hover:text-destructive"
77
77
  type="button"
78
- title=${b(`delete`)}
78
+ title=${w(`delete`)}
79
79
  @click=${()=>this.removeModelRow(t)}
80
80
  >
81
81
 
82
82
  </button>
83
83
  `:``}
84
84
  </div>
85
- ${n?a`
85
+ ${n?u`
86
86
  <div class="grid gap-3 border-t border-border p-3">
87
87
  <div class="grid grid-cols-2 gap-3">
88
88
  <label class="grid gap-1 text-xs">
89
- <span class="text-muted-foreground">${b(`contextWindow`)}</span>
89
+ <span class="text-muted-foreground">${w(`contextWindow`)}</span>
90
90
  <input
91
91
  class="rounded-md border border-input bg-background px-3 py-1.5 text-sm"
92
92
  .value=${String(e.contextWindow)}
@@ -95,7 +95,7 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
95
95
  />
96
96
  </label>
97
97
  <label class="grid gap-1 text-xs">
98
- <span class="text-muted-foreground">${b(`maxTokens`)}</span>
98
+ <span class="text-muted-foreground">${w(`maxTokens`)}</span>
99
99
  <input
100
100
  class="rounded-md border border-input bg-background px-3 py-1.5 text-sm"
101
101
  .value=${String(e.maxTokens)}
@@ -111,37 +111,37 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
111
111
  .checked=${e.reasoning}
112
112
  @change=${e=>this.updateModelField(t,`reasoning`,e.target.checked)}
113
113
  />
114
- <span class="text-muted-foreground">${b(`reasoningModel`)}</span>
114
+ <span class="text-muted-foreground">${w(`reasoningModel`)}</span>
115
115
  </label>
116
116
  </div>
117
117
  `:``}
118
118
  </div>
119
- `}renderHeadersEditor(){return a`
119
+ `}renderHeadersEditor(){return u`
120
120
  <div class="grid gap-1.5">
121
121
  <span class="inline-flex items-center gap-1.5 text-xs text-muted-foreground">
122
- ${b(`customHeaders`)}
123
- <quickforge-info-tip .label=${b(`customHeadersHelp`)}></quickforge-info-tip>
122
+ ${w(`customHeaders`)}
123
+ <quickforge-info-tip .label=${w(`customHeadersHelp`)}></quickforge-info-tip>
124
124
  </span>
125
- ${this.form.headerRows.length===0?a``:a`
125
+ ${this.form.headerRows.length===0?u``:u`
126
126
  <div class="grid gap-2">
127
- ${this.form.headerRows.map((e,t)=>a`
127
+ ${this.form.headerRows.map((e,t)=>u`
128
128
  <div class="grid grid-cols-[1fr_1fr_auto] items-center gap-2">
129
129
  <input
130
130
  class="rounded-md border border-input bg-background px-3 py-1.5 text-sm"
131
131
  .value=${e.key}
132
132
  @input=${e=>this.updateHeaderRow(t,`key`,e.target.value)}
133
- placeholder=${b(`headerName`)}
133
+ placeholder=${w(`headerName`)}
134
134
  />
135
135
  <input
136
136
  class="rounded-md border border-input bg-background px-3 py-1.5 text-sm"
137
137
  .value=${e.value}
138
138
  @input=${e=>this.updateHeaderRow(t,`value`,e.target.value)}
139
- placeholder=${b(`headerValue`)}
139
+ placeholder=${w(`headerValue`)}
140
140
  />
141
141
  <button
142
142
  class="shrink-0 rounded px-1.5 py-1.5 text-xs text-muted-foreground hover:bg-secondary hover:text-destructive"
143
143
  type="button"
144
- title=${b(`removeHeader`)}
144
+ title=${w(`removeHeader`)}
145
145
  @click=${()=>this.removeHeaderRow(t)}
146
146
  >
147
147
 
@@ -155,25 +155,25 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
155
155
  type="button"
156
156
  @click=${()=>this.addHeaderRow()}
157
157
  >
158
- + ${b(`addHeader`)}
158
+ + ${w(`addHeader`)}
159
159
  </button>
160
160
  </div>
161
- `}renderTestStatus(){return this.testResult===`idle`&&!this.testing?a``:this.testing?a`<span class="text-xs text-muted-foreground">${b(`testingConnection`)}</span>`:this.testResult===`ok`?a`<span class="text-xs text-green-600">✓ ${b(`connectionOk`)}</span>`:a`<span class="break-all text-xs text-destructive">✗ ${this.testError||b(`connectionFailed`)}</span>`}renderForm(){return a`
161
+ `}renderTestStatus(){return this.testResult===`idle`&&!this.testing?u``:this.testing?u`<span class="text-xs text-muted-foreground">${w(`testingConnection`)}</span>`:this.testResult===`ok`?u`<span class="text-xs text-green-600">✓ ${w(`connectionOk`)}</span>`:u`<span class="break-all text-xs text-destructive">✗ ${this.testError||w(`connectionFailed`)}</span>`}renderForm(){return u`
162
162
  <div class="rounded-lg border border-border p-4">
163
163
  <div class="mb-4 text-sm font-semibold text-foreground">
164
- ${this.editingProviderId?b(`editCustomModel`):b(`addCustomModel`)}
164
+ ${this.editingProviderId?w(`editCustomModel`):w(`addCustomModel`)}
165
165
  </div>
166
166
 
167
167
  <div class="grid gap-4">
168
168
  ${this.renderPresetChips()}
169
169
 
170
170
  <label class="grid gap-1.5 text-sm">
171
- <span class="text-foreground">${b(`providerName`)}</span>
171
+ <span class="text-foreground">${w(`providerName`)}</span>
172
172
  <input
173
173
  class="rounded-md border border-input bg-background px-3 py-2 text-sm"
174
174
  .value=${this.form.name}
175
175
  @input=${e=>this.updateForm(`name`,e.target.value)}
176
- placeholder=${b(`providerNamePlaceholder`)}
176
+ placeholder=${w(`providerNamePlaceholder`)}
177
177
  />
178
178
  </label>
179
179
 
@@ -188,37 +188,37 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
188
188
  </label>
189
189
 
190
190
  <label class="grid gap-1.5 text-sm">
191
- <span class="text-foreground">${b(`apiKey`)}</span>
191
+ <span class="text-foreground">${w(`apiKey`)}</span>
192
192
  <div class="relative">
193
193
  <input
194
194
  class="w-full rounded-md border border-input bg-background px-3 py-2 pr-10 text-sm"
195
195
  .value=${this.form.apiKey}
196
196
  type=${this.apiKeyVisible?`text`:`password`}
197
197
  @input=${e=>this.updateForm(`apiKey`,e.target.value)}
198
- placeholder=${b(`apiKeyPlaceholder`)}
198
+ placeholder=${w(`apiKeyPlaceholder`)}
199
199
  />
200
200
  <button
201
201
  class="absolute inset-y-0 right-0 flex w-10 items-center justify-center rounded-r-md text-muted-foreground hover:text-foreground/85 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
202
202
  type="button"
203
- title=${this.apiKeyVisible?b(`hideApiKey`):b(`showApiKey`)}
204
- aria-label=${this.apiKeyVisible?b(`hideApiKey`):b(`showApiKey`)}
203
+ title=${this.apiKeyVisible?w(`hideApiKey`):w(`showApiKey`)}
204
+ aria-label=${this.apiKeyVisible?w(`hideApiKey`):w(`showApiKey`)}
205
205
  aria-pressed=${this.apiKeyVisible?`true`:`false`}
206
206
  @click=${()=>this.toggleApiKeyVisibility()}
207
207
  >
208
- ${this.apiKeyVisible?a`<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68"/><path d="M6.61 6.61A13.53 13.53 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61"/><line x1="2" y1="2" x2="22" y2="22"/><path d="M8.53 8.53A5 5 0 0 0 12 17a5 5 0 0 0 3.47-8.53"/></svg>`:a`<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg>`}
208
+ ${this.apiKeyVisible?u`<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68"/><path d="M6.61 6.61A13.53 13.53 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61"/><line x1="2" y1="2" x2="22" y2="22"/><path d="M8.53 8.53A5 5 0 0 0 12 17a5 5 0 0 0 3.47-8.53"/></svg>`:u`<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg>`}
209
209
  </button>
210
210
  </div>
211
211
  </label>
212
212
 
213
213
  <div class="grid gap-2">
214
214
  <div class="flex items-center justify-between">
215
- <span class="text-sm font-medium text-foreground">${b(`modelsList`)}</span>
215
+ <span class="text-sm font-medium text-foreground">${w(`modelsList`)}</span>
216
216
  <button
217
217
  class="rounded-md px-2 py-1 text-xs hover:bg-secondary"
218
218
  type="button"
219
219
  @click=${()=>this.addModelRow()}
220
220
  >
221
- + ${b(`addModel`)}
221
+ + ${w(`addModel`)}
222
222
  </button>
223
223
  </div>
224
224
  ${this.form.models.map((e,t)=>this.renderModelRow(e,t))}
@@ -231,15 +231,15 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
231
231
  @click=${()=>{this.advancedOpen=!this.advancedOpen,this.requestUpdate()}}
232
232
  >
233
233
  <span>${this.advancedOpen?`▾`:`▸`}</span>
234
- ${b(`providerAdvanced`)}
234
+ ${w(`providerAdvanced`)}
235
235
  </button>
236
236
 
237
- ${this.advancedOpen?a`
237
+ ${this.advancedOpen?u`
238
238
  <div class="grid gap-4 rounded-md border border-border p-3">
239
239
  <label class="grid gap-1.5 text-sm">
240
240
  <span class="inline-flex items-center gap-1.5 text-foreground">
241
- ${b(`protocolType`)}
242
- <quickforge-info-tip .label=${b(`protocolHelp`)}></quickforge-info-tip>
241
+ ${w(`protocolType`)}
242
+ <quickforge-info-tip .label=${w(`protocolHelp`)}></quickforge-info-tip>
243
243
  </span>
244
244
  <select
245
245
  class="rounded-md border border-input bg-background px-3 py-2 text-sm"
@@ -262,7 +262,7 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
262
262
  type="button"
263
263
  @click=${()=>this.closeForm()}
264
264
  >
265
- ${b(`cancel`)}
265
+ ${w(`cancel`)}
266
266
  </button>
267
267
  <button
268
268
  class="rounded-md px-3 py-2 text-sm hover:bg-secondary ${this.testing?`opacity-50 pointer-events-none`:``}"
@@ -270,24 +270,24 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
270
270
  ?disabled=${this.testing}
271
271
  @click=${()=>this.testConnection()}
272
272
  >
273
- ${b(`testConnection`)}
273
+ ${w(`testConnection`)}
274
274
  </button>
275
275
  <button
276
276
  class="rounded-md bg-primary px-3 py-2 text-sm text-primary-foreground"
277
277
  type="button"
278
278
  @click=${()=>this.saveModel()}
279
279
  >
280
- ${b(`save`)}
280
+ ${w(`save`)}
281
281
  </button>
282
282
  </div>
283
283
  </div>
284
- `}render(){return a`
284
+ `}render(){return u`
285
285
  <div class="flex flex-col gap-6">
286
286
  <div class="flex items-center justify-between gap-4">
287
287
  <div>
288
288
  <h3 class="mb-2 inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
289
- ${b(`customModelsTitle`)}
290
- <quickforge-info-tip .label=${b(`customModelsDescription`)}></quickforge-info-tip>
289
+ ${w(`customModelsTitle`)}
290
+ <quickforge-info-tip .label=${w(`customModelsDescription`)}></quickforge-info-tip>
291
291
  </h3>
292
292
  </div>
293
293
  <button
@@ -295,32 +295,32 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
295
295
  type="button"
296
296
  @click=${()=>this.openAddForm()}
297
297
  >
298
- ${b(`addModel`)}
298
+ ${w(`addModel`)}
299
299
  </button>
300
300
  </div>
301
301
 
302
302
  ${this.formOpen?this.renderForm():``}
303
303
 
304
- ${this.loading?a`<div class="py-8 text-center text-sm text-muted-foreground">${b(`loading`)}</div>`:this.providers.length===0?a`<div class="py-8 text-center text-sm text-muted-foreground">${b(`noCustomModels`)}</div>`:a`<div class="flex flex-col gap-3">${this.providers.map(e=>this.renderProvider(e))}</div>`}
304
+ ${this.loading?u`<div class="py-8 text-center text-sm text-muted-foreground">${w(`loading`)}</div>`:this.providers.length===0?u`<div class="py-8 text-center text-sm text-muted-foreground">${w(`noCustomModels`)}</div>`:u`<div class="flex flex-col gap-3">${this.providers.map(e=>this.renderProvider(e))}</div>`}
305
305
  </div>
306
- `}},E=`quickforge-custom-providers-only-tab`;customElements.get(E)||customElements.define(E,ye);function be(e){let t=document.createElement(E);return e&&(t.autoEditProviderName=e),t}var xe=class extends o{selectedLanguage=ue();getTabName(){return b(`language`)}updateLanguage(e){this.selectedLanguage=e===`zh`?`zh`:`en`,this.requestUpdate()}async applyLanguage(){await fe(s(),this.selectedLanguage)||x(b(`noLanguageChange`))}render(){return a`
306
+ `}},A=`quickforge-custom-providers-only-tab`;customElements.get(A)||customElements.define(A,je);function Me(e){let t=document.createElement(A);return e&&(t.autoEditProviderName=e),t}var Ne=class extends d{selectedLanguage=Se();getTabName(){return w(`language`)}updateLanguage(e){this.selectedLanguage=e===`zh`?`zh`:`en`,this.requestUpdate()}async applyLanguage(){await we(f(),this.selectedLanguage)||T(w(`noLanguageChange`))}render(){return u`
307
307
  <div class="flex flex-col gap-6">
308
308
  <div>
309
309
  <h3 class="mb-2 inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
310
- ${b(`language`)}
311
- <quickforge-info-tip .label=${b(`languageDescription`)}></quickforge-info-tip>
310
+ ${w(`language`)}
311
+ <quickforge-info-tip .label=${w(`languageDescription`)}></quickforge-info-tip>
312
312
  </h3>
313
313
  </div>
314
314
 
315
315
  <label class="grid max-w-sm gap-1.5 text-sm">
316
- <span class="text-foreground">${b(`displayLanguage`)}</span>
316
+ <span class="text-foreground">${w(`displayLanguage`)}</span>
317
317
  <select
318
318
  class="rounded-md border border-input bg-background px-3 py-2 text-sm"
319
319
  .value=${this.selectedLanguage}
320
320
  @change=${e=>this.updateLanguage(e.target.value)}
321
321
  >
322
- <option value="zh">${b(`simplifiedChinese`)}</option>
323
- <option value="en">${b(`english`)}</option>
322
+ <option value="zh">${w(`simplifiedChinese`)}</option>
323
+ <option value="en">${w(`english`)}</option>
324
324
  </select>
325
325
  </label>
326
326
 
@@ -330,11 +330,11 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
330
330
  type="button"
331
331
  @click=${()=>this.applyLanguage()}
332
332
  >
333
- ${b(`apply`)}
333
+ ${w(`apply`)}
334
334
  </button>
335
335
  </div>
336
336
  </div>
337
- `}},D=`quickforge-language-settings-tab`;customElements.get(D)||customElements.define(D,xe);function Se(){return document.createElement(D)}var Ce=[{value:`light`,label:()=>b(`lightTheme`)},{value:`dark`,label:()=>b(`darkTheme`)}],we=class extends o{theme=ge();interfaceFontSizePx=h.interfaceFontSizePx;messageFontSizePx=h.messageFontSizePx;loading=!0;error=``;getTabName(){return b(`appearance`)}async connectedCallback(){super.connectedCallback(),await this.loadSettings()}async loadSettings(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=s(),[t,n]=await Promise.all([se(e),ie(e)]);this.theme=t.theme,this.interfaceFontSizePx=n.interfaceFontSizePx,this.messageFontSizePx=n.messageFontSizePx}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}async selectTheme(e){if(this.theme!==e){this.theme=e,this.requestUpdate();try{await he(s(),{theme:e}),this.error=``,this.requestUpdate()}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`),this.requestUpdate()}}}currentFontSizeSettings(){return f({interfaceFontSizePx:this.interfaceFontSizePx,messageFontSizePx:this.messageFontSizePx})}previewFontSize(e){let t=f(e);this.interfaceFontSizePx=t.interfaceFontSizePx,this.messageFontSizePx=t.messageFontSizePx,me(t),this.requestUpdate()}updateInterfaceFontSize(e){this.previewFontSize({...this.currentFontSizeSettings(),interfaceFontSizePx:Number(e)||h.interfaceFontSizePx})}updateMessageFontSize(e){this.previewFontSize({...this.currentFontSizeSettings(),messageFontSizePx:Number(e)||h.messageFontSizePx})}async saveFontSize(){try{await te(s(),this.currentFontSizeSettings()),this.error=``,this.requestUpdate()}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`),this.requestUpdate()}}renderThemeOption(e){let t=this.theme===e.value,n=e.value===`dark`;return a`
337
+ `}},j=`quickforge-language-settings-tab`;customElements.get(j)||customElements.define(j,Ne);function Pe(){return document.createElement(j)}var Fe=[{value:`light`,label:()=>w(`lightTheme`)},{value:`dark`,label:()=>w(`darkTheme`)}],Ie=class extends d{theme=Oe();interfaceFontSizePx=y.interfaceFontSizePx;messageFontSizePx=y.messageFontSizePx;loading=!0;error=``;getTabName(){return w(`appearance`)}async connectedCallback(){super.connectedCallback(),await this.loadSettings()}async loadSettings(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=f(),[t,n]=await Promise.all([ye(e),ge(e)]);this.theme=t.theme,this.interfaceFontSizePx=n.interfaceFontSizePx,this.messageFontSizePx=n.messageFontSizePx}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}async selectTheme(e){if(this.theme!==e){this.theme=e,this.requestUpdate();try{await De(f(),{theme:e}),this.error=``,this.requestUpdate()}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`),this.requestUpdate()}}}currentFontSizeSettings(){return g({interfaceFontSizePx:this.interfaceFontSizePx,messageFontSizePx:this.messageFontSizePx})}previewFontSize(e){let t=g(e);this.interfaceFontSizePx=t.interfaceFontSizePx,this.messageFontSizePx=t.messageFontSizePx,Ee(t),this.requestUpdate()}updateInterfaceFontSize(e){this.previewFontSize({...this.currentFontSizeSettings(),interfaceFontSizePx:Number(e)||y.interfaceFontSizePx})}updateMessageFontSize(e){this.previewFontSize({...this.currentFontSizeSettings(),messageFontSizePx:Number(e)||y.messageFontSizePx})}async saveFontSize(){try{await pe(f(),this.currentFontSizeSettings()),this.error=``,this.requestUpdate()}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`),this.requestUpdate()}}renderThemeOption(e){let t=this.theme===e.value,n=e.value===`dark`;return u`
338
338
  <button
339
339
  type="button"
340
340
  class="group flex flex-col gap-2 rounded-lg border p-3 text-left transition-colors ${t?`border-primary ring-1 ring-primary`:`border-border hover:border-foreground/30`}"
@@ -355,7 +355,7 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
355
355
  <span
356
356
  class="flex size-4 items-center justify-center rounded-full border ${t?`border-primary bg-primary`:`border-muted-foreground/40`}"
357
357
  >
358
- ${t?a`<svg class="size-3 text-primary-foreground" viewBox="0 0 12 12" fill="none">
358
+ ${t?u`<svg class="size-3 text-primary-foreground" viewBox="0 0 12 12" fill="none">
359
359
  <path
360
360
  d="M2.5 6l2.5 2.5 4.5-5"
361
361
  stroke="currentColor"
@@ -367,12 +367,12 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
367
367
  </span>
368
368
  </div>
369
369
  </button>
370
- `}getFontSizeRangeProgress(e){return(e-d.min)/(d.max-d.min)*100}renderFontSizeSlider(e,t,n,r){return a`
370
+ `}getFontSizeRangeProgress(e){return(e-h.min)/(h.max-h.min)*100}renderFontSizeSlider(e,t,n,r){return u`
371
371
  <label class="grid gap-2 text-sm">
372
372
  <div class="flex items-center justify-between gap-3">
373
373
  <span class="inline-flex items-center gap-1.5 text-foreground">
374
374
  ${e}
375
- ${t?a`<quickforge-info-tip .label=${t}></quickforge-info-tip>`:null}
375
+ ${t?u`<quickforge-info-tip .label=${t}></quickforge-info-tip>`:null}
376
376
  </span>
377
377
  <span class="rounded-md bg-muted px-2 py-0.5 font-mono text-xs text-foreground">${n}px</span>
378
378
  </div>
@@ -380,79 +380,79 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
380
380
  class="quickforge-font-size-slider w-full"
381
381
  style=${`--quickforge-font-size-slider-progress: ${this.getFontSizeRangeProgress(n)}%`}
382
382
  type="range"
383
- min=${String(d.min)}
384
- max=${String(d.max)}
383
+ min=${String(h.min)}
384
+ max=${String(h.max)}
385
385
  step="1"
386
386
  .value=${String(n)}
387
387
  @input=${e=>r(e.target.value)}
388
388
  @change=${()=>this.saveFontSize()}
389
389
  />
390
390
  <div class="flex justify-between text-xs text-muted-foreground">
391
- <span>${d.min}px</span>
392
- <span>${d.max}px</span>
391
+ <span>${h.min}px</span>
392
+ <span>${h.max}px</span>
393
393
  </div>
394
394
  </label>
395
- `}render(){return this.loading?a`<div class="text-sm text-muted-foreground">${b(`loading`)}</div>`:a`
395
+ `}render(){return this.loading?u`<div class="text-sm text-muted-foreground">${w(`loading`)}</div>`:u`
396
396
  <div class="flex flex-col gap-6">
397
397
  <div>
398
398
  <h3 class="mb-2 inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
399
- ${b(`appearance`)}
400
- <quickforge-info-tip .label=${b(`appearanceDescription`)}></quickforge-info-tip>
399
+ ${w(`appearance`)}
400
+ <quickforge-info-tip .label=${w(`appearanceDescription`)}></quickforge-info-tip>
401
401
  </h3>
402
402
  </div>
403
403
 
404
404
  <div class="grid max-w-xl gap-3 rounded-lg border border-border p-4">
405
405
  <div>
406
406
  <h4 class="inline-flex items-center gap-1.5 text-sm font-medium text-foreground">
407
- ${b(`theme`)}
408
- <quickforge-info-tip .label=${b(`themeDescription`)}></quickforge-info-tip>
407
+ ${w(`theme`)}
408
+ <quickforge-info-tip .label=${w(`themeDescription`)}></quickforge-info-tip>
409
409
  </h4>
410
410
  </div>
411
411
  <div class="grid grid-cols-2 gap-3">
412
- ${Ce.map(e=>this.renderThemeOption(e))}
412
+ ${Fe.map(e=>this.renderThemeOption(e))}
413
413
  </div>
414
414
  </div>
415
415
 
416
416
  <div class="grid max-w-xl gap-4 rounded-lg border border-border p-4">
417
417
  <div>
418
418
  <h4 class="inline-flex items-center gap-1.5 text-sm font-medium text-foreground">
419
- ${b(`fontSize`)}
420
- <quickforge-info-tip .label=${b(`fontSizeDescription`)}></quickforge-info-tip>
419
+ ${w(`fontSize`)}
420
+ <quickforge-info-tip .label=${w(`fontSizeDescription`)}></quickforge-info-tip>
421
421
  </h4>
422
422
  </div>
423
423
 
424
- ${this.renderFontSizeSlider(b(`interfaceFontSize`),null,this.interfaceFontSizePx,e=>this.updateInterfaceFontSize(e))}
424
+ ${this.renderFontSizeSlider(w(`interfaceFontSize`),null,this.interfaceFontSizePx,e=>this.updateInterfaceFontSize(e))}
425
425
 
426
- ${this.renderFontSizeSlider(b(`messageFontSize`),b(`messageFontSizeNote`),this.messageFontSizePx,e=>this.updateMessageFontSize(e))}
426
+ ${this.renderFontSizeSlider(w(`messageFontSize`),w(`messageFontSizeNote`),this.messageFontSizePx,e=>this.updateMessageFontSize(e))}
427
427
  </div>
428
428
 
429
- ${this.error?a`<span class="text-sm text-destructive">${this.error}</span>`:null}
429
+ ${this.error?u`<span class="text-sm text-destructive">${this.error}</span>`:null}
430
430
  </div>
431
- `}},O=`quickforge-appearance-settings-tab`;customElements.get(O)||customElements.define(O,we);function k(){return document.createElement(O)}var A=`auto-compact-settings`,j={enabled:!1,thresholdPercent:80,keepRecentTurns:3,minSourceChars:1600,requireConfirmation:!0};function M(e,t,n,r){let i=Number(e);return Number.isFinite(i)?Math.min(r,Math.max(n,Math.round(i))):t}function N(e){if(!e||typeof e!=`object`)return{...j};let t=e;return{enabled:t.enabled===!0,thresholdPercent:M(t.thresholdPercent,j.thresholdPercent,50,95),keepRecentTurns:M(t.keepRecentTurns,j.keepRecentTurns,1,20),minSourceChars:M(t.minSourceChars,j.minSourceChars,0,2e5),requireConfirmation:t.requireConfirmation!==!1}}async function Te(e){return N(await e.settings.get(A))}async function Ee(e,t){await e.settings.set(A,N(t))}var P=[{value:`off`,label:()=>b(`thinkingOff`)},{value:`low`,label:()=>b(`thinkingLow`)},{value:`medium`,label:()=>b(`thinkingMedium`)},{value:`high`,label:()=>b(`thinkingHigh`)},{value:`xhigh`,label:()=>b(`thinkingXHigh`)}];function De(e){return(e??``).trim().replace(/\/$/,``)}function F(e){return JSON.stringify([e.provider,e.id,e.api,De(e.baseUrl)])}function Oe(e){return`${e.provider} / ${e.id}`}var ke=class extends o{models=[];selectedModel;thinkingLevel=`off`;showToolDetails=!1;expandToolsByDefault=!1;autoCompactEnabled=!1;autoCompactRequireConfirmation=!0;autoCompactThresholdPercent=80;autoCompactThresholdPercentInput=`80`;autoCompactKeepRecentTurns=3;loading=!0;saved=!1;error=``;getTabName(){return b(`defaultOptions`)}async connectedCallback(){super.connectedCallback(),await this.loadSettings()}updated(){this.syncSelectValues()}syncSelectValues(){let e=this.querySelector(`[data-default-model-select]`);e&&this.selectedModel&&(e.value=F(this.selectedModel));let t=this.querySelector(`[data-default-thinking-select]`);t&&(t.value=this.thinkingLevel)}async loadSettings(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=s(),[t,n,r,i]=await Promise.all([ae(e),ne(e),le(e),Te(e)]);this.models=t,this.selectedModel=n.model?t.find(e=>F(e)===F(n.model))??n.model:t[0],this.thinkingLevel=n.thinkingLevel??p(this.selectedModel),this.showToolDetails=r.showToolDetails,this.expandToolsByDefault=r.expandToolsByDefault,this.autoCompactEnabled=i.enabled,this.autoCompactRequireConfirmation=i.requireConfirmation,this.autoCompactThresholdPercent=i.thresholdPercent,this.autoCompactThresholdPercentInput=String(i.thresholdPercent),this.autoCompactKeepRecentTurns=i.keepRecentTurns}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}updateModel(e){let t=this.models.find(t=>F(t)===e);this.selectedModel=t,this.thinkingLevel=p(t),this.saved=!1,this.requestUpdate()}updateThinkingLevel(e){this.thinkingLevel=P.some(t=>t.value===e)?e:`off`,this.saved=!1,this.requestUpdate()}updateShowToolDetails(e){this.showToolDetails=e,this.saved=!1,this.requestUpdate()}updateExpandToolsByDefault(e){this.expandToolsByDefault=e,this.saved=!1,this.requestUpdate()}updateAutoCompactEnabled(e){this.autoCompactEnabled=e,this.saved=!1,this.requestUpdate()}updateAutoCompactRequireConfirmation(e){this.autoCompactRequireConfirmation=e,this.saved=!1,this.requestUpdate()}updateAutoCompactThresholdPercent(e){this.autoCompactThresholdPercentInput=e;let t=Number(e);e!==``&&Number.isFinite(t)&&(this.autoCompactThresholdPercent=t),this.saved=!1,this.requestUpdate()}updateAutoCompactKeepRecentTurns(e){this.autoCompactKeepRecentTurns=Number(e)||3,this.saved=!1,this.requestUpdate()}modelOptions(){if(!this.selectedModel)return this.models;let e=F(this.selectedModel);return this.models.some(t=>F(t)===e)?this.models:[this.selectedModel,...this.models]}async save(){try{let e=this.selectedModel?.reasoning?this.thinkingLevel:`off`;await re(s(),{model:this.selectedModel,thinkingLevel:e}),await ee(s(),{showToolDetails:this.showToolDetails,expandToolsByDefault:this.expandToolsByDefault}),await Ee(s(),{enabled:this.autoCompactEnabled,thresholdPercent:this.autoCompactThresholdPercent,keepRecentTurns:this.autoCompactKeepRecentTurns,minSourceChars:1600,requireConfirmation:this.autoCompactRequireConfirmation}),await this.loadSettings(),this.saved=!0,this.error=``,this.requestUpdate()}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`),this.requestUpdate()}}render(){return this.loading?a`<div class="text-sm text-muted-foreground">${b(`loading`)}</div>`:a`
431
+ `}},M=`quickforge-appearance-settings-tab`;customElements.get(M)||customElements.define(M,Ie);function Le(){return document.createElement(M)}var N=`auto-compact-settings`,P={enabled:!1,thresholdPercent:80,keepRecentTurns:3,minSourceChars:1600,requireConfirmation:!0};function F(e,t,n,r){let i=Number(e);return Number.isFinite(i)?Math.min(r,Math.max(n,Math.round(i))):t}function I(e){if(!e||typeof e!=`object`)return{...P};let t=e;return{enabled:t.enabled===!0,thresholdPercent:F(t.thresholdPercent,P.thresholdPercent,50,95),keepRecentTurns:F(t.keepRecentTurns,P.keepRecentTurns,1,20),minSourceChars:F(t.minSourceChars,P.minSourceChars,0,2e5),requireConfirmation:t.requireConfirmation!==!1}}async function Re(e){return I(await e.settings.get(N))}async function ze(e,t){await e.settings.set(N,I(t))}var L=[{value:`off`,label:()=>w(`thinkingOff`)},{value:`low`,label:()=>w(`thinkingLow`)},{value:`medium`,label:()=>w(`thinkingMedium`)},{value:`high`,label:()=>w(`thinkingHigh`)},{value:`xhigh`,label:()=>w(`thinkingXHigh`)}];function Be(e){return(e??``).trim().replace(/\/$/,``)}function R(e){return JSON.stringify([e.provider,e.id,e.api,Be(e.baseUrl)])}function Ve(e){return`${e.provider} / ${e.id}`}var He=class extends d{models=[];selectedModel;thinkingLevel=`off`;showToolDetails=!1;expandToolsByDefault=!1;autoCompactEnabled=!1;autoCompactRequireConfirmation=!0;autoCompactThresholdPercent=80;autoCompactThresholdPercentInput=`80`;autoCompactKeepRecentTurns=3;loading=!0;saved=!1;error=``;getTabName(){return w(`defaultOptions`)}async connectedCallback(){super.connectedCallback(),await this.loadSettings()}updated(){this.syncSelectValues()}syncSelectValues(){let e=this.querySelector(`[data-default-model-select]`);e&&this.selectedModel&&(e.value=R(this.selectedModel));let t=this.querySelector(`[data-default-thinking-select]`);t&&(t.value=this.thinkingLevel)}async loadSettings(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=f(),[t,n,r,i]=await Promise.all([_e(e),me(e),xe(e),Re(e)]);this.models=t,this.selectedModel=n.model?t.find(e=>R(e)===R(n.model))??n.model:t[0],this.thinkingLevel=n.thinkingLevel??_(this.selectedModel),this.showToolDetails=r.showToolDetails,this.expandToolsByDefault=r.expandToolsByDefault,this.autoCompactEnabled=i.enabled,this.autoCompactRequireConfirmation=i.requireConfirmation,this.autoCompactThresholdPercent=i.thresholdPercent,this.autoCompactThresholdPercentInput=String(i.thresholdPercent),this.autoCompactKeepRecentTurns=i.keepRecentTurns}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}updateModel(e){let t=this.models.find(t=>R(t)===e);this.selectedModel=t,this.thinkingLevel=_(t),this.saved=!1,this.requestUpdate()}updateThinkingLevel(e){this.thinkingLevel=L.some(t=>t.value===e)?e:`off`,this.saved=!1,this.requestUpdate()}updateShowToolDetails(e){this.showToolDetails=e,this.saved=!1,this.requestUpdate()}updateExpandToolsByDefault(e){this.expandToolsByDefault=e,this.saved=!1,this.requestUpdate()}updateAutoCompactEnabled(e){this.autoCompactEnabled=e,this.saved=!1,this.requestUpdate()}updateAutoCompactRequireConfirmation(e){this.autoCompactRequireConfirmation=e,this.saved=!1,this.requestUpdate()}updateAutoCompactThresholdPercent(e){this.autoCompactThresholdPercentInput=e;let t=Number(e);e!==``&&Number.isFinite(t)&&(this.autoCompactThresholdPercent=t),this.saved=!1,this.requestUpdate()}updateAutoCompactKeepRecentTurns(e){this.autoCompactKeepRecentTurns=Number(e)||3,this.saved=!1,this.requestUpdate()}modelOptions(){if(!this.selectedModel)return this.models;let e=R(this.selectedModel);return this.models.some(t=>R(t)===e)?this.models:[this.selectedModel,...this.models]}async save(){try{let e=this.selectedModel?.reasoning?this.thinkingLevel:`off`;await he(f(),{model:this.selectedModel,thinkingLevel:e}),await fe(f(),{showToolDetails:this.showToolDetails,expandToolsByDefault:this.expandToolsByDefault}),await ze(f(),{enabled:this.autoCompactEnabled,thresholdPercent:this.autoCompactThresholdPercent,keepRecentTurns:this.autoCompactKeepRecentTurns,minSourceChars:1600,requireConfirmation:this.autoCompactRequireConfirmation}),await this.loadSettings(),this.saved=!0,this.error=``,this.requestUpdate()}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`),this.requestUpdate()}}render(){return this.loading?u`<div class="text-sm text-muted-foreground">${w(`loading`)}</div>`:u`
432
432
  <div class="flex flex-col gap-6">
433
433
  <div>
434
434
  <h3 class="mb-2 inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
435
- ${b(`defaultOptions`)}
436
- <quickforge-info-tip .label=${b(`defaultOptionsDescription`)}></quickforge-info-tip>
435
+ ${w(`defaultOptions`)}
436
+ <quickforge-info-tip .label=${w(`defaultOptionsDescription`)}></quickforge-info-tip>
437
437
  </h3>
438
438
  </div>
439
439
 
440
440
  <label class="grid max-w-md gap-1.5 text-sm">
441
- <span class="text-foreground">${b(`defaultModel`)}</span>
441
+ <span class="text-foreground">${w(`defaultModel`)}</span>
442
442
  <select
443
443
  data-default-model-select
444
444
  class="rounded-md border border-input bg-background px-3 py-2 text-sm"
445
- .value=${this.selectedModel?F(this.selectedModel):``}
445
+ .value=${this.selectedModel?R(this.selectedModel):``}
446
446
  @change=${e=>this.updateModel(e.target.value)}
447
447
  >
448
- ${this.modelOptions().length===0?a`<option value="">${b(`noModelAvailable`)}</option>`:this.modelOptions().map(e=>a`
449
- <option .value=${F(e)}>${Oe(e)}</option>
448
+ ${this.modelOptions().length===0?u`<option value="">${w(`noModelAvailable`)}</option>`:this.modelOptions().map(e=>u`
449
+ <option .value=${R(e)}>${Ve(e)}</option>
450
450
  `)}
451
451
  </select>
452
452
  </label>
453
453
 
454
454
  <label class="grid max-w-sm gap-1.5 text-sm">
455
- <span class="text-foreground">${b(`defaultThinkingLevel`)}</span>
455
+ <span class="text-foreground">${w(`defaultThinkingLevel`)}</span>
456
456
  <select
457
457
  data-default-thinking-select
458
458
  class="rounded-md border border-input bg-background px-3 py-2 text-sm disabled:opacity-60"
@@ -460,18 +460,18 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
460
460
  ?disabled=${!this.selectedModel?.reasoning}
461
461
  @change=${e=>this.updateThinkingLevel(e.target.value)}
462
462
  >
463
- ${P.map(e=>a`
463
+ ${L.map(e=>u`
464
464
  <option .value=${e.value}>${e.label()}</option>
465
465
  `)}
466
466
  </select>
467
- ${this.selectedModel?.reasoning?null:a`<span class="text-xs text-muted-foreground">${b(`thinkingRequiresReasoningModel`)}</span>`}
467
+ ${this.selectedModel?.reasoning?null:u`<span class="text-xs text-muted-foreground">${w(`thinkingRequiresReasoningModel`)}</span>`}
468
468
  </label>
469
469
 
470
470
  <div class="grid max-w-xl gap-3 rounded-lg border border-border p-4">
471
471
  <div>
472
472
  <h4 class="inline-flex items-center gap-1.5 text-sm font-medium text-foreground">
473
- ${b(`toolDisplay`)}
474
- <quickforge-info-tip .label=${b(`showToolDetailsDescription`)}></quickforge-info-tip>
473
+ ${w(`toolDisplay`)}
474
+ <quickforge-info-tip .label=${w(`showToolDetailsDescription`)}></quickforge-info-tip>
475
475
  </h4>
476
476
  </div>
477
477
  <label class="flex items-center gap-2 text-sm text-foreground">
@@ -481,7 +481,7 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
481
481
  .checked=${this.showToolDetails}
482
482
  @change=${e=>this.updateShowToolDetails(e.target.checked)}
483
483
  />
484
- <span>${b(`showToolDetails`)}</span>
484
+ <span>${w(`showToolDetails`)}</span>
485
485
  </label>
486
486
  <label class="flex items-center gap-2 text-sm text-foreground">
487
487
  <input
@@ -490,15 +490,15 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
490
490
  .checked=${this.expandToolsByDefault}
491
491
  @change=${e=>this.updateExpandToolsByDefault(e.target.checked)}
492
492
  />
493
- <span>${b(`expandToolsByDefault`)}</span>
493
+ <span>${w(`expandToolsByDefault`)}</span>
494
494
  </label>
495
495
  </div>
496
496
 
497
497
  <div class="grid max-w-xl gap-3 rounded-lg border border-border p-4">
498
498
  <div>
499
499
  <h4 class="inline-flex items-center gap-1.5 text-sm font-medium text-foreground">
500
- ${b(`contextManagement`)}
501
- <quickforge-info-tip .label=${b(`autoCompactDescription`)}></quickforge-info-tip>
500
+ ${w(`contextManagement`)}
501
+ <quickforge-info-tip .label=${w(`autoCompactDescription`)}></quickforge-info-tip>
502
502
  </h4>
503
503
  </div>
504
504
  <label class="flex items-center gap-2 text-sm text-foreground">
@@ -509,8 +509,8 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
509
509
  @change=${e=>this.updateAutoCompactEnabled(e.target.checked)}
510
510
  />
511
511
  <span class="inline-flex items-center gap-1.5">
512
- ${b(`autoCompactEnabled`)}
513
- <quickforge-info-tip .label=${b(`autoCompactTriggerNote`)}></quickforge-info-tip>
512
+ ${w(`autoCompactEnabled`)}
513
+ <quickforge-info-tip .label=${w(`autoCompactTriggerNote`)}></quickforge-info-tip>
514
514
  </span>
515
515
  </label>
516
516
  <label class="flex items-center gap-2 text-sm text-foreground">
@@ -521,10 +521,10 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
521
521
  ?disabled=${!this.autoCompactEnabled}
522
522
  @change=${e=>this.updateAutoCompactRequireConfirmation(e.target.checked)}
523
523
  />
524
- <span>${b(`autoCompactRequireConfirmation`)}</span>
524
+ <span>${w(`autoCompactRequireConfirmation`)}</span>
525
525
  </label>
526
526
  <label class="grid max-w-xs gap-1.5 text-sm">
527
- <span class="text-foreground">${b(`autoCompactThresholdPercent`)}</span>
527
+ <span class="text-foreground">${w(`autoCompactThresholdPercent`)}</span>
528
528
  <input
529
529
  class="rounded-md border border-input bg-background px-3 py-2 text-sm disabled:opacity-60"
530
530
  type="number"
@@ -538,8 +538,8 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
538
538
  </label>
539
539
  <label class="grid max-w-xs gap-1.5 text-sm">
540
540
  <span class="inline-flex items-center gap-1.5 text-foreground">
541
- ${b(`autoCompactKeepRecentTurns`)}
542
- <quickforge-info-tip .label=${b(`autoCompactHistoryPreserved`)}></quickforge-info-tip>
541
+ ${w(`autoCompactKeepRecentTurns`)}
542
+ <quickforge-info-tip .label=${w(`autoCompactHistoryPreserved`)}></quickforge-info-tip>
543
543
  </span>
544
544
  <input
545
545
  class="rounded-md border border-input bg-background px-3 py-2 text-sm disabled:opacity-60"
@@ -561,30 +561,30 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
561
561
  ?disabled=${!this.selectedModel}
562
562
  @click=${()=>this.save()}
563
563
  >
564
- ${b(`saveDefaultOptions`)}
564
+ ${w(`saveDefaultOptions`)}
565
565
  </button>
566
- ${this.saved?a`<span class="text-sm text-muted-foreground">${b(`defaultOptionsSaved`)}</span>`:null}
567
- ${this.error?a`<span class="text-sm text-destructive">${this.error}</span>`:null}
566
+ ${this.saved?u`<span class="text-sm text-muted-foreground">${w(`defaultOptionsSaved`)}</span>`:null}
567
+ ${this.error?u`<span class="text-sm text-destructive">${this.error}</span>`:null}
568
568
  </div>
569
569
  </div>
570
- `}},I=`quickforge-default-options-settings-tab`;customElements.get(I)||customElements.define(I,ke);function Ae(){return document.createElement(I)}var je=`quickforge-backup`,Me=[{id:`settings`,countKey:`settings`,label:()=>b(`restoreSettings`),description:()=>b(`restoreSettingsDescription`)},{id:`mcp`,countKey:`mcp`,label:()=>b(`restoreMcp`),description:()=>b(`restoreMcpDescription`)},{id:`providerKeys`,countKey:`providerKeys`,label:()=>b(`restoreProviderKeys`),description:()=>b(`restoreProviderKeysDescription`)},{id:`customProviders`,countKey:`customProviders`,label:()=>b(`restoreCustomProviders`),description:()=>b(`restoreCustomProvidersDescription`)},{id:`projects`,countKey:`projects`,label:()=>b(`restoreProjects`),description:()=>b(`restoreProjectsDescription`)},{id:`scheduledTasks`,countKey:`scheduledTasks`,label:()=>b(`restoreScheduledTasks`),description:()=>b(`restoreScheduledTasksDescription`)},{id:`conversations`,countKey:`sessions`,label:()=>b(`restoreConversations`),description:()=>b(`restoreConversationsDescription`)}];function Ne(e,t){let n=new Blob([`${JSON.stringify(t,null,2)}\n`],{type:`application/json`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=e,document.body.appendChild(i),i.click(),i.remove(),URL.revokeObjectURL(r)}function Pe(){return new Date().toISOString().replace(/[:.]/g,`-`)}function Fe(e){return e?Object.entries(e).map(([e,t])=>`${e}: ${t}`).join(`, `):``}function L(e){return Me.filter(t=>(e.sections?.[t.countKey]??0)>0)}var Ie=class extends o{exportScope=`all`;includeSecrets=!1;busy=!1;message=``;error=``;safetyBackupPath=``;pendingImport=null;getTabName(){return b(`backupRestore`)}setScope(e){this.exportScope=e===`config`||e===`sessions`?e:`all`,this.exportScope===`sessions`&&(this.includeSecrets=!1),this.clearStatus(),this.requestUpdate()}clearStatus(){this.message=``,this.error=``,this.safetyBackupPath=``}setIncludeSecrets(e){this.includeSecrets=e&&this.exportScope!==`sessions`,this.message=``,this.error=``,this.requestUpdate()}async exportBackup(){if(!(this.includeSecrets&&!await m({description:b(`backupExportSecretsConfirm`),confirmLabel:b(`exportBackup`),cancelLabel:b(`cancel`)}))){this.busy=!0,this.clearStatus(),this.requestUpdate();try{let e=new URLSearchParams({scope:this.exportScope,includeSecrets:this.includeSecrets?`1`:`0`}),t=await fetch(`/api/backup/export?${e.toString()}`,{cache:`no-store`}),n=await t.json().catch(()=>null);if(!t.ok)throw Error(n?.error||b(`backupExportFailed`));let r=this.includeSecrets?`with-secrets`:`no-secrets`;Ne(`${je}-${this.exportScope}-${r}-${Pe()}.json`,n),this.message=b(`backupExported`)}catch(e){this.error=e instanceof Error?e.message:b(`backupExportFailed`)}finally{this.busy=!1,this.requestUpdate()}}}async inspectBackup(e){let t=await fetch(`/api/backup/inspect`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)}),n=await t.json().catch(()=>null);if(!t.ok)throw Error(n?.error||b(`backupInspectFailed`));if(!n)throw Error(b(`backupInspectFailed`));return n}async importBackupFromFile(e){this.busy=!0,this.clearStatus(),this.pendingImport=null,this.requestUpdate();try{let t=await e.text(),n=JSON.parse(t),r=await this.inspectBackup(n),i=new Set(L(r).map(e=>e.id));this.pendingImport={backup:n,inspect:r,selectedSections:i,mode:`replace`},this.message=b(`backupInspected`)}catch(e){this.error=e instanceof Error?e.message:b(`backupImportFailed`)}finally{this.busy=!1,this.requestUpdate()}}togglePendingSection(e,t){this.pendingImport&&(t?this.pendingImport.selectedSections.add(e):this.pendingImport.selectedSections.delete(e),this.message=``,this.error=``,this.requestUpdate())}setRestoreMode(e){this.pendingImport&&(this.pendingImport.mode=e,this.message=``,this.error=``,this.requestUpdate())}cancelPendingImport(){this.pendingImport=null,this.message=``,this.error=``,this.requestUpdate()}async confirmPendingImport(){if(this.pendingImport){if(this.pendingImport.selectedSections.size===0){this.error=b(`selectAtLeastOneRestoreSection`),this.requestUpdate();return}this.busy=!0,this.clearStatus(),this.requestUpdate();try{let e=await fetch(`/api/backup/import`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({backup:this.pendingImport.backup,sections:[...this.pendingImport.selectedSections],mode:this.pendingImport.mode})}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||b(`backupImportFailed`));let n=Fe(t?.summary);this.safetyBackupPath=t?.safetyBackupPath||``,this.pendingImport=null,this.message=n?`${b(`backupImported`)} ${n}`:b(`backupImported`),window.setTimeout(()=>window.location.reload(),1500)}catch(e){this.error=e instanceof Error?e.message:b(`backupImportFailed`)}finally{this.busy=!1,this.requestUpdate()}}}handleFileChange(e){let t=e.target,n=t.files?.[0];t.value=``,n&&this.importBackupFromFile(n)}renderPendingImport(){if(!this.pendingImport)return null;let{inspect:e,selectedSections:t}=this.pendingImport,n=L(e);return a`
570
+ `}},z=`quickforge-default-options-settings-tab`;customElements.get(z)||customElements.define(z,He);function Ue(){return document.createElement(z)}var We=`quickforge-backup`,Ge=[{id:`settings`,countKey:`settings`,label:()=>w(`restoreSettings`),description:()=>w(`restoreSettingsDescription`)},{id:`mcp`,countKey:`mcp`,label:()=>w(`restoreMcp`),description:()=>w(`restoreMcpDescription`)},{id:`providerKeys`,countKey:`providerKeys`,label:()=>w(`restoreProviderKeys`),description:()=>w(`restoreProviderKeysDescription`)},{id:`customProviders`,countKey:`customProviders`,label:()=>w(`restoreCustomProviders`),description:()=>w(`restoreCustomProvidersDescription`)},{id:`projects`,countKey:`projects`,label:()=>w(`restoreProjects`),description:()=>w(`restoreProjectsDescription`)},{id:`scheduledTasks`,countKey:`scheduledTasks`,label:()=>w(`restoreScheduledTasks`),description:()=>w(`restoreScheduledTasksDescription`)},{id:`conversations`,countKey:`sessions`,label:()=>w(`restoreConversations`),description:()=>w(`restoreConversationsDescription`)}];function Ke(e,t){let n=new Blob([`${JSON.stringify(t,null,2)}\n`],{type:`application/json`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=e,document.body.appendChild(i),i.click(),i.remove(),URL.revokeObjectURL(r)}function qe(){return new Date().toISOString().replace(/[:.]/g,`-`)}function Je(e){return e?Object.entries(e).map(([e,t])=>`${e}: ${t}`).join(`, `):``}function Ye(e){return Ge.filter(t=>(e.sections?.[t.countKey]??0)>0)}var Xe=class extends d{exportScope=`all`;includeSecrets=!1;busy=!1;message=``;error=``;safetyBackupPath=``;pendingImport=null;getTabName(){return w(`backupRestore`)}setScope(e){this.exportScope=e===`config`||e===`sessions`?e:`all`,this.exportScope===`sessions`&&(this.includeSecrets=!1),this.clearStatus(),this.requestUpdate()}clearStatus(){this.message=``,this.error=``,this.safetyBackupPath=``}setIncludeSecrets(e){this.includeSecrets=e&&this.exportScope!==`sessions`,this.message=``,this.error=``,this.requestUpdate()}async exportBackup(){if(!(this.includeSecrets&&!await v({description:w(`backupExportSecretsConfirm`),confirmLabel:w(`exportBackup`),cancelLabel:w(`cancel`)}))){this.busy=!0,this.clearStatus(),this.requestUpdate();try{let e=new URLSearchParams({scope:this.exportScope,includeSecrets:this.includeSecrets?`1`:`0`}),t=await fetch(`/api/backup/export?${e.toString()}`,{cache:`no-store`}),n=await t.json().catch(()=>null);if(!t.ok)throw Error(n?.error||w(`backupExportFailed`));let r=this.includeSecrets?`with-secrets`:`no-secrets`;Ke(`${We}-${this.exportScope}-${r}-${qe()}.json`,n),this.message=w(`backupExported`)}catch(e){this.error=e instanceof Error?e.message:w(`backupExportFailed`)}finally{this.busy=!1,this.requestUpdate()}}}async inspectBackup(e){let t=await fetch(`/api/backup/inspect`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)}),n=await t.json().catch(()=>null);if(!t.ok)throw Error(n?.error||w(`backupInspectFailed`));if(!n)throw Error(w(`backupInspectFailed`));return n}async importBackupFromFile(e){this.busy=!0,this.clearStatus(),this.pendingImport=null,this.requestUpdate();try{let t=await e.text(),n=JSON.parse(t),r=await this.inspectBackup(n),i=new Set(Ye(r).map(e=>e.id));this.pendingImport={backup:n,inspect:r,selectedSections:i,mode:`replace`},this.message=w(`backupInspected`)}catch(e){this.error=e instanceof Error?e.message:w(`backupImportFailed`)}finally{this.busy=!1,this.requestUpdate()}}togglePendingSection(e,t){this.pendingImport&&(t?this.pendingImport.selectedSections.add(e):this.pendingImport.selectedSections.delete(e),this.message=``,this.error=``,this.requestUpdate())}setRestoreMode(e){this.pendingImport&&(this.pendingImport.mode=e,this.message=``,this.error=``,this.requestUpdate())}cancelPendingImport(){this.pendingImport=null,this.message=``,this.error=``,this.requestUpdate()}async confirmPendingImport(){if(this.pendingImport){if(this.pendingImport.selectedSections.size===0){this.error=w(`selectAtLeastOneRestoreSection`),this.requestUpdate();return}this.busy=!0,this.clearStatus(),this.requestUpdate();try{let e=await fetch(`/api/backup/import`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({backup:this.pendingImport.backup,sections:[...this.pendingImport.selectedSections],mode:this.pendingImport.mode})}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||w(`backupImportFailed`));let n=Je(t?.summary);this.safetyBackupPath=t?.safetyBackupPath||``,this.pendingImport=null,this.message=n?`${w(`backupImported`)} ${n}`:w(`backupImported`),window.setTimeout(()=>window.location.reload(),1500)}catch(e){this.error=e instanceof Error?e.message:w(`backupImportFailed`)}finally{this.busy=!1,this.requestUpdate()}}}handleFileChange(e){let t=e.target,n=t.files?.[0];t.value=``,n&&this.importBackupFromFile(n)}renderPendingImport(){if(!this.pendingImport)return null;let{inspect:e,selectedSections:t}=this.pendingImport,n=Ye(e);return u`
571
571
  <section class="rounded-lg border border-amber-500/30 bg-amber-500/5 p-4">
572
- <h4 class="text-sm font-semibold text-foreground">${b(`backupInspectTitle`)}</h4>
572
+ <h4 class="text-sm font-semibold text-foreground">${w(`backupInspectTitle`)}</h4>
573
573
  <dl class="mt-3 grid gap-1 text-sm text-muted-foreground">
574
- <div><span class="text-foreground">${b(`backupInspectExportedAt`)}:</span> ${e.exportedAt||`-`}</div>
575
- <div><span class="text-foreground">${b(`backupInspectVersion`)}:</span> ${e.version??`-`}</div>
576
- <div><span class="text-foreground">${b(`backupInspectScope`)}:</span> ${e.scope||`-`}</div>
577
- <div><span class="text-foreground">${b(`backupInspectSecrets`)}:</span> ${e.includeSecrets?b(`yes`):b(`no`)}</div>
574
+ <div><span class="text-foreground">${w(`backupInspectExportedAt`)}:</span> ${e.exportedAt||`-`}</div>
575
+ <div><span class="text-foreground">${w(`backupInspectVersion`)}:</span> ${e.version??`-`}</div>
576
+ <div><span class="text-foreground">${w(`backupInspectScope`)}:</span> ${e.scope||`-`}</div>
577
+ <div><span class="text-foreground">${w(`backupInspectSecrets`)}:</span> ${e.includeSecrets?w(`yes`):w(`no`)}</div>
578
578
  </dl>
579
579
 
580
- ${e.warnings?.length?a`
580
+ ${e.warnings?.length?u`
581
581
  <div class="mt-3 rounded-md border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-xs text-amber-700 dark:text-amber-300">
582
- ${e.warnings.map(e=>a`<div>⚠ ${e}</div>`)}
582
+ ${e.warnings.map(e=>u`<div>⚠ ${e}</div>`)}
583
583
  </div>
584
584
  `:null}
585
585
 
586
586
  <div class="mt-4">
587
- <div class="text-sm font-medium text-foreground">${b(`restoreMode`)}</div>
587
+ <div class="text-sm font-medium text-foreground">${w(`restoreMode`)}</div>
588
588
  <div class="mt-2 grid gap-2">
589
589
  <label class="flex items-start gap-2 rounded-md border border-border bg-background/60 p-3 text-sm ${this.pendingImport.mode===`replace`?`border-primary`:``}">
590
590
  <input
@@ -596,8 +596,8 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
596
596
  @change=${()=>this.setRestoreMode(`replace`)}
597
597
  />
598
598
  <span>
599
- <span class="block text-foreground">${b(`restoreModeReplace`)}</span>
600
- <span class="block text-xs text-muted-foreground">${b(`restoreModeReplaceDescription`)}</span>
599
+ <span class="block text-foreground">${w(`restoreModeReplace`)}</span>
600
+ <span class="block text-xs text-muted-foreground">${w(`restoreModeReplaceDescription`)}</span>
601
601
  </span>
602
602
  </label>
603
603
  <label class="flex items-start gap-2 rounded-md border border-border bg-background/60 p-3 text-sm ${this.pendingImport.mode===`merge`?`border-primary`:``}">
@@ -610,17 +610,17 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
610
610
  @change=${()=>this.setRestoreMode(`merge`)}
611
611
  />
612
612
  <span>
613
- <span class="block text-foreground">${b(`restoreModeMerge`)}</span>
614
- <span class="block text-xs text-muted-foreground">${b(`restoreModeMergeDescription`)}</span>
613
+ <span class="block text-foreground">${w(`restoreModeMerge`)}</span>
614
+ <span class="block text-xs text-muted-foreground">${w(`restoreModeMergeDescription`)}</span>
615
615
  </span>
616
616
  </label>
617
617
  </div>
618
618
  </div>
619
619
 
620
620
  <div class="mt-4">
621
- <div class="text-sm font-medium text-foreground">${b(`selectRestoreSections`)}</div>
621
+ <div class="text-sm font-medium text-foreground">${w(`selectRestoreSections`)}</div>
622
622
  <div class="mt-2 grid gap-2">
623
- ${n.map(n=>a`
623
+ ${n.map(n=>u`
624
624
  <label class="flex items-start gap-2 rounded-md border border-border bg-background/60 p-3 text-sm">
625
625
  <input
626
626
  class="mt-1"
@@ -645,7 +645,7 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
645
645
  ?disabled=${this.busy||t.size===0}
646
646
  @click=${()=>this.confirmPendingImport()}
647
647
  >
648
- ${this.busy?b(`loading`):b(`confirmImportSelected`)}
648
+ ${this.busy?w(`loading`):w(`confirmImportSelected`)}
649
649
  </button>
650
650
  <button
651
651
  class="rounded-md border border-input px-3 py-2 text-sm hover:bg-muted/60 disabled:opacity-60"
@@ -653,36 +653,36 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
653
653
  ?disabled=${this.busy}
654
654
  @click=${()=>this.cancelPendingImport()}
655
655
  >
656
- ${b(`cancel`)}
656
+ ${w(`cancel`)}
657
657
  </button>
658
658
  </div>
659
659
  </section>
660
- `}render(){return a`
660
+ `}render(){return u`
661
661
  <div class="flex flex-col gap-6">
662
662
  <div>
663
663
  <h3 class="mb-2 inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
664
- ${b(`backupRestore`)}
665
- <quickforge-info-tip .label=${b(`backupRestoreDescription`)}></quickforge-info-tip>
664
+ ${w(`backupRestore`)}
665
+ <quickforge-info-tip .label=${w(`backupRestoreDescription`)}></quickforge-info-tip>
666
666
  </h3>
667
667
  </div>
668
668
 
669
669
  <section class="rounded-lg border border-border p-4">
670
670
  <h4 class="inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
671
- ${b(`exportData`)}
672
- <quickforge-info-tip .label=${b(`exportDataDescription`)}></quickforge-info-tip>
671
+ ${w(`exportData`)}
672
+ <quickforge-info-tip .label=${w(`exportDataDescription`)}></quickforge-info-tip>
673
673
  </h4>
674
674
 
675
675
  <label class="mt-4 grid max-w-sm gap-1.5 text-sm">
676
- <span class="text-foreground">${b(`exportScope`)}</span>
676
+ <span class="text-foreground">${w(`exportScope`)}</span>
677
677
  <select
678
678
  class="rounded-md border border-input bg-background px-3 py-2 text-sm"
679
679
  .value=${this.exportScope}
680
680
  ?disabled=${this.busy}
681
681
  @change=${e=>this.setScope(e.target.value)}
682
682
  >
683
- <option value="all">${b(`exportScopeAll`)}</option>
684
- <option value="config">${b(`exportScopeConfig`)}</option>
685
- <option value="sessions">${b(`exportScopeSessions`)}</option>
683
+ <option value="all">${w(`exportScopeAll`)}</option>
684
+ <option value="config">${w(`exportScopeConfig`)}</option>
685
+ <option value="sessions">${w(`exportScopeSessions`)}</option>
686
686
  </select>
687
687
  </label>
688
688
 
@@ -695,8 +695,8 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
695
695
  @change=${e=>this.setIncludeSecrets(e.target.checked)}
696
696
  />
697
697
  <span>
698
- <span class="block">${b(`includeApiKeys`)}</span>
699
- <span class="block text-xs text-muted-foreground">${b(`includeApiKeysDescription`)}</span>
698
+ <span class="block">${w(`includeApiKeys`)}</span>
699
+ <span class="block text-xs text-muted-foreground">${w(`includeApiKeysDescription`)}</span>
700
700
  </span>
701
701
  </label>
702
702
 
@@ -706,14 +706,14 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
706
706
  ?disabled=${this.busy}
707
707
  @click=${()=>this.exportBackup()}
708
708
  >
709
- ${this.busy?b(`loading`):b(`exportBackup`)}
709
+ ${this.busy?w(`loading`):w(`exportBackup`)}
710
710
  </button>
711
711
  </section>
712
712
 
713
713
  <section class="rounded-lg border border-border p-4">
714
714
  <h4 class="inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
715
- ${b(`importData`)}
716
- <quickforge-info-tip .label=${b(`importDataDescription`)}></quickforge-info-tip>
715
+ ${w(`importData`)}
716
+ <quickforge-info-tip .label=${w(`importDataDescription`)}></quickforge-info-tip>
717
717
  </h4>
718
718
 
719
719
  <label class="mt-4 inline-flex cursor-pointer rounded-md border border-input px-3 py-2 text-sm hover:bg-muted/60 ${this.busy?`pointer-events-none opacity-60`:``}">
@@ -724,22 +724,22 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
724
724
  ?disabled=${this.busy}
725
725
  @change=${e=>this.handleFileChange(e)}
726
726
  />
727
- ${b(`importBackup`)}
727
+ ${w(`importBackup`)}
728
728
  </label>
729
729
  </section>
730
730
 
731
731
  ${this.renderPendingImport()}
732
- ${this.message?a`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
733
- ${this.safetyBackupPath?a`<div class="rounded-md border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground">${b(`backupSafetyBackupPath`)}: <code>${this.safetyBackupPath}</code></div>`:null}
734
- ${this.error?a`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
732
+ ${this.message?u`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
733
+ ${this.safetyBackupPath?u`<div class="rounded-md border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground">${w(`backupSafetyBackupPath`)}: <code>${this.safetyBackupPath}</code></div>`:null}
734
+ ${this.error?u`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
735
735
  </div>
736
- `}},R=`quickforge-backup-settings-tab`;customElements.get(R)||customElements.define(R,Ie);function Le(){return document.createElement(R)}function z(e){if(!e)return`-`;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(S())}function B(e){let t={...e};return delete t.archivedAt,t}function V(){if(!(typeof BroadcastChannel>`u`))try{let e=new BroadcastChannel(`quickforge-sync`);e.postMessage({type:`sessions-changed`,sourceTabId:`archived-conversations-settings-tab`,timestamp:Date.now()}),e.close()}catch{}}var Re=class extends o{sessions=[];projects=[];loading=!0;busySessionId=``;query=``;projectFilter=`all`;message=``;error=``;getTabName(){return b(`archivedConversations`)}async connectedCallback(){super.connectedCallback(),await this.loadData()}get projectNameById(){return new Map(this.projects.map(e=>[e.id,e.name]))}async loadData(){this.loading=!0,this.error=``,this.requestUpdate();try{let[e,t]=await Promise.all([fetch(`/api/storage/sessions-metadata/index/lastModified?direction=desc&limit=1000&offset=0&archived=only`,{cache:`no-store`}),fetch(`/api/project`,{cache:`no-store`}).catch(()=>null)]),n=await e.json().catch(()=>null);if(!e.ok)throw Error(n?.error||b(`requestFailed`));if(this.sessions=Array.isArray(n?.values)?n.values:[],t?.ok){let e=await t.json().catch(()=>null);this.projects=Array.isArray(e?.projects)?e.projects:[]}}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}filteredSessions(){let e=this.query.trim().toLowerCase();return this.sessions.filter(t=>{if(this.projectFilter!==`all`&&(this.projectFilter===`global`&&t.scope===`project`||this.projectFilter!==`global`&&t.projectId!==this.projectFilter))return!1;if(!e)return!0;let n=t.projectId&&this.projectNameById.get(t.projectId)||``;return`${_(t.title)} ${n}`.toLowerCase().includes(e)})}groupedSessions(){let e=new Map;for(let t of this.filteredSessions()){let n=t.scope===`project`&&t.projectId?t.projectId:`global`;e.set(n,[...e.get(n)??[],t])}return[...e.entries()]}projectLabel(e){return e===`global`?b(`normalChat`):this.projectNameById.get(e)||b(`unknownProject`)}async restoreSession(e){if(!this.busySessionId){this.busySessionId=e,this.message=``,this.error=``,this.requestUpdate();try{let t=s(),n=await t.sessions.get(e),r=await t.sessions.getMetadata(e);if(!n||!r)throw Error(b(`sessionNotFound`));await t.sessions.save(B(n),B(r)),this.sessions=this.sessions.filter(t=>t.id!==e),this.message=b(`sessionRestored`),V()}catch(e){this.error=e instanceof Error?e.message:b(`restoreSessionFailed`)}finally{this.busySessionId=``,this.requestUpdate()}}}async deleteSession(e){if(!this.busySessionId&&await m({description:b(`deleteArchivedSessionConfirm`,{title:_(e.title)}),confirmLabel:b(`confirmDelete`),cancelLabel:b(`cancel`),variant:`destructive`})){this.busySessionId=e.id,this.message=``,this.error=``,this.requestUpdate();try{await s().sessions.delete(e.id),this.sessions=this.sessions.filter(t=>t.id!==e.id),this.message=b(`archivedSessionDeleted`),V()}catch(e){this.error=e instanceof Error?e.message:b(`deleteSessionFailed`)}finally{this.busySessionId=``,this.requestUpdate()}}}async deleteAllArchivedSessions(){if(!(this.busySessionId||this.sessions.length===0)&&await m({description:b(`deleteAllArchivedSessionsConfirm`),confirmLabel:b(`confirmDelete`),cancelLabel:b(`cancel`),variant:`destructive`})){this.busySessionId=`__all__`,this.message=``,this.error=``,this.requestUpdate();try{let e=s();await Promise.all(this.sessions.map(t=>e.sessions.delete(t.id))),this.sessions=[],this.message=b(`archivedSessionsDeleted`),V()}catch(e){this.error=e instanceof Error?e.message:b(`deleteSessionFailed`)}finally{this.busySessionId=``,this.requestUpdate()}}}renderSession(e){let t=this.busySessionId===e.id||this.busySessionId===`__all__`;return a`
736
+ `}},B=`quickforge-backup-settings-tab`;customElements.get(B)||customElements.define(B,Xe);function Ze(){return document.createElement(B)}function Qe(e){if(!e)return`-`;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(E())}function $e(e){let t={...e};return delete t.archivedAt,t}function V(){if(!(typeof BroadcastChannel>`u`))try{let e=new BroadcastChannel(`quickforge-sync`);e.postMessage({type:`sessions-changed`,sourceTabId:`archived-conversations-settings-tab`,timestamp:Date.now()}),e.close()}catch{}}var et=class extends d{sessions=[];projects=[];loading=!0;busySessionId=``;query=``;projectFilter=`all`;message=``;error=``;getTabName(){return w(`archivedConversations`)}async connectedCallback(){super.connectedCallback(),await this.loadData()}get projectNameById(){return new Map(this.projects.map(e=>[e.id,e.name]))}async loadData(){this.loading=!0,this.error=``,this.requestUpdate();try{let[e,t]=await Promise.all([fetch(`/api/storage/sessions-metadata/index/lastModified?direction=desc&limit=1000&offset=0&archived=only`,{cache:`no-store`}),fetch(`/api/project`,{cache:`no-store`}).catch(()=>null)]),n=await e.json().catch(()=>null);if(!e.ok)throw Error(n?.error||w(`requestFailed`));if(this.sessions=Array.isArray(n?.values)?n.values:[],t?.ok){let e=await t.json().catch(()=>null);this.projects=Array.isArray(e?.projects)?e.projects:[]}}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}filteredSessions(){let e=this.query.trim().toLowerCase();return this.sessions.filter(t=>{if(this.projectFilter!==`all`&&(this.projectFilter===`global`&&t.scope===`project`||this.projectFilter!==`global`&&t.projectId!==this.projectFilter))return!1;if(!e)return!0;let n=t.projectId&&this.projectNameById.get(t.projectId)||``;return`${x(t.title)} ${n}`.toLowerCase().includes(e)})}groupedSessions(){let e=new Map;for(let t of this.filteredSessions()){let n=t.scope===`project`&&t.projectId?t.projectId:`global`;e.set(n,[...e.get(n)??[],t])}return[...e.entries()]}projectLabel(e){return e===`global`?w(`normalChat`):this.projectNameById.get(e)||w(`unknownProject`)}async restoreSession(e){if(!this.busySessionId){this.busySessionId=e,this.message=``,this.error=``,this.requestUpdate();try{let t=f(),n=await t.sessions.get(e),r=await t.sessions.getMetadata(e);if(!n||!r)throw Error(w(`sessionNotFound`));await t.sessions.save($e(n),$e(r)),this.sessions=this.sessions.filter(t=>t.id!==e),this.message=w(`sessionRestored`),V()}catch(e){this.error=e instanceof Error?e.message:w(`restoreSessionFailed`)}finally{this.busySessionId=``,this.requestUpdate()}}}async deleteSession(e){if(!this.busySessionId&&await v({description:w(`deleteArchivedSessionConfirm`,{title:x(e.title)}),confirmLabel:w(`confirmDelete`),cancelLabel:w(`cancel`),variant:`destructive`})){this.busySessionId=e.id,this.message=``,this.error=``,this.requestUpdate();try{await f().sessions.delete(e.id),this.sessions=this.sessions.filter(t=>t.id!==e.id),this.message=w(`archivedSessionDeleted`),V()}catch(e){this.error=e instanceof Error?e.message:w(`deleteSessionFailed`)}finally{this.busySessionId=``,this.requestUpdate()}}}async deleteAllArchivedSessions(){if(!(this.busySessionId||this.sessions.length===0)&&await v({description:w(`deleteAllArchivedSessionsConfirm`),confirmLabel:w(`confirmDelete`),cancelLabel:w(`cancel`),variant:`destructive`})){this.busySessionId=`__all__`,this.message=``,this.error=``,this.requestUpdate();try{let e=f();await Promise.all(this.sessions.map(t=>e.sessions.delete(t.id))),this.sessions=[],this.message=w(`archivedSessionsDeleted`),V()}catch(e){this.error=e instanceof Error?e.message:w(`deleteSessionFailed`)}finally{this.busySessionId=``,this.requestUpdate()}}}renderSession(e){let t=this.busySessionId===e.id||this.busySessionId===`__all__`;return u`
737
737
  <div class="border-t border-border px-4 py-3 first:border-t-0">
738
738
  <div class="flex items-start justify-between gap-3">
739
739
  <div class="min-w-0">
740
- <div class="truncate text-sm font-medium text-foreground">${_(e.title)}</div>
740
+ <div class="truncate text-sm font-medium text-foreground">${x(e.title)}</div>
741
741
  <div class="mt-1 text-xs text-muted-foreground">
742
- ${b(`lastModified`)}: ${z(e.lastModified)} · ${b(`archivedAt`)}: ${z(e.archivedAt)}
742
+ ${w(`lastModified`)}: ${Qe(e.lastModified)} · ${w(`archivedAt`)}: ${Qe(e.archivedAt)}
743
743
  </div>
744
744
  </div>
745
745
  <div class="flex shrink-0 items-center gap-2">
@@ -749,7 +749,7 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
749
749
  ?disabled=${t}
750
750
  @click=${()=>this.restoreSession(e.id)}
751
751
  >
752
- ${b(`restoreSession`)}
752
+ ${w(`restoreSession`)}
753
753
  </button>
754
754
  <button
755
755
  class="rounded-md px-2.5 py-1 text-xs text-destructive hover:bg-destructive/10 disabled:opacity-60"
@@ -757,17 +757,17 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
757
757
  ?disabled=${t}
758
758
  @click=${()=>this.deleteSession(e)}
759
759
  >
760
- ${b(`deletePermanently`)}
760
+ ${w(`deletePermanently`)}
761
761
  </button>
762
762
  </div>
763
763
  </div>
764
764
  </div>
765
- `}render(){let e=this.groupedSessions(),t=!!this.busySessionId;return a`
765
+ `}render(){let e=this.groupedSessions(),t=!!this.busySessionId;return u`
766
766
  <div class="flex flex-col gap-4">
767
767
  <div class="flex items-center justify-between gap-3">
768
768
  <div>
769
- <h3 class="text-sm font-semibold text-foreground">${b(`archivedConversations`)}</h3>
770
- <p class="mt-1 text-xs text-muted-foreground">${b(`archivedConversationsDescription`)}</p>
769
+ <h3 class="text-sm font-semibold text-foreground">${w(`archivedConversations`)}</h3>
770
+ <p class="mt-1 text-xs text-muted-foreground">${w(`archivedConversationsDescription`)}</p>
771
771
  </div>
772
772
  <button
773
773
  class="rounded-md bg-destructive/10 px-3 py-2 text-sm text-destructive hover:bg-destructive/15 disabled:opacity-60"
@@ -775,7 +775,7 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
775
775
  ?disabled=${t||this.sessions.length===0}
776
776
  @click=${()=>this.deleteAllArchivedSessions()}
777
777
  >
778
- ${b(`deleteAll`)}
778
+ ${w(`deleteAll`)}
779
779
  </button>
780
780
  </div>
781
781
 
@@ -785,7 +785,7 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
785
785
  class="rounded-md border border-input bg-background px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-ring/30"
786
786
  type="search"
787
787
  .value=${this.query}
788
- placeholder=${b(`searchArchivedConversations`)}
788
+ placeholder=${w(`searchArchivedConversations`)}
789
789
  @input=${e=>{this.query=e.target.value,this.requestUpdate()}}
790
790
  />
791
791
  <select
@@ -793,23 +793,23 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
793
793
  .value=${this.projectFilter}
794
794
  @change=${e=>{this.projectFilter=e.target.value,this.requestUpdate()}}
795
795
  >
796
- <option value="all">${b(`allProjects`)}</option>
797
- <option value="global">${b(`normalChat`)}</option>
798
- ${this.projects.map(e=>a`<option value=${e.id}>${e.name}</option>`)}
796
+ <option value="all">${w(`allProjects`)}</option>
797
+ <option value="global">${w(`normalChat`)}</option>
798
+ ${this.projects.map(e=>u`<option value=${e.id}>${e.name}</option>`)}
799
799
  </select>
800
800
  </div>
801
801
 
802
- ${this.loading?a`
803
- <div class="px-4 py-8 text-center text-sm text-muted-foreground">${b(`loading`)}</div>
804
- `:e.length===0?a`
805
- <div class="px-4 py-8 text-center text-sm text-muted-foreground">${b(`noArchivedConversations`)}</div>
806
- `:a`
802
+ ${this.loading?u`
803
+ <div class="px-4 py-8 text-center text-sm text-muted-foreground">${w(`loading`)}</div>
804
+ `:e.length===0?u`
805
+ <div class="px-4 py-8 text-center text-sm text-muted-foreground">${w(`noArchivedConversations`)}</div>
806
+ `:u`
807
807
  <div>
808
- ${e.map(([e,t])=>a`
808
+ ${e.map(([e,t])=>u`
809
809
  <div class="border-b border-border last:border-b-0">
810
810
  <div class="flex items-center justify-between gap-3 bg-muted/20 px-4 py-2 text-sm text-muted-foreground">
811
811
  <div class="truncate">${this.projectLabel(e)}</div>
812
- <div class="shrink-0">${b(`conversationCount`,{count:t.length})}</div>
812
+ <div class="shrink-0">${w(`conversationCount`,{count:t.length})}</div>
813
813
  </div>
814
814
  ${t.map(e=>this.renderSession(e))}
815
815
  </div>
@@ -818,112 +818,112 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
818
818
  `}
819
819
  </section>
820
820
 
821
- ${this.message?a`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
822
- ${this.error?a`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
821
+ ${this.message?u`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
822
+ ${this.error?u`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
823
823
  </div>
824
- `}},H=`quickforge-archived-conversations-settings-tab`;customElements.get(H)||customElements.define(H,Re);function ze(){return document.createElement(H)}var Be=3e4,Ve=800;function He(e){return new Promise(t=>window.setTimeout(t,e))}function Ue(e){if(!e)return`-`;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(S())}function We(){return`custom_${globalThis.crypto?.randomUUID?.().slice(0,8)||Date.now().toString(36)}`}function Ge(e){let t=e.trim(),n=t.split(/[\\/]/).pop()?.replace(/^"|"$/g,``)||t;return/^bash(\.exe)?$/i.test(n)?`Bash`:/^zsh$/i.test(n)?`Zsh`:/^fish$/i.test(n)?`Fish`:/^cmd(\.exe)?$/i.test(n)?`Command Prompt`:/^powershell(\.exe)?$/i.test(n)?`Windows PowerShell`:/^pwsh(\.exe)?$/i.test(n)?`PowerShell 7+`:n||`Custom Shell`}var Ke=a`
824
+ `}},H=`quickforge-archived-conversations-settings-tab`;customElements.get(H)||customElements.define(H,et);function tt(){return document.createElement(H)}var nt=3e4,rt=800;function it(e){return new Promise(t=>window.setTimeout(t,e))}function at(e){if(!e)return`-`;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(E())}function ot(){return`custom_${globalThis.crypto?.randomUUID?.().slice(0,8)||Date.now().toString(36)}`}function st(e){let t=e.trim(),n=t.split(/[\\/]/).pop()?.replace(/^"|"$/g,``)||t;return/^bash(\.exe)?$/i.test(n)?`Bash`:/^zsh$/i.test(n)?`Zsh`:/^fish$/i.test(n)?`Fish`:/^cmd(\.exe)?$/i.test(n)?`Command Prompt`:/^powershell(\.exe)?$/i.test(n)?`Windows PowerShell`:/^pwsh(\.exe)?$/i.test(n)?`PowerShell 7+`:n||`Custom Shell`}var ct=u`
825
825
  <svg class="size-3.5" viewBox="0 0 16 16" fill="none" aria-hidden="true">
826
826
  <path d="M3.5 8.2 6.6 11.3 12.7 4.7" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" />
827
827
  </svg>
828
- `,qe=a`
828
+ `,lt=u`
829
829
  <svg class="size-3.5" viewBox="0 0 16 16" fill="none" aria-hidden="true">
830
830
  <circle cx="8" cy="8" r="4.8" stroke="currentColor" stroke-width="1.5" />
831
831
  </svg>
832
- `,Je=a`
832
+ `,ut=u`
833
833
  <svg class="size-3.5" viewBox="0 0 16 16" fill="none" aria-hidden="true">
834
834
  <path d="M4.5 4.5 11.5 11.5M11.5 4.5 4.5 11.5" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" />
835
835
  </svg>
836
- `,Ye=class extends o{status;loading=!0;restarting=!1;message=``;error=``;terminalShellConfig={terminalShell:`auto`,defaultProfileId:`auto`,profiles:[]};customShellCommand=``;getTabName(){return b(`backendService`)}async connectedCallback(){super.connectedCallback(),await Promise.all([this.loadStatus(),this.loadTerminalShell()])}customShellProfiles(){return this.terminalShellConfig.profiles.filter(e=>!e.builtin)}async loadTerminalShell(){try{let e=await fetch(`/api/system/terminal-shell`,{cache:`no-store`}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||b(`requestFailed`));this.terminalShellConfig={terminalShell:t?.terminalShell||`auto`,defaultProfileId:t?.defaultProfileId||`auto`,profiles:Array.isArray(t?.profiles)?t.profiles:[]}}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.requestUpdate()}}async saveTerminalShellConfig(e,t=this.customShellProfiles(),n=b(`terminalShellSaved`)){try{let r=await fetch(`/api/system/terminal-shell`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({defaultProfileId:e,profiles:t})}),i=await r.json().catch(()=>null);if(!r.ok)throw Error(i?.error||b(`requestFailed`));this.terminalShellConfig=i,this.message=n,this.error=``}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.requestUpdate()}}async addCustomTerminalShell(){let e=this.customShellCommand.trim();if(!e){this.error=b(`terminalShellProfileRequired`),this.requestUpdate();return}let t=[...this.customShellProfiles(),{id:We(),name:Ge(e),command:e,builtin:!1}];this.customShellCommand=``,await this.saveTerminalShellConfig(this.terminalShellConfig.defaultProfileId,t,b(`terminalShellProfilesSaved`))}async deleteCustomTerminalShell(e){let t=this.terminalShellConfig.profiles.find(t=>t.id===e);if(!t||t.builtin||!await m({description:b(`terminalShellDeleteConfirm`,{name:t.name}),confirmLabel:b(`confirmDelete`),cancelLabel:b(`cancel`),variant:`destructive`}))return;let n=this.customShellProfiles().filter(t=>t.id!==e),r=this.terminalShellConfig.defaultProfileId===e?`auto`:this.terminalShellConfig.defaultProfileId;await this.saveTerminalShellConfig(r,n,b(`terminalShellProfilesSaved`))}async loadStatus(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=await fetch(`/api/health`,{cache:`no-store`}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||b(`requestFailed`));this.status=t}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}async pollUntilRestarted(e){let t=Date.now();for(;Date.now()-t<Be;){await He(Ve);try{let t=await fetch(`/api/health?restartPoll=${Date.now()}`,{cache:`no-store`}),n=await t.json().catch(()=>null);if(t.ok&&n?.ok&&n.bootId&&n.bootId!==e){this.message=b(`backendRestarted`),this.requestUpdate(),window.setTimeout(()=>window.location.reload(),300);return}}catch{}}throw Error(b(`backendRestartTimeout`))}async restartService(){if(!this.status||this.restarting||!await m({description:b(`restartBackendConfirm`),confirmLabel:b(`restartBackendService`),cancelLabel:b(`cancel`)}))return;this.restarting=!0,this.message=b(`backendRestarting`),this.error=``,this.requestUpdate();let e=this.status.bootId;try{let t=await fetch(`/api/system/restart`,{method:`POST`,headers:{"x-quickforge-action":`restart`}}),n=await t.json().catch(()=>null);if(!t.ok)throw Error(n?.error||b(`backendRestartFailed`));await this.pollUntilRestarted(e)}catch(e){this.error=e instanceof Error?e.message:b(`backendRestartFailed`),this.message=``,this.restarting=!1,this.requestUpdate()}}statusRows(){return this.status?a`
836
+ `,dt=class extends d{status;loading=!0;restarting=!1;message=``;error=``;terminalShellConfig={terminalShell:`auto`,defaultProfileId:`auto`,profiles:[]};customShellCommand=``;getTabName(){return w(`backendService`)}async connectedCallback(){super.connectedCallback(),await Promise.all([this.loadStatus(),this.loadTerminalShell()])}customShellProfiles(){return this.terminalShellConfig.profiles.filter(e=>!e.builtin)}async loadTerminalShell(){try{let e=await fetch(`/api/system/terminal-shell`,{cache:`no-store`}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||w(`requestFailed`));this.terminalShellConfig={terminalShell:t?.terminalShell||`auto`,defaultProfileId:t?.defaultProfileId||`auto`,profiles:Array.isArray(t?.profiles)?t.profiles:[]}}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.requestUpdate()}}async saveTerminalShellConfig(e,t=this.customShellProfiles(),n=w(`terminalShellSaved`)){try{let r=await fetch(`/api/system/terminal-shell`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({defaultProfileId:e,profiles:t})}),i=await r.json().catch(()=>null);if(!r.ok)throw Error(i?.error||w(`requestFailed`));this.terminalShellConfig=i,this.message=n,this.error=``}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.requestUpdate()}}async addCustomTerminalShell(){let e=this.customShellCommand.trim();if(!e){this.error=w(`terminalShellProfileRequired`),this.requestUpdate();return}let t=[...this.customShellProfiles(),{id:ot(),name:st(e),command:e,builtin:!1}];this.customShellCommand=``,await this.saveTerminalShellConfig(this.terminalShellConfig.defaultProfileId,t,w(`terminalShellProfilesSaved`))}async deleteCustomTerminalShell(e){let t=this.terminalShellConfig.profiles.find(t=>t.id===e);if(!t||t.builtin||!await v({description:w(`terminalShellDeleteConfirm`,{name:t.name}),confirmLabel:w(`confirmDelete`),cancelLabel:w(`cancel`),variant:`destructive`}))return;let n=this.customShellProfiles().filter(t=>t.id!==e),r=this.terminalShellConfig.defaultProfileId===e?`auto`:this.terminalShellConfig.defaultProfileId;await this.saveTerminalShellConfig(r,n,w(`terminalShellProfilesSaved`))}async loadStatus(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=await fetch(`/api/health`,{cache:`no-store`}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||w(`requestFailed`));this.status=t}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}async pollUntilRestarted(e){let t=Date.now();for(;Date.now()-t<nt;){await it(rt);try{let t=await fetch(`/api/health?restartPoll=${Date.now()}`,{cache:`no-store`}),n=await t.json().catch(()=>null);if(t.ok&&n?.ok&&n.bootId&&n.bootId!==e){this.message=w(`backendRestarted`),this.requestUpdate(),window.setTimeout(()=>window.location.reload(),300);return}}catch{}}throw Error(w(`backendRestartTimeout`))}async restartService(){if(!this.status||this.restarting||!await v({description:w(`restartBackendConfirm`),confirmLabel:w(`restartBackendService`),cancelLabel:w(`cancel`)}))return;this.restarting=!0,this.message=w(`backendRestarting`),this.error=``,this.requestUpdate();let e=this.status.bootId;try{let t=await fetch(`/api/system/restart`,{method:`POST`,headers:{"x-quickforge-action":`restart`}}),n=await t.json().catch(()=>null);if(!t.ok)throw Error(n?.error||w(`backendRestartFailed`));await this.pollUntilRestarted(e)}catch(e){this.error=e instanceof Error?e.message:w(`backendRestartFailed`),this.message=``,this.restarting=!1,this.requestUpdate()}}statusRows(){return this.status?u`
837
837
  <dl class="grid gap-3 text-sm">
838
- ${[[b(`serviceMode`),this.status.mode],[b(`servicePid`),String(this.status.pid)],[b(`serviceStartedAt`),Ue(this.status.startedAt)],[b(`serviceDataDir`),this.status.dataDir],[b(`serviceWorkspace`),this.status.workspaceRoot]].map(([e,t])=>a`
838
+ ${[[w(`serviceMode`),this.status.mode],[w(`servicePid`),String(this.status.pid)],[w(`serviceStartedAt`),at(this.status.startedAt)],[w(`serviceDataDir`),this.status.dataDir],[w(`serviceWorkspace`),this.status.workspaceRoot]].map(([e,t])=>u`
839
839
  <div class="grid gap-1 sm:grid-cols-[120px_1fr] sm:gap-3">
840
840
  <dt class="text-muted-foreground">${e}</dt>
841
841
  <dd class="min-w-0 break-all text-foreground">${t}</dd>
842
842
  </div>
843
843
  `)}
844
844
  </dl>
845
- `:null}shellProfileRow(e,t=!1){let n=e.id===this.terminalShellConfig.defaultProfileId||this.terminalShellConfig.defaultProfileId===`auto`&&t;return a`
845
+ `:null}shellProfileRow(e,t=!1){let n=e.id===this.terminalShellConfig.defaultProfileId||this.terminalShellConfig.defaultProfileId===`auto`&&t;return u`
846
846
  <div class="flex min-w-0 items-center gap-3 border-b px-1.5 py-2 last:border-b-0 hover:bg-muted/5" style="border-bottom-color: color-mix(in oklab, var(--border) 32%, transparent);">
847
847
  <div class="min-w-0 flex-1">
848
848
  <div class="truncate text-sm font-medium text-foreground/90">${e.name}</div>
849
849
  <div class="truncate font-mono text-xs text-muted-foreground/55" title=${e.command}>${e.command}</div>
850
850
  </div>
851
851
  <div class="flex shrink-0 items-center gap-1">
852
- ${n?a`
853
- <span class="inline-flex size-7 items-center justify-center rounded-md text-emerald-500/85" title=${b(`terminalShellDefaultBadge`)} aria-label=${b(`terminalShellDefaultBadge`)}>
854
- ${Ke}
852
+ ${n?u`
853
+ <span class="inline-flex size-7 items-center justify-center rounded-md text-emerald-500/85" title=${w(`terminalShellDefaultBadge`)} aria-label=${w(`terminalShellDefaultBadge`)}>
854
+ ${ct}
855
855
  </span>
856
- `:a`
856
+ `:u`
857
857
  <button
858
858
  class="inline-flex size-7 items-center justify-center rounded-md text-muted-foreground/55 hover:bg-muted/20 hover:text-foreground/85"
859
859
  type="button"
860
- title=${b(`terminalShellSetDefault`)}
861
- aria-label=${b(`terminalShellSetDefault`)}
860
+ title=${w(`terminalShellSetDefault`)}
861
+ aria-label=${w(`terminalShellSetDefault`)}
862
862
  @click=${()=>this.saveTerminalShellConfig(e.id)}
863
863
  >
864
- ${qe}
864
+ ${lt}
865
865
  </button>
866
866
  `}
867
- ${e.builtin?null:a`
867
+ ${e.builtin?null:u`
868
868
  <button
869
869
  class="inline-flex size-7 items-center justify-center rounded-md text-muted-foreground/55 hover:bg-destructive/10 hover:text-destructive"
870
870
  type="button"
871
- title=${b(`delete`)}
872
- aria-label=${b(`delete`)}
871
+ title=${w(`delete`)}
872
+ aria-label=${w(`delete`)}
873
873
  @click=${()=>this.deleteCustomTerminalShell(e.id)}
874
874
  >
875
- ${Je}
875
+ ${ut}
876
876
  </button>
877
877
  `}
878
878
  </div>
879
879
  </div>
880
- `}terminalShellSettings(){let e=this.terminalShellConfig.profiles;return a`
880
+ `}terminalShellSettings(){let e=this.terminalShellConfig.profiles;return u`
881
881
  <section class="rounded-lg border border-border p-4">
882
882
  <div>
883
883
  <h4 class="inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
884
- ${b(`terminalShell`)}
885
- <quickforge-info-tip .label=${b(`terminalShellDescription`)}></quickforge-info-tip>
884
+ ${w(`terminalShell`)}
885
+ <quickforge-info-tip .label=${w(`terminalShellDescription`)}></quickforge-info-tip>
886
886
  </h4>
887
- <p class="mt-1 text-xs text-muted-foreground/60">${b(`terminalShellAutoDetectedHint`)}</p>
887
+ <p class="mt-1 text-xs text-muted-foreground/60">${w(`terminalShellAutoDetectedHint`)}</p>
888
888
  </div>
889
889
 
890
890
  <div class="mt-4 overflow-hidden rounded-lg border bg-transparent" style="border-color: color-mix(in oklab, var(--border) 36%, transparent);">
891
- ${e.length>0?e.map((e,t)=>this.shellProfileRow(e,t===0)):a`<div class="px-2 py-3 text-sm text-muted-foreground">${b(`terminalShellNoDetected`)}</div>`}
891
+ ${e.length>0?e.map((e,t)=>this.shellProfileRow(e,t===0)):u`<div class="px-2 py-3 text-sm text-muted-foreground">${w(`terminalShellNoDetected`)}</div>`}
892
892
  </div>
893
893
 
894
894
  <div class="mt-3 grid gap-2 sm:grid-cols-[1fr_auto] sm:items-end">
895
895
  <label class="grid gap-1 text-sm">
896
- <span class="text-xs text-muted-foreground/70">${b(`terminalShellCommand`)}</span>
896
+ <span class="text-xs text-muted-foreground/70">${w(`terminalShellCommand`)}</span>
897
897
  <input
898
898
  class="h-9 rounded-md border border-border bg-background px-3 font-mono text-sm text-foreground outline-none focus:border-ring"
899
899
  type="text"
900
900
  .value=${this.customShellCommand}
901
- placeholder=${b(`terminalShellCommandPlaceholder`)}
901
+ placeholder=${w(`terminalShellCommandPlaceholder`)}
902
902
  @input=${e=>{this.customShellCommand=e.target.value}}
903
903
  />
904
904
  </label>
905
905
  <button
906
906
  class="h-9 rounded-md bg-primary px-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-60"
907
907
  type="button"
908
- title=${b(`terminalShellAdd`)}
909
- aria-label=${b(`terminalShellAdd`)}
908
+ title=${w(`terminalShellAdd`)}
909
+ aria-label=${w(`terminalShellAdd`)}
910
910
  @click=${()=>this.addCustomTerminalShell()}
911
911
  >
912
- ${b(`terminalShellAdd`)}
912
+ ${w(`terminalShellAdd`)}
913
913
  </button>
914
914
  </div>
915
915
  </section>
916
- `}render(){if(this.loading)return a`<div class="text-sm text-muted-foreground">${b(`loading`)}</div>`;let e=this.status?.restartUnsupportedReason||b(`backendRestartUnsupported`),t=this.restarting||!this.status?.restartSupported;return a`
916
+ `}render(){if(this.loading)return u`<div class="text-sm text-muted-foreground">${w(`loading`)}</div>`;let e=this.status?.restartUnsupportedReason||w(`backendRestartUnsupported`),t=this.restarting||!this.status?.restartSupported;return u`
917
917
  <div class="flex flex-col gap-6">
918
918
  <div>
919
919
  <h3 class="mb-2 inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
920
- ${b(`backendService`)}
921
- <quickforge-info-tip .label=${b(`backendServiceDescription`)}></quickforge-info-tip>
920
+ ${w(`backendService`)}
921
+ <quickforge-info-tip .label=${w(`backendServiceDescription`)}></quickforge-info-tip>
922
922
  </h3>
923
923
  </div>
924
924
 
925
925
  <section class="rounded-lg border border-border p-4">
926
- <h4 class="text-sm font-semibold text-foreground">${b(`backendServiceStatus`)}</h4>
926
+ <h4 class="text-sm font-semibold text-foreground">${w(`backendServiceStatus`)}</h4>
927
927
  <div class="mt-4">${this.statusRows()}</div>
928
928
  </section>
929
929
 
@@ -931,11 +931,11 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
931
931
 
932
932
  <section class="rounded-lg border border-border p-4">
933
933
  <h4 class="inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
934
- ${b(`restartBackendService`)}
935
- <quickforge-info-tip .label=${b(`restartBackendServiceDescription`)}></quickforge-info-tip>
934
+ ${w(`restartBackendService`)}
935
+ <quickforge-info-tip .label=${w(`restartBackendServiceDescription`)}></quickforge-info-tip>
936
936
  </h4>
937
937
 
938
- ${this.status?.restartSupported?null:a`<div class="mt-4 rounded-md border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-sm text-amber-700 dark:text-amber-300">${e}</div>`}
938
+ ${this.status?.restartSupported?null:u`<div class="mt-4 rounded-md border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-sm text-amber-700 dark:text-amber-300">${e}</div>`}
939
939
 
940
940
  <button
941
941
  class="mt-4 rounded-md bg-destructive px-3 py-2 text-sm text-destructive-foreground disabled:opacity-60"
@@ -943,44 +943,44 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
943
943
  ?disabled=${t}
944
944
  @click=${()=>this.restartService()}
945
945
  >
946
- ${this.restarting?b(`backendRestarting`):b(`restartBackendService`)}
946
+ ${this.restarting?w(`backendRestarting`):w(`restartBackendService`)}
947
947
  </button>
948
948
  </section>
949
949
 
950
- ${this.message?a`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
951
- ${this.error?a`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
950
+ ${this.message?u`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
951
+ ${this.error?u`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
952
952
  </div>
953
- `}},U=`quickforge-service-settings-tab`;customElements.get(U)||customElements.define(U,Ye);function Xe(){return document.createElement(U)}function Ze(){return Array.from({length:16},()=>`ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%^&*`[Math.floor(Math.random()*65)]).join(``)}var Qe=class extends o{loading=!0;saving=!1;enabled=!1;hasPassword=!1;password=``;sessionTtlHours=12;activeTokenCount=0;lanUrls=[];error=``;message=``;getTabName(){return b(`lanAccess`)}async connectedCallback(){super.connectedCallback(),await this.loadStatus()}async request(e,t){let n=await fetch(e,{...t,cache:`no-store`,headers:{...t?.body?{"content-type":`application/json`}:void 0,...t?.headers}}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||b(`requestFailed`));return r}applyStatus(e){this.enabled=!!e.enabled,this.hasPassword=!!e.hasPassword,this.sessionTtlHours=Number(e.sessionTtlHours||12),this.activeTokenCount=Number(e.activeTokenCount||0),this.lanUrls=Array.isArray(e.lanUrls)?e.lanUrls:[]}async loadStatus(){this.loading=!0,this.error=``,this.requestUpdate();try{this.applyStatus(await this.request(`/api/lan-access/status`))}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}updatePassword(e){this.password=e,this.requestUpdate()}updateEnabled(e){this.enabled=e,this.requestUpdate()}updateTtl(e){this.sessionTtlHours=Number(e)||12,this.requestUpdate()}async saveSettings(){if(!this.saving){if(this.enabled&&!this.hasPassword&&!this.password.trim()){this.error=b(`lanAccessPasswordRequired`),this.requestUpdate();return}if(this.password.trim()&&this.password.trim().length<8){this.error=b(`lanAccessPasswordTooShort`),this.requestUpdate();return}if(!(this.enabled&&!await m({description:b(`lanAccessEnableConfirm`),confirmLabel:b(`enabled`),cancelLabel:b(`cancel`)}))){this.saving=!0,this.error=``,this.message=``,this.requestUpdate();try{let e=await this.request(`/api/lan-access/settings`,{method:`PUT`,body:JSON.stringify({enabled:this.enabled,password:this.password.trim()||void 0,sessionTtlHours:this.sessionTtlHours})});this.applyStatus(e),this.password=``,this.message=b(`lanAccessSaved`)}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.saving=!1,this.requestUpdate()}}}}async revokeAll(){if(await m({description:b(`lanAccessRevokeAllConfirm`),confirmLabel:b(`lanAccessRevokeAll`),cancelLabel:b(`cancel`),variant:`destructive`})){this.saving=!0,this.error=``,this.message=``,this.requestUpdate();try{let e=await this.request(`/api/lan-access/revoke-all`,{method:`POST`});this.applyStatus(e),this.message=b(`lanAccessRevoked`)}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.saving=!1,this.requestUpdate()}}}render(){return this.loading?a`<div class="text-sm text-muted-foreground">${b(`loading`)}</div>`:a`
953
+ `}},U=`quickforge-service-settings-tab`;customElements.get(U)||customElements.define(U,dt);function ft(){return document.createElement(U)}function pt(){return Array.from({length:16},()=>`ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%^&*`[Math.floor(Math.random()*65)]).join(``)}var mt=class extends d{loading=!0;saving=!1;enabled=!1;hasPassword=!1;password=``;sessionTtlHours=12;activeTokenCount=0;lanUrls=[];error=``;message=``;getTabName(){return w(`lanAccess`)}async connectedCallback(){super.connectedCallback(),await this.loadStatus()}async request(e,t){let n=await fetch(e,{...t,cache:`no-store`,headers:{...t?.body?{"content-type":`application/json`}:void 0,...t?.headers}}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||w(`requestFailed`));return r}applyStatus(e){this.enabled=!!e.enabled,this.hasPassword=!!e.hasPassword,this.sessionTtlHours=Number(e.sessionTtlHours||12),this.activeTokenCount=Number(e.activeTokenCount||0),this.lanUrls=Array.isArray(e.lanUrls)?e.lanUrls:[]}async loadStatus(){this.loading=!0,this.error=``,this.requestUpdate();try{this.applyStatus(await this.request(`/api/lan-access/status`))}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}updatePassword(e){this.password=e,this.requestUpdate()}updateEnabled(e){this.enabled=e,this.requestUpdate()}updateTtl(e){this.sessionTtlHours=Number(e)||12,this.requestUpdate()}async saveSettings(){if(!this.saving){if(this.enabled&&!this.hasPassword&&!this.password.trim()){this.error=w(`lanAccessPasswordRequired`),this.requestUpdate();return}if(this.password.trim()&&this.password.trim().length<8){this.error=w(`lanAccessPasswordTooShort`),this.requestUpdate();return}if(!(this.enabled&&!await v({description:w(`lanAccessEnableConfirm`),confirmLabel:w(`enabled`),cancelLabel:w(`cancel`)}))){this.saving=!0,this.error=``,this.message=``,this.requestUpdate();try{let e=await this.request(`/api/lan-access/settings`,{method:`PUT`,body:JSON.stringify({enabled:this.enabled,password:this.password.trim()||void 0,sessionTtlHours:this.sessionTtlHours})});this.applyStatus(e),this.password=``,this.message=w(`lanAccessSaved`)}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.saving=!1,this.requestUpdate()}}}}async revokeAll(){if(await v({description:w(`lanAccessRevokeAllConfirm`),confirmLabel:w(`lanAccessRevokeAll`),cancelLabel:w(`cancel`),variant:`destructive`})){this.saving=!0,this.error=``,this.message=``,this.requestUpdate();try{let e=await this.request(`/api/lan-access/revoke-all`,{method:`POST`});this.applyStatus(e),this.message=w(`lanAccessRevoked`)}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.saving=!1,this.requestUpdate()}}}render(){return this.loading?u`<div class="text-sm text-muted-foreground">${w(`loading`)}</div>`:u`
954
954
  <div class="flex flex-col gap-6">
955
955
  <div>
956
956
  <h3 class="mb-2 inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
957
- ${b(`lanAccess`)}
958
- <quickforge-info-tip .label=${b(`lanAccessDescription`)}></quickforge-info-tip>
957
+ ${w(`lanAccess`)}
958
+ <quickforge-info-tip .label=${w(`lanAccessDescription`)}></quickforge-info-tip>
959
959
  </h3>
960
960
  </div>
961
961
 
962
962
  <section class="rounded-lg border border-amber-500/30 bg-amber-500/10 p-4 text-sm text-amber-800 dark:text-amber-200">
963
- ${b(`lanAccessRiskWarning`)}
963
+ ${w(`lanAccessRiskWarning`)}
964
964
  </section>
965
965
 
966
966
  <section class="rounded-lg border border-border p-4">
967
- <h4 class="text-sm font-semibold text-foreground">${b(`lanAccessStatus`)}</h4>
967
+ <h4 class="text-sm font-semibold text-foreground">${w(`lanAccessStatus`)}</h4>
968
968
  <dl class="mt-4 grid gap-3 text-sm">
969
969
  <div class="grid gap-1 sm:grid-cols-[140px_1fr] sm:gap-3">
970
- <dt class="text-muted-foreground">${b(`lanAccessEnabled`)}</dt>
971
- <dd>${this.enabled?b(`enabled`):b(`disabled`)}</dd>
970
+ <dt class="text-muted-foreground">${w(`lanAccessEnabled`)}</dt>
971
+ <dd>${this.enabled?w(`enabled`):w(`disabled`)}</dd>
972
972
  </div>
973
973
  <div class="grid gap-1 sm:grid-cols-[140px_1fr] sm:gap-3">
974
- <dt class="text-muted-foreground">${b(`lanAccessPassword`)}</dt>
975
- <dd>${this.hasPassword?b(`configured`):b(`notConfigured`)}</dd>
974
+ <dt class="text-muted-foreground">${w(`lanAccessPassword`)}</dt>
975
+ <dd>${this.hasPassword?w(`configured`):w(`notConfigured`)}</dd>
976
976
  </div>
977
977
  <div class="grid gap-1 sm:grid-cols-[140px_1fr] sm:gap-3">
978
- <dt class="text-muted-foreground">${b(`lanAccessActiveDevices`)}</dt>
978
+ <dt class="text-muted-foreground">${w(`lanAccessActiveDevices`)}</dt>
979
979
  <dd>${this.activeTokenCount}</dd>
980
980
  </div>
981
981
  <div class="grid gap-1 sm:grid-cols-[140px_1fr] sm:gap-3">
982
- <dt class="text-muted-foreground">${b(`lanAccessUrls`)}</dt>
983
- <dd class="min-w-0 break-all">${this.lanUrls.length?this.lanUrls.map(e=>a`<div>${e}</div>`):`-`}</dd>
982
+ <dt class="text-muted-foreground">${w(`lanAccessUrls`)}</dt>
983
+ <dd class="min-w-0 break-all">${this.lanUrls.length?this.lanUrls.map(e=>u`<div>${e}</div>`):`-`}</dd>
984
984
  </div>
985
985
  </dl>
986
986
  </section>
@@ -988,37 +988,37 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
988
988
  <section class="rounded-lg border border-border p-4">
989
989
  <label class="flex items-center gap-2 text-sm font-medium text-foreground">
990
990
  <input type="checkbox" .checked=${this.enabled} @change=${e=>this.updateEnabled(e.target.checked)} />
991
- ${b(`lanAccessAllowFull`)}
991
+ ${w(`lanAccessAllowFull`)}
992
992
  </label>
993
993
 
994
994
  <label class="mt-4 block text-sm font-medium text-foreground">
995
- ${b(`lanAccessPassword`)}
995
+ ${w(`lanAccessPassword`)}
996
996
  <div class="mt-2 flex flex-col gap-3 sm:flex-row">
997
- <input class="h-10 min-w-0 flex-1 rounded-md border border-input bg-background px-3 text-sm" type="password" .value=${this.password} @input=${e=>this.updatePassword(e.target.value)} placeholder=${this.hasPassword?b(`lanAccessPasswordPlaceholderConfigured`):b(`lanAccessPasswordPlaceholder`)} />
998
- <button class="rounded-md border border-input px-3 py-2 text-sm" type="button" @click=${()=>this.updatePassword(Ze())}>${b(`generatePassword`)}</button>
997
+ <input class="h-10 min-w-0 flex-1 rounded-md border border-input bg-background px-3 text-sm" type="password" .value=${this.password} @input=${e=>this.updatePassword(e.target.value)} placeholder=${this.hasPassword?w(`lanAccessPasswordPlaceholderConfigured`):w(`lanAccessPasswordPlaceholder`)} />
998
+ <button class="rounded-md border border-input px-3 py-2 text-sm" type="button" @click=${()=>this.updatePassword(pt())}>${w(`generatePassword`)}</button>
999
999
  </div>
1000
1000
  </label>
1001
1001
 
1002
1002
  <label class="mt-4 block text-sm font-medium text-foreground">
1003
- ${b(`lanAccessSessionTtl`)}
1003
+ ${w(`lanAccessSessionTtl`)}
1004
1004
  <select class="mt-2 h-10 w-full rounded-md border border-input bg-background px-3 text-sm" .value=${String(this.sessionTtlHours)} @change=${e=>this.updateTtl(e.target.value)}>
1005
- <option value="1">1 ${b(`hour`)}</option>
1006
- <option value="12">12 ${b(`hours`)}</option>
1007
- <option value="24">24 ${b(`hours`)}</option>
1008
- <option value="168">7 ${b(`days`)}</option>
1005
+ <option value="1">1 ${w(`hour`)}</option>
1006
+ <option value="12">12 ${w(`hours`)}</option>
1007
+ <option value="24">24 ${w(`hours`)}</option>
1008
+ <option value="168">7 ${w(`days`)}</option>
1009
1009
  </select>
1010
1010
  </label>
1011
1011
 
1012
1012
  <div class="mt-4 flex flex-wrap gap-2">
1013
- <button class="rounded-md bg-primary px-3 py-2 text-sm text-primary-foreground disabled:opacity-60" type="button" ?disabled=${this.saving} @click=${()=>this.saveSettings()}>${this.saving?b(`saving`):b(`save`)}</button>
1014
- <button class="rounded-md border border-destructive/40 px-3 py-2 text-sm text-destructive disabled:opacity-60" type="button" ?disabled=${this.saving} @click=${()=>this.revokeAll()}>${b(`lanAccessRevokeAll`)}</button>
1013
+ <button class="rounded-md bg-primary px-3 py-2 text-sm text-primary-foreground disabled:opacity-60" type="button" ?disabled=${this.saving} @click=${()=>this.saveSettings()}>${this.saving?w(`saving`):w(`save`)}</button>
1014
+ <button class="rounded-md border border-destructive/40 px-3 py-2 text-sm text-destructive disabled:opacity-60" type="button" ?disabled=${this.saving} @click=${()=>this.revokeAll()}>${w(`lanAccessRevokeAll`)}</button>
1015
1015
  </div>
1016
1016
  </section>
1017
1017
 
1018
- ${this.message?a`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
1019
- ${this.error?a`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
1018
+ ${this.message?u`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
1019
+ ${this.error?u`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
1020
1020
  </div>
1021
- `}},W=`quickforge-lan-access-settings-tab`;customElements.get(W)||customElements.define(W,Qe);function $e(){return document.createElement(W)}var et=18e4,tt=1e3;function nt(e){return new Promise(t=>window.setTimeout(t,e))}var rt=[{value:`startup`,label:()=>b(`frequencyStartup`)},{value:`daily`,label:()=>b(`frequencyDaily`)},{value:`weekly`,label:()=>b(`frequencyWeekly`)},{value:`off`,label:()=>b(`frequencyOff`)}],it=class extends o{about;updateInfo;loading=!0;checking=!1;updating=!1;message=``;error=``;frequency=ce.frequency;lastCheckAt=null;getTabName(){return b(`about`)}async connectedCallback(){super.connectedCallback(),await this.loadAbout()}async loadAbout(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=await fetch(`/api/system/about`,{cache:`no-store`}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||b(`requestFailed`));this.about=t;try{let e=await v(s());this.frequency=e.frequency,this.lastCheckAt=e.lastCheckAt}catch{}}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}async checkUpdate(){if(!(this.checking||this.updating)){this.checking=!0,this.message=``,this.error=``,this.requestUpdate();try{let e=await fetch(`/api/system/update/check`,{cache:`no-store`}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||b(`updateCheckFailed`));this.updateInfo=t,this.about=t,this.updateInfo.updateAvailable?this.message=b(`updateAvailableMessage`,{current:this.updateInfo.currentVersion,latest:this.updateInfo.latestVersion}):this.updateInfo.localVersionIsNewer?this.message=b(`localVersionNewerMessage`,{current:this.updateInfo.currentVersion,latest:this.updateInfo.latestVersion}):this.message=b(`alreadyLatestVersion`,{version:this.updateInfo.currentVersion})}catch(e){this.error=e instanceof Error?e.message:b(`updateCheckFailed`)}finally{this.checking=!1,this.requestUpdate()}}}async pollUntilUpdated(e){let t=Date.now();for(;Date.now()-t<et;){await nt(tt);try{let t=await fetch(`/api/health?updatePoll=${Date.now()}`,{cache:`no-store`}),n=await t.json().catch(()=>null);if(t.ok&&n?.ok&&n.bootId&&n.bootId!==e){this.message=b(`updateRestarted`),this.requestUpdate(),window.setTimeout(()=>window.location.reload(),300);return}}catch{}}throw Error(b(`updateRestartTimeout`))}async updateQuickForge(){if(!(!this.updateInfo?.updateAvailable||this.updating)&&await m({description:b(`updateConfirm`,{command:this.updateInfo.installCommand}),confirmLabel:b(`updateNow`),cancelLabel:b(`cancel`)})){this.updating=!0,this.message=b(`updatingQuickForge`),this.error=``,this.requestUpdate();try{let e=await fetch(`/api/system/update`,{method:`POST`,headers:{"x-quickforge-action":`update`}}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||b(`updateFailed`));if(this.updateInfo=t,t?.updateStarted){let e=t.logFile?` ${b(`updateLogFile`,{path:t.logFile})}`:``;this.message=`${b(`updateStarted`)}${e}`,this.requestUpdate(),await this.pollUntilUpdated(t.bootId)}else this.message=t?.updated?b(`updateCompleted`):b(`alreadyLatestVersion`,{version:t?.currentVersion||this.about?.version||`-`}),this.updating=!1}catch(e){this.error=e instanceof Error?e.message:b(`updateFailed`),this.message=``,this.updating=!1}finally{this.requestUpdate()}}}async selectFrequency(e){if(this.frequency!==e){this.frequency=e,this.requestUpdate();try{let t=s();await pe(t,{...await v(t),frequency:e}),this.error=``}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.requestUpdate()}}}renderFrequencyOption(e){return a`
1021
+ `}},W=`quickforge-lan-access-settings-tab`;customElements.get(W)||customElements.define(W,mt);function ht(){return document.createElement(W)}var gt=18e4,_t=1e3;function vt(e){return new Promise(t=>window.setTimeout(t,e))}var yt=[{value:`startup`,label:()=>w(`frequencyStartup`)},{value:`daily`,label:()=>w(`frequencyDaily`)},{value:`weekly`,label:()=>w(`frequencyWeekly`)},{value:`off`,label:()=>w(`frequencyOff`)}],bt=class extends d{about;updateInfo;loading=!0;checking=!1;updating=!1;message=``;error=``;frequency=be.frequency;lastCheckAt=null;getTabName(){return w(`about`)}async connectedCallback(){super.connectedCallback(),await this.loadAbout()}async loadAbout(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=await fetch(`/api/system/about`,{cache:`no-store`}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||w(`requestFailed`));this.about=t;try{let e=await S(f());this.frequency=e.frequency,this.lastCheckAt=e.lastCheckAt}catch{}}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}async checkUpdate(){if(!(this.checking||this.updating)){this.checking=!0,this.message=``,this.error=``,this.requestUpdate();try{let e=await fetch(`/api/system/update/check`,{cache:`no-store`}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||w(`updateCheckFailed`));this.updateInfo=t,this.about=t,this.updateInfo.updateAvailable?this.message=w(`updateAvailableMessage`,{current:this.updateInfo.currentVersion,latest:this.updateInfo.latestVersion}):this.updateInfo.localVersionIsNewer?this.message=w(`localVersionNewerMessage`,{current:this.updateInfo.currentVersion,latest:this.updateInfo.latestVersion}):this.message=w(`alreadyLatestVersion`,{version:this.updateInfo.currentVersion})}catch(e){this.error=e instanceof Error?e.message:w(`updateCheckFailed`)}finally{this.checking=!1,this.requestUpdate()}}}async pollUntilUpdated(e){let t=Date.now();for(;Date.now()-t<gt;){await vt(_t);try{let t=await fetch(`/api/health?updatePoll=${Date.now()}`,{cache:`no-store`}),n=await t.json().catch(()=>null);if(t.ok&&n?.ok&&n.bootId&&n.bootId!==e){this.message=w(`updateRestarted`),this.requestUpdate(),window.setTimeout(()=>window.location.reload(),300);return}}catch{}}throw Error(w(`updateRestartTimeout`))}async updateQuickForge(){if(!(!this.updateInfo?.updateAvailable||this.updating)&&await v({description:w(`updateConfirm`,{command:this.updateInfo.installCommand}),confirmLabel:w(`updateNow`),cancelLabel:w(`cancel`)})){this.updating=!0,this.message=w(`updatingQuickForge`),this.error=``,this.requestUpdate();try{let e=await fetch(`/api/system/update`,{method:`POST`,headers:{"x-quickforge-action":`update`}}),t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||w(`updateFailed`));if(this.updateInfo=t,t?.updateStarted){let e=t.logFile?` ${w(`updateLogFile`,{path:t.logFile})}`:``;this.message=`${w(`updateStarted`)}${e}`,this.requestUpdate(),await this.pollUntilUpdated(t.bootId)}else this.message=t?.updated?w(`updateCompleted`):w(`alreadyLatestVersion`,{version:t?.currentVersion||this.about?.version||`-`}),this.updating=!1}catch(e){this.error=e instanceof Error?e.message:w(`updateFailed`),this.message=``,this.updating=!1}finally{this.requestUpdate()}}}async selectFrequency(e){if(this.frequency!==e){this.frequency=e,this.requestUpdate();try{let t=f();await Te(t,{...await S(t),frequency:e}),this.error=``}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.requestUpdate()}}}renderFrequencyOption(e){return u`
1022
1022
  <button
1023
1023
  type="button"
1024
1024
  class="rounded-md border px-3 py-1.5 text-sm transition-colors ${this.frequency===e.value?`border-primary bg-primary text-primary-foreground`:`border-border bg-background text-foreground hover:bg-accent`}"
@@ -1026,16 +1026,16 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
1026
1026
  >
1027
1027
  ${e.label()}
1028
1028
  </button>
1029
- `}infoRows(){let e=this.about;return e?a`
1029
+ `}infoRows(){let e=this.about;return e?u`
1030
1030
  <dl class="grid gap-3 text-sm">
1031
- ${[[b(`packageName`),e.name],[b(`currentVersion`),e.version]].map(([e,t])=>a`
1031
+ ${[[w(`packageName`),e.name],[w(`currentVersion`),e.version]].map(([e,t])=>u`
1032
1032
  <div class="grid gap-1 sm:grid-cols-[120px_1fr] sm:gap-3">
1033
1033
  <dt class="text-muted-foreground">${e}</dt>
1034
1034
  <dd class="min-w-0 break-all text-foreground">${t}</dd>
1035
1035
  </div>
1036
1036
  `)}
1037
1037
  <div class="grid gap-1 sm:grid-cols-[120px_1fr] sm:gap-3">
1038
- <dt class="text-muted-foreground">${b(`github`)}</dt>
1038
+ <dt class="text-muted-foreground">${w(`github`)}</dt>
1039
1039
  <dd class="min-w-0 break-all">
1040
1040
  <a class="text-primary underline-offset-4 hover:underline" href=${e.repositoryUrl} target="_blank" rel="noreferrer">
1041
1041
  ${e.repositoryUrl}
@@ -1043,50 +1043,50 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
1043
1043
  </dd>
1044
1044
  </div>
1045
1045
  </dl>
1046
- `:null}updateStatus(){return this.updateInfo?a`
1046
+ `:null}updateStatus(){return this.updateInfo?u`
1047
1047
  <div class="mt-4 rounded-lg border bg-transparent p-3 text-sm" style="border-color: color-mix(in oklab, var(--border) 36%, transparent);">
1048
1048
  <div class="grid gap-2 sm:grid-cols-[120px_1fr] sm:gap-3">
1049
- <span class="text-muted-foreground">${b(`latestVersion`)}</span>
1049
+ <span class="text-muted-foreground">${w(`latestVersion`)}</span>
1050
1050
  <span class="text-foreground">${this.updateInfo.latestVersion}</span>
1051
1051
  </div>
1052
1052
  <div class="mt-2 grid gap-2 sm:grid-cols-[120px_1fr] sm:gap-3">
1053
- <span class="text-muted-foreground">${b(`updateCommand`)}</span>
1053
+ <span class="text-muted-foreground">${w(`updateCommand`)}</span>
1054
1054
  <code class="min-w-0 break-all rounded bg-muted/20 px-1.5 py-0.5 font-mono text-xs text-foreground/90">${this.updateInfo.installCommand}</code>
1055
1055
  </div>
1056
- ${this.updateInfo.logFile?a`
1056
+ ${this.updateInfo.logFile?u`
1057
1057
  <div class="mt-2 grid gap-2 sm:grid-cols-[120px_1fr] sm:gap-3">
1058
- <span class="text-muted-foreground">${b(`updateLog`)}</span>
1058
+ <span class="text-muted-foreground">${w(`updateLog`)}</span>
1059
1059
  <code class="min-w-0 break-all rounded bg-muted/20 px-1.5 py-0.5 font-mono text-xs text-foreground/90">${this.updateInfo.logFile}</code>
1060
1060
  </div>
1061
1061
  `:null}
1062
1062
  </div>
1063
- `:null}render(){if(this.loading)return a`<div class="text-sm text-muted-foreground">${b(`loading`)}</div>`;let e=this.checking||this.updating||!this.updateInfo?.updateAvailable;return a`
1063
+ `:null}render(){if(this.loading)return u`<div class="text-sm text-muted-foreground">${w(`loading`)}</div>`;let e=this.checking||this.updating||!this.updateInfo?.updateAvailable;return u`
1064
1064
  <div class="flex flex-col gap-6">
1065
1065
  <div>
1066
1066
  <h3 class="mb-2 inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
1067
- ${b(`aboutQuickForge`)}
1068
- <quickforge-info-tip .label=${b(`aboutQuickForgeDescription`)}></quickforge-info-tip>
1067
+ ${w(`aboutQuickForge`)}
1068
+ <quickforge-info-tip .label=${w(`aboutQuickForgeDescription`)}></quickforge-info-tip>
1069
1069
  </h3>
1070
1070
  </div>
1071
1071
 
1072
1072
  <section class="rounded-lg border border-border p-4">
1073
- <h4 class="text-sm font-semibold text-foreground">${b(`projectInfo`)}</h4>
1073
+ <h4 class="text-sm font-semibold text-foreground">${w(`projectInfo`)}</h4>
1074
1074
  <div class="mt-4">${this.infoRows()}</div>
1075
1075
  </section>
1076
1076
 
1077
1077
  <section class="rounded-lg border border-border p-4">
1078
1078
  <h4 class="inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
1079
- ${b(`checkUpdate`)}
1080
- <quickforge-info-tip .label=${b(`checkUpdateDescription`)}></quickforge-info-tip>
1079
+ ${w(`checkUpdate`)}
1080
+ <quickforge-info-tip .label=${w(`checkUpdateDescription`)}></quickforge-info-tip>
1081
1081
  </h4>
1082
1082
 
1083
1083
  <div class="mt-4">
1084
- <div class="text-sm font-medium text-foreground">${b(`updateFrequencySection`)}</div>
1085
- <div class="mt-1 text-xs text-muted-foreground">${b(`updateFrequencyDescription`)}</div>
1084
+ <div class="text-sm font-medium text-foreground">${w(`updateFrequencySection`)}</div>
1085
+ <div class="mt-1 text-xs text-muted-foreground">${w(`updateFrequencyDescription`)}</div>
1086
1086
  <div class="mt-2 flex flex-wrap gap-2">
1087
- ${rt.map(e=>this.renderFrequencyOption(e))}
1087
+ ${yt.map(e=>this.renderFrequencyOption(e))}
1088
1088
  </div>
1089
- <div class="mt-2 text-xs text-muted-foreground">${this.lastCheckAt?b(`lastCheckedAt`,{time:new Date(this.lastCheckAt).toLocaleString(S())}):b(`lastCheckedNever`)}</div>
1089
+ <div class="mt-2 text-xs text-muted-foreground">${this.lastCheckAt?w(`lastCheckedAt`,{time:new Date(this.lastCheckAt).toLocaleString(E())}):w(`lastCheckedNever`)}</div>
1090
1090
  </div>
1091
1091
 
1092
1092
  <div class="my-4 border-t border-border"></div>
@@ -1100,7 +1100,7 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
1100
1100
  ?disabled=${this.checking||this.updating}
1101
1101
  @click=${()=>this.checkUpdate()}
1102
1102
  >
1103
- ${this.checking?b(`checkingUpdate`):b(`checkUpdate`)}
1103
+ ${this.checking?w(`checkingUpdate`):w(`checkUpdate`)}
1104
1104
  </button>
1105
1105
  <button
1106
1106
  class="rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-60"
@@ -1108,56 +1108,56 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
1108
1108
  ?disabled=${e}
1109
1109
  @click=${()=>this.updateQuickForge()}
1110
1110
  >
1111
- ${this.updating?b(`updatingQuickForge`):b(`updateNow`)}
1111
+ ${this.updating?w(`updatingQuickForge`):w(`updateNow`)}
1112
1112
  </button>
1113
1113
  </div>
1114
1114
  </section>
1115
1115
 
1116
- ${this.message?a`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
1117
- ${this.error?a`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
1116
+ ${this.message?u`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
1117
+ ${this.error?u`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
1118
1118
  </div>
1119
- `}},G=`quickforge-about-settings-tab`;customElements.get(G)||customElements.define(G,it);function at(){return document.createElement(G)}var ot=class extends o{loading=!0;saving=!1;saved=!1;error=``;message=``;projects=[];project;commandDir=``;commands=[];loadingCommands=!1;getTabName(){return b(`projectCommands`)}async connectedCallback(){super.connectedCallback(),await this.loadProjects()}async request(e,t){let n=await fetch(e,{...t,cache:`no-store`,headers:{...t?.body?{"content-type":`application/json`}:void 0,...t?.headers}}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||b(`requestFailed`));return r}async loadProjects(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=await this.request(`/api/project`);this.projects=e?.projects??(e?.project?[e.project]:[]),this.project=e?.project??this.projects[0],this.commandDir=typeof this.project?.commandDir==`string`?this.project.commandDir:``,await this.loadCommands()}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}selectProject(e){let t=e.target,n=this.projects.find(e=>e.id===t.value);n&&(this.project=n,this.commandDir=typeof n.commandDir==`string`?n.commandDir:``,this.saved=!1,this.message=``,this.error=``,this.commands=[],this.requestUpdate(),this.loadCommands())}async loadCommands(){if(this.project?.id){this.loadingCommands=!0,this.requestUpdate();try{let e=await this.request(`/api/project/commands?projectId=${encodeURIComponent(this.project.id)}`);this.commands=e?.commands??[]}catch{this.commands=[]}finally{this.loadingCommands=!1,this.requestUpdate()}}}updateCommandDir(e){this.commandDir=e,this.saved=!1,this.message=``,this.requestUpdate()}async save(){if(!(!this.project||this.saving)){this.saving=!0,this.saved=!1,this.error=``,this.message=``,this.requestUpdate();try{let e=await this.request(`/api/project/${encodeURIComponent(this.project.id)}/command-dir`,{method:`PUT`,body:JSON.stringify({commandDir:this.commandDir})});if(this.project=e?.project??this.project,this.project){let e=this.projects.findIndex(e=>e.id===this.project.id);e>=0&&(this.projects[e]=this.project)}this.commandDir=typeof this.project?.commandDir==`string`?this.project.commandDir:``,this.saved=!0,await this.loadCommands()}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.saving=!1,this.requestUpdate()}}}async openCommandDir(){if(this.project){this.error=``,this.message=``,this.requestUpdate();try{await this.request(`/api/project/open-path`,{method:`POST`,body:JSON.stringify({path:`.ai/commands`,projectId:this.project.id})})}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`),this.requestUpdate()}}}async createCommand(){if(!this.project)return;let e=window.prompt(b(`newCommandPrompt`));if(e?.trim()){this.error=``,this.message=``,this.requestUpdate();try{let t=await this.request(`/api/project/command`,{method:`POST`,body:JSON.stringify({name:e.trim(),projectId:this.project.id})});t.ok?(this.message=b(`commandCreated`,{name:t.name??e.trim()}),await this.loadCommands()):t.reason===`exists`?this.error=b(`commandAlreadyExists`,{name:t.name??e.trim()}):this.error=b(`invalidCommandName`)}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.requestUpdate()}}}render(){return this.loading?a`<div class="text-sm text-muted-foreground">${b(`loading`)}</div>`:this.projects.length===0?a`
1119
+ `}},G=`quickforge-about-settings-tab`;customElements.get(G)||customElements.define(G,bt);function xt(){return document.createElement(G)}var St=class extends d{loading=!0;saving=!1;saved=!1;error=``;message=``;projects=[];project;commandDir=``;commands=[];loadingCommands=!1;getTabName(){return w(`projectCommands`)}async connectedCallback(){super.connectedCallback(),await this.loadProjects()}async request(e,t){let n=await fetch(e,{...t,cache:`no-store`,headers:{...t?.body?{"content-type":`application/json`}:void 0,...t?.headers}}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||w(`requestFailed`));return r}async loadProjects(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=await this.request(`/api/project`);this.projects=e?.projects??(e?.project?[e.project]:[]),this.project=e?.project??this.projects[0],this.commandDir=typeof this.project?.commandDir==`string`?this.project.commandDir:``,await this.loadCommands()}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}selectProject(e){let t=e.target,n=this.projects.find(e=>e.id===t.value);n&&(this.project=n,this.commandDir=typeof n.commandDir==`string`?n.commandDir:``,this.saved=!1,this.message=``,this.error=``,this.commands=[],this.requestUpdate(),this.loadCommands())}async loadCommands(){if(this.project?.id){this.loadingCommands=!0,this.requestUpdate();try{let e=await this.request(`/api/project/commands?projectId=${encodeURIComponent(this.project.id)}`);this.commands=e?.commands??[]}catch{this.commands=[]}finally{this.loadingCommands=!1,this.requestUpdate()}}}updateCommandDir(e){this.commandDir=e,this.saved=!1,this.message=``,this.requestUpdate()}async save(){if(!(!this.project||this.saving)){this.saving=!0,this.saved=!1,this.error=``,this.message=``,this.requestUpdate();try{let e=await this.request(`/api/project/${encodeURIComponent(this.project.id)}/command-dir`,{method:`PUT`,body:JSON.stringify({commandDir:this.commandDir})});if(this.project=e?.project??this.project,this.project){let e=this.projects.findIndex(e=>e.id===this.project.id);e>=0&&(this.projects[e]=this.project)}this.commandDir=typeof this.project?.commandDir==`string`?this.project.commandDir:``,this.saved=!0,await this.loadCommands()}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.saving=!1,this.requestUpdate()}}}async openCommandDir(){if(this.project){this.error=``,this.message=``,this.requestUpdate();try{await this.request(`/api/project/open-path`,{method:`POST`,body:JSON.stringify({path:`.ai/commands`,projectId:this.project.id})})}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`),this.requestUpdate()}}}async createCommand(){if(!this.project)return;let e=window.prompt(w(`newCommandPrompt`));if(e?.trim()){this.error=``,this.message=``,this.requestUpdate();try{let t=await this.request(`/api/project/command`,{method:`POST`,body:JSON.stringify({name:e.trim(),projectId:this.project.id})});t.ok?(this.message=w(`commandCreated`,{name:t.name??e.trim()}),await this.loadCommands()):t.reason===`exists`?this.error=w(`commandAlreadyExists`,{name:t.name??e.trim()}):this.error=w(`invalidCommandName`)}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.requestUpdate()}}}render(){return this.loading?u`<div class="text-sm text-muted-foreground">${w(`loading`)}</div>`:this.projects.length===0?u`
1120
1120
  <div class="flex flex-col gap-3">
1121
- <h3 class="text-sm font-semibold text-foreground">${b(`projectCommands`)}</h3>
1122
- <p class="text-sm text-muted-foreground">${b(`selectProjectForCommands`)}</p>
1123
- ${this.error?a`<div class="text-sm text-destructive">${this.error}</div>`:null}
1121
+ <h3 class="text-sm font-semibold text-foreground">${w(`projectCommands`)}</h3>
1122
+ <p class="text-sm text-muted-foreground">${w(`selectProjectForCommands`)}</p>
1123
+ ${this.error?u`<div class="text-sm text-destructive">${this.error}</div>`:null}
1124
1124
  </div>
1125
- `:a`
1125
+ `:u`
1126
1126
  <div class="flex flex-col gap-6">
1127
1127
  <div>
1128
1128
  <h3 class="mb-2 text-sm font-semibold text-foreground">
1129
- ${b(`projectCommands`)}
1130
- <quickforge-info-tip .label=${b(`projectCommandsDescription`)}></quickforge-info-tip>
1129
+ ${w(`projectCommands`)}
1130
+ <quickforge-info-tip .label=${w(`projectCommandsDescription`)}></quickforge-info-tip>
1131
1131
  </h3>
1132
1132
  </div>
1133
1133
 
1134
1134
  <div class="grid max-w-xl gap-1.5 text-sm">
1135
- <span class="text-foreground">${b(`project`)}</span>
1135
+ <span class="text-foreground">${w(`project`)}</span>
1136
1136
  <select
1137
1137
  class="rounded-md border border-input bg-background px-3 py-2 text-sm"
1138
1138
  .value=${this.project?.id??``}
1139
1139
  @change=${e=>this.selectProject(e)}
1140
1140
  >
1141
- ${this.projects.map(e=>a`<option value=${e.id} ?selected=${e.id===this.project?.id}>${e.name}</option>`)}
1141
+ ${this.projects.map(e=>u`<option value=${e.id} ?selected=${e.id===this.project?.id}>${e.name}</option>`)}
1142
1142
  </select>
1143
- ${this.project?.path?a`<span class="break-all text-xs text-muted-foreground">${this.project.path}</span>`:null}
1143
+ ${this.project?.path?u`<span class="break-all text-xs text-muted-foreground">${this.project.path}</span>`:null}
1144
1144
  </div>
1145
1145
 
1146
1146
  <label class="grid max-w-xl gap-1.5 text-sm">
1147
1147
  <span class="inline-flex items-center gap-1.5 text-foreground">
1148
- ${b(`commandDirectories`)}
1149
- <quickforge-info-tip .label=${b(`commandDirectoryHelp`)}></quickforge-info-tip>
1148
+ ${w(`commandDirectories`)}
1149
+ <quickforge-info-tip .label=${w(`commandDirectoryHelp`)}></quickforge-info-tip>
1150
1150
  </span>
1151
1151
  <textarea
1152
1152
  class="min-h-28 rounded-md border border-input bg-background px-3 py-2 text-sm"
1153
1153
  .value=${this.commandDir}
1154
- placeholder=${b(`commandDirectoryPlaceholder`)}
1154
+ placeholder=${w(`commandDirectoryPlaceholder`)}
1155
1155
  @input=${e=>this.updateCommandDir(e.target.value)}
1156
1156
  ></textarea>
1157
1157
  </label>
1158
1158
 
1159
1159
  <div class="rounded-lg border border-border p-4 text-xs leading-5 text-muted-foreground">
1160
- <div class="mb-1 font-medium text-foreground">${b(`commandDirectoryExamples`)}</div>
1160
+ <div class="mb-1 font-medium text-foreground">${w(`commandDirectoryExamples`)}</div>
1161
1161
  <ul class="list-disc space-y-1 pl-5">
1162
1162
  <li>.ai/commands</li>
1163
1163
  <li>.claude/commands</li>
@@ -1173,17 +1173,17 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
1173
1173
  ?disabled=${this.saving}
1174
1174
  @click=${()=>this.save()}
1175
1175
  >
1176
- ${this.saving?b(`saving`):b(`save`)}
1176
+ ${this.saving?w(`saving`):w(`save`)}
1177
1177
  </button>
1178
- ${this.saved?a`<span class="text-sm text-muted-foreground">${b(`projectCommandsSaved`)}</span>`:null}
1179
- ${this.message?a`<span class="text-sm text-muted-foreground">${this.message}</span>`:null}
1180
- ${this.error?a`<span class="text-sm text-destructive">${this.error}</span>`:null}
1178
+ ${this.saved?u`<span class="text-sm text-muted-foreground">${w(`projectCommandsSaved`)}</span>`:null}
1179
+ ${this.message?u`<span class="text-sm text-muted-foreground">${this.message}</span>`:null}
1180
+ ${this.error?u`<span class="text-sm text-destructive">${this.error}</span>`:null}
1181
1181
  </div>
1182
1182
 
1183
1183
  <section class="rounded-lg border border-border p-4">
1184
1184
  <div class="mb-3 flex flex-wrap items-center justify-between gap-2">
1185
1185
  <h4 class="text-sm font-semibold text-foreground">
1186
- ${b(`loadedCommands`,{count:this.commands.length})}
1186
+ ${w(`loadedCommands`,{count:this.commands.length})}
1187
1187
  </h4>
1188
1188
  <div class="flex items-center gap-2">
1189
1189
  <button
@@ -1192,7 +1192,7 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
1192
1192
  ?disabled=${this.loadingCommands}
1193
1193
  @click=${()=>this.openCommandDir()}
1194
1194
  >
1195
- ${b(`openCommandDir`)}
1195
+ ${w(`openCommandDir`)}
1196
1196
  </button>
1197
1197
  <button
1198
1198
  class="rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground hover:bg-primary/90 disabled:opacity-60"
@@ -1200,29 +1200,29 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
1200
1200
  ?disabled=${this.loadingCommands}
1201
1201
  @click=${()=>this.createCommand()}
1202
1202
  >
1203
- ${b(`createCommand`)}
1203
+ ${w(`createCommand`)}
1204
1204
  </button>
1205
1205
  </div>
1206
1206
  </div>
1207
1207
 
1208
- ${this.loadingCommands?a`<div class="text-sm text-muted-foreground">${b(`loading`)}</div>`:this.commands.length===0?a`<p class="text-sm text-muted-foreground">${b(`noCommandsLoaded`)}</p>`:a`<ul class="grid gap-2">
1209
- ${this.commands.map(e=>{let t=e.argumentHint?` ${e.argumentHint}`:``;return a`
1208
+ ${this.loadingCommands?u`<div class="text-sm text-muted-foreground">${w(`loading`)}</div>`:this.commands.length===0?u`<p class="text-sm text-muted-foreground">${w(`noCommandsLoaded`)}</p>`:u`<ul class="grid gap-2">
1209
+ ${this.commands.map(e=>{let t=e.argumentHint?` ${e.argumentHint}`:``;return u`
1210
1210
  <li class="grid gap-0.5 text-sm">
1211
1211
  <span class="text-foreground">
1212
1212
  <code class="text-xs">/${e.name}${t}</code>
1213
- ${e.description?a` — <span class="text-muted-foreground">${e.description}</span>`:null}
1213
+ ${e.description?u` — <span class="text-muted-foreground">${e.description}</span>`:null}
1214
1214
  </span>
1215
- ${e.relativePath?a`<span class="text-xs text-muted-foreground">${e.relativePath}</span>`:null}
1215
+ ${e.relativePath?u`<span class="text-xs text-muted-foreground">${e.relativePath}</span>`:null}
1216
1216
  </li>
1217
1217
  `})}
1218
1218
  </ul>`}
1219
1219
  </section>
1220
1220
  </div>
1221
- `}},K=`quickforge-project-commands-settings-tab`;customElements.get(K)||customElements.define(K,ot);function st(){return document.createElement(K)}var q={"x-quickforge-action":`channel-action`};function ct(e){switch(e){case`running`:return`border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300`;case`waiting_scan`:case`starting`:case`stopping`:return`border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300`;case`error`:return`border-destructive/30 bg-destructive/10 text-destructive`;default:return`border-border bg-muted/15 text-muted-foreground`}}function lt(e){switch(e){case`starting`:return b(`channelStatusStarting`);case`waiting_scan`:return b(`channelStatusWaitingScan`);case`running`:return b(`channelStatusRunning`);case`stopping`:return b(`channelStatusStopping`);case`error`:return b(`channelStatusError`);default:return b(`channelStatusStopped`)}}function ut(e){if(!e)return`-`;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString()}var dt=class extends o{loading=!0;channels=[];workspaces=[];selectedWorkspaceIdByChannel={};error=``;message=``;eventSource;busyChannelId=``;getTabName(){return b(`channels`)}async connectedCallback(){super.connectedCallback(),await Promise.all([this.loadChannels(),this.loadWorkspaces()]),this.connectEvents()}disconnectedCallback(){this.eventSource?.close(),this.eventSource=void 0,super.disconnectedCallback()}async request(e,t){let n=await fetch(e,{...t,cache:`no-store`,headers:{...t?.headers||{}}}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||b(`requestFailed`));return r}async loadChannels(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=await this.request(`/api/channels`);this.channels=Array.isArray(e.channels)?e.channels:[],this.ensureWorkspaceSelections()}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}async loadWorkspaces(){try{let e=await this.request(`/api/project`),t=e.defaultWorkspaceRoot||``,n=t?[{id:`default`,name:b(`channelDefaultWorkspace`),path:t,kind:`default`}]:[],r=(Array.isArray(e.projects)?e.projects:[]).map(e=>({id:e.id,name:e.name,path:e.path,kind:`project`}));this.workspaces=[...n,...r],this.ensureWorkspaceSelections()}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.requestUpdate()}}ensureWorkspaceSelections(){let e=new Set(this.workspaces.map(e=>e.id)),t={...this.selectedWorkspaceIdByChannel};for(let n of this.channels){if(!n.supportsWorkspaceSelection)continue;let r=t[n.id],i=n.launchWorkspace?.id,a=n.status!==`stopped`&&n.status!==`error`;if(i&&e.has(i)&&a){t[n.id]=i;continue}r&&e.has(r)||(t[n.id]=i&&e.has(i)?i:`default`)}this.selectedWorkspaceIdByChannel=t}connectEvents(){this.eventSource?.close();let e=new EventSource(`/api/channels/events`);this.eventSource=e;let t=e=>{try{let t=JSON.parse(e.data);this.applyChannelEvent(t)}catch{}};e.addEventListener(`snapshot`,t),e.addEventListener(`status`,t),e.addEventListener(`log`,t),e.addEventListener(`qrcode`,t),e.addEventListener(`error`,()=>{})}applyChannelEvent(e){if(Array.isArray(e.channels)){this.channels=e.channels,this.ensureWorkspaceSelections(),this.requestUpdate();return}if(e.snapshot){this.upsertChannel(e.snapshot);return}if(e.channelId&&e.log){let t=this.channels.find(t=>t.id===e.channelId);t&&(t.logs=[...t.logs||[],e.log].slice(-300),this.requestUpdate())}}upsertChannel(e){let t=this.channels.findIndex(t=>t.id===e.id);t>=0?this.channels=[...this.channels.slice(0,t),e,...this.channels.slice(t+1)]:this.channels=[...this.channels,e],this.ensureWorkspaceSelections(),this.requestUpdate()}selectedWorkspaceId(e){return this.selectedWorkspaceIdByChannel[e.id]||e.launchWorkspace?.id||`default`}handleWorkspaceChange(e,t){let n=t.currentTarget;n&&(this.selectedWorkspaceIdByChannel={...this.selectedWorkspaceIdByChannel,[e.id]:n.value||`default`},this.requestUpdate())}startOptions(e){return e.supportsWorkspaceSelection?{projectId:this.selectedWorkspaceId(e)}:void 0}async invoke(e,t){if(!this.busyChannelId&&!(t===`restart`&&!await m({description:b(`channelRestartConfirm`,{name:e.name}),confirmLabel:b(`restart`),cancelLabel:b(`cancel`)}))){this.busyChannelId=e.id,this.error=``,this.message=``,this.requestUpdate();try{let n=t===`start`||t===`restart`?this.startOptions(e):void 0,r=await this.request(`/api/channels/${encodeURIComponent(e.id)}/${t}`,{method:`POST`,headers:n?{...q,"content-type":`application/json`}:q,body:n?JSON.stringify(n):void 0});this.upsertChannel(r)}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.busyChannelId=``,this.requestUpdate()}}}async invokeAction(e,t){if(!this.busyChannelId&&!((t.destructive||t.id===`relogin`)&&!await m({description:t.id===`relogin`?b(`channelReloginConfirm`,{name:e.name}):b(`channelLogoutConfirm`,{name:e.name}),confirmLabel:t.label,cancelLabel:b(`cancel`),variant:t.destructive?`destructive`:void 0}))){this.busyChannelId=e.id,this.error=``,this.message=``,this.requestUpdate();try{let n=t.id===`relogin`?this.startOptions(e):void 0,r=await this.request(`/api/channels/${encodeURIComponent(e.id)}/actions/${encodeURIComponent(t.id)}`,{method:`POST`,headers:n?{...q,"content-type":`application/json`}:q,body:n?JSON.stringify(n):void 0});this.upsertChannel(r)}catch(e){this.error=e instanceof Error?e.message:b(`requestFailed`)}finally{this.busyChannelId=``,this.requestUpdate()}}}workspaceSection(e,t){if(!e.supportsWorkspaceSelection)return null;let n=this.selectedWorkspaceId(e),r=e.launchWorkspace;return a`
1221
+ `}},K=`quickforge-project-commands-settings-tab`;customElements.get(K)||customElements.define(K,St);function Ct(){return document.createElement(K)}var q={"x-quickforge-action":`channel-action`};function wt(e){switch(e){case`running`:return`border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300`;case`waiting_scan`:case`starting`:case`stopping`:return`border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300`;case`error`:return`border-destructive/30 bg-destructive/10 text-destructive`;default:return`border-border bg-muted/15 text-muted-foreground`}}function Tt(e){switch(e){case`starting`:return w(`channelStatusStarting`);case`waiting_scan`:return w(`channelStatusWaitingScan`);case`running`:return w(`channelStatusRunning`);case`stopping`:return w(`channelStatusStopping`);case`error`:return w(`channelStatusError`);default:return w(`channelStatusStopped`)}}function Et(e){if(!e)return`-`;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString()}var Dt=class extends d{loading=!0;channels=[];workspaces=[];selectedWorkspaceIdByChannel={};error=``;message=``;eventSource;busyChannelId=``;getTabName(){return w(`channels`)}async connectedCallback(){super.connectedCallback(),await Promise.all([this.loadChannels(),this.loadWorkspaces()]),this.connectEvents()}disconnectedCallback(){this.eventSource?.close(),this.eventSource=void 0,super.disconnectedCallback()}async request(e,t){let n=await fetch(e,{...t,cache:`no-store`,headers:{...t?.headers||{}}}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||w(`requestFailed`));return r}async loadChannels(){this.loading=!0,this.error=``,this.requestUpdate();try{let e=await this.request(`/api/channels`);this.channels=Array.isArray(e.channels)?e.channels:[],this.ensureWorkspaceSelections()}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.loading=!1,this.requestUpdate()}}async loadWorkspaces(){try{let e=await this.request(`/api/project`),t=e.defaultWorkspaceRoot||``,n=t?[{id:`default`,name:w(`channelDefaultWorkspace`),path:t,kind:`default`}]:[],r=(Array.isArray(e.projects)?e.projects:[]).map(e=>({id:e.id,name:e.name,path:e.path,kind:`project`}));this.workspaces=[...n,...r],this.ensureWorkspaceSelections()}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.requestUpdate()}}ensureWorkspaceSelections(){let e=new Set(this.workspaces.map(e=>e.id)),t={...this.selectedWorkspaceIdByChannel};for(let n of this.channels){if(!n.supportsWorkspaceSelection)continue;let r=t[n.id],i=n.launchWorkspace?.id,a=n.status!==`stopped`&&n.status!==`error`;if(i&&e.has(i)&&a){t[n.id]=i;continue}r&&e.has(r)||(t[n.id]=i&&e.has(i)?i:`default`)}this.selectedWorkspaceIdByChannel=t}connectEvents(){this.eventSource?.close();let e=new EventSource(`/api/channels/events`);this.eventSource=e;let t=e=>{try{let t=JSON.parse(e.data);this.applyChannelEvent(t)}catch{}};e.addEventListener(`snapshot`,t),e.addEventListener(`status`,t),e.addEventListener(`log`,t),e.addEventListener(`qrcode`,t),e.addEventListener(`error`,()=>{})}applyChannelEvent(e){if(Array.isArray(e.channels)){this.channels=e.channels,this.ensureWorkspaceSelections(),this.requestUpdate();return}if(e.snapshot){this.upsertChannel(e.snapshot);return}if(e.channelId&&e.log){let t=this.channels.find(t=>t.id===e.channelId);t&&(t.logs=[...t.logs||[],e.log].slice(-300),this.requestUpdate())}}upsertChannel(e){let t=this.channels.findIndex(t=>t.id===e.id);t>=0?this.channels=[...this.channels.slice(0,t),e,...this.channels.slice(t+1)]:this.channels=[...this.channels,e],this.ensureWorkspaceSelections(),this.requestUpdate()}selectedWorkspaceId(e){return this.selectedWorkspaceIdByChannel[e.id]||e.launchWorkspace?.id||`default`}handleWorkspaceChange(e,t){let n=t.currentTarget;n&&(this.selectedWorkspaceIdByChannel={...this.selectedWorkspaceIdByChannel,[e.id]:n.value||`default`},this.requestUpdate())}startOptions(e){return e.supportsWorkspaceSelection?{projectId:this.selectedWorkspaceId(e)}:void 0}async invoke(e,t){if(!this.busyChannelId&&!(t===`restart`&&!await v({description:w(`channelRestartConfirm`,{name:e.name}),confirmLabel:w(`restart`),cancelLabel:w(`cancel`)}))){this.busyChannelId=e.id,this.error=``,this.message=``,this.requestUpdate();try{let n=t===`start`||t===`restart`?this.startOptions(e):void 0,r=await this.request(`/api/channels/${encodeURIComponent(e.id)}/${t}`,{method:`POST`,headers:n?{...q,"content-type":`application/json`}:q,body:n?JSON.stringify(n):void 0});this.upsertChannel(r)}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.busyChannelId=``,this.requestUpdate()}}}async invokeAction(e,t){if(!this.busyChannelId&&!((t.destructive||t.id===`relogin`)&&!await v({description:t.id===`relogin`?w(`channelReloginConfirm`,{name:e.name}):w(`channelLogoutConfirm`,{name:e.name}),confirmLabel:t.label,cancelLabel:w(`cancel`),variant:t.destructive?`destructive`:void 0}))){this.busyChannelId=e.id,this.error=``,this.message=``,this.requestUpdate();try{let n=t.id===`relogin`?this.startOptions(e):void 0,r=await this.request(`/api/channels/${encodeURIComponent(e.id)}/actions/${encodeURIComponent(t.id)}`,{method:`POST`,headers:n?{...q,"content-type":`application/json`}:q,body:n?JSON.stringify(n):void 0});this.upsertChannel(r)}catch(e){this.error=e instanceof Error?e.message:w(`requestFailed`)}finally{this.busyChannelId=``,this.requestUpdate()}}}workspaceSection(e,t){if(!e.supportsWorkspaceSelection)return null;let n=this.selectedWorkspaceId(e),r=e.launchWorkspace;return u`
1222
1222
  <div class="mt-4 rounded-lg border border-border bg-muted/10 p-3">
1223
1223
  <label class="inline-flex items-center gap-1.5 text-sm font-medium text-foreground" for=${`channel-workspace-${e.id}`}>
1224
- ${b(`channelWorkspace`)}
1225
- <quickforge-info-tip .label=${b(`channelWorkspaceDescription`)}></quickforge-info-tip>
1224
+ ${w(`channelWorkspace`)}
1225
+ <quickforge-info-tip .label=${w(`channelWorkspaceDescription`)}></quickforge-info-tip>
1226
1226
  </label>
1227
1227
  <select
1228
1228
  id=${`channel-workspace-${e.id}`}
@@ -1231,90 +1231,90 @@ import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,Dt as n}from".
1231
1231
  .value=${n}
1232
1232
  @change=${t=>this.handleWorkspaceChange(e,t)}
1233
1233
  >
1234
- ${this.workspaces.map(e=>a`
1235
- <option value=${e.id}>${e.kind===`default`?b(`channelDefaultWorkspace`):e.name} — ${e.path}</option>
1234
+ ${this.workspaces.map(e=>u`
1235
+ <option value=${e.id}>${e.kind===`default`?w(`channelDefaultWorkspace`):e.name} — ${e.path}</option>
1236
1236
  `)}
1237
1237
  </select>
1238
- ${r?a`<div class="mt-2 text-xs text-muted-foreground">${b(`channelCurrentWorkspace`)}: <span class="font-mono">${r.path}</span></div>`:null}
1238
+ ${r?u`<div class="mt-2 text-xs text-muted-foreground">${w(`channelCurrentWorkspace`)}: <span class="font-mono">${r.path}</span></div>`:null}
1239
1239
  </div>
1240
- `}channelMeta(e){return a`
1240
+ `}channelMeta(e){return u`
1241
1241
  <dl class="grid gap-2 text-sm">
1242
- ${[[b(`channelProvider`),e.provider||`-`],[b(`channelCommand`),e.commandLabel||`-`],[b(`channelPid`),e.pid?String(e.pid):`-`],[b(`channelStartedAt`),ut(e.startedAt)]].map(([e,t])=>a`
1242
+ ${[[w(`channelProvider`),e.provider||`-`],[w(`channelCommand`),e.commandLabel||`-`],[w(`channelPid`),e.pid?String(e.pid):`-`],[w(`channelStartedAt`),Et(e.startedAt)]].map(([e,t])=>u`
1243
1243
  <div class="grid gap-1 sm:grid-cols-[112px_1fr] sm:gap-3">
1244
1244
  <dt class="text-muted-foreground">${e}</dt>
1245
- <dd class="min-w-0 break-all ${e===b(`channelCommand`)?`font-mono text-xs`:`text-foreground`}">${t}</dd>
1245
+ <dd class="min-w-0 break-all ${e===w(`channelCommand`)?`font-mono text-xs`:`text-foreground`}">${t}</dd>
1246
1246
  </div>
1247
1247
  `)}
1248
1248
  </dl>
1249
- `}qrSection(e){return!e.qrCodeText&&!e.qrCodeUrl&&e.status!==`waiting_scan`?null:a`
1249
+ `}qrSection(e){return!e.qrCodeText&&!e.qrCodeUrl&&e.status!==`waiting_scan`?null:u`
1250
1250
  <div class="mt-4 rounded-lg border border-border bg-muted/10 p-3">
1251
1251
  <div class="inline-flex items-center gap-1.5 text-sm font-medium text-foreground">
1252
- ${b(`channelQrTitle`)}
1253
- <quickforge-info-tip .label=${b(`channelQrDescription`)}></quickforge-info-tip>
1252
+ ${w(`channelQrTitle`)}
1253
+ <quickforge-info-tip .label=${w(`channelQrDescription`)}></quickforge-info-tip>
1254
1254
  </div>
1255
- ${e.qrCodeText?a`<pre class="mt-3 max-h-96 overflow-auto whitespace-pre font-mono text-[10px] leading-none text-foreground">${e.qrCodeText}</pre>`:null}
1256
- ${e.qrCodeUrl?a`
1257
- <div class="mt-3 text-xs text-muted-foreground">${b(`channelQrLink`)}</div>
1255
+ ${e.qrCodeText?u`<pre class="mt-3 max-h-96 overflow-auto whitespace-pre font-mono text-[10px] leading-none text-foreground">${e.qrCodeText}</pre>`:null}
1256
+ ${e.qrCodeUrl?u`
1257
+ <div class="mt-3 text-xs text-muted-foreground">${w(`channelQrLink`)}</div>
1258
1258
  <a class="mt-1 block break-all font-mono text-xs text-primary hover:underline" href=${e.qrCodeUrl} target="_blank" rel="noreferrer">${e.qrCodeUrl}</a>
1259
1259
  `:null}
1260
1260
  </div>
1261
- `}logsSection(e){let t=e.logs||[];return a`
1261
+ `}logsSection(e){let t=e.logs||[];return u`
1262
1262
  <details class="mt-4 rounded-lg border border-border bg-muted/10" open>
1263
- <summary class="quickforge-channel-logs-summary cursor-pointer px-3 py-2 text-sm font-medium text-foreground">${b(`channelRecentLogs`)}</summary>
1263
+ <summary class="quickforge-channel-logs-summary cursor-pointer px-3 py-2 text-sm font-medium text-foreground">${w(`channelRecentLogs`)}</summary>
1264
1264
  <div class="max-h-72 overflow-auto p-3 font-mono text-xs leading-5">
1265
- ${t.length?t.slice(-80).map(e=>a`
1265
+ ${t.length?t.slice(-80).map(e=>u`
1266
1266
  <div class="grid gap-1 py-0.5 sm:grid-cols-[72px_56px_1fr]">
1267
1267
  <span class="text-muted-foreground/55">${new Date(e.time).toLocaleTimeString()}</span>
1268
1268
  <span class=${e.stream===`stderr`?`text-destructive/80`:`text-muted-foreground/70`}>${e.stream}</span>
1269
1269
  <span class="min-w-0 whitespace-pre-wrap break-words text-foreground/85">${e.text}</span>
1270
1270
  </div>
1271
- `):a`<div class="text-muted-foreground">${b(`channelNoLogs`)}</div>`}
1271
+ `):u`<div class="text-muted-foreground">${w(`channelNoLogs`)}</div>`}
1272
1272
  </div>
1273
1273
  </details>
1274
- `}channelCard(e){let t=this.busyChannelId===e.id||!!e.activeAction,n=e.status===`running`||e.status===`waiting_scan`||e.status===`starting`,r=e.status===`stopping`,i=!!(e.supportsWorkspaceSelection&&this.workspaces.length===0);return a`
1274
+ `}channelCard(e){let t=this.busyChannelId===e.id||!!e.activeAction,n=e.status===`running`||e.status===`waiting_scan`||e.status===`starting`,r=e.status===`stopping`,i=!!(e.supportsWorkspaceSelection&&this.workspaces.length===0);return u`
1275
1275
  <section class="rounded-lg border border-border p-4">
1276
1276
  <div class="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
1277
1277
  <div class="min-w-0">
1278
1278
  <div class="flex flex-wrap items-center gap-2">
1279
1279
  <h4 class="text-sm font-semibold text-foreground">${e.name}</h4>
1280
- <span class="inline-flex rounded-full border px-2 py-0.5 text-xs ${ct(e.status)}">${lt(e.status)}</span>
1280
+ <span class="inline-flex rounded-full border px-2 py-0.5 text-xs ${wt(e.status)}">${Tt(e.status)}</span>
1281
1281
  </div>
1282
1282
  <p class="mt-1 text-sm text-muted-foreground">${e.description}</p>
1283
- ${e.requirements?.length?a`<div class="mt-2 text-xs text-muted-foreground/70">${b(`channelRequirements`)}: ${e.requirements.join(` · `)}</div>`:null}
1283
+ ${e.requirements?.length?u`<div class="mt-2 text-xs text-muted-foreground/70">${w(`channelRequirements`)}: ${e.requirements.join(` · `)}</div>`:null}
1284
1284
  </div>
1285
1285
  <div class="flex shrink-0 flex-wrap gap-2">
1286
- <button class="rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-60" type="button" ?disabled=${t||n||r||i} @click=${()=>this.invoke(e,`start`)}>${b(`start`)}</button>
1287
- <button class="rounded-md border border-input px-3 py-2 text-sm hover:bg-muted/20 disabled:opacity-60" type="button" ?disabled=${t||!n||r} @click=${()=>this.invoke(e,`stop`)}>${b(`stop`)}</button>
1288
- <button class="rounded-md border border-input px-3 py-2 text-sm hover:bg-muted/20 disabled:opacity-60" type="button" ?disabled=${t||r||i} @click=${()=>this.invoke(e,`restart`)}>${b(`restart`)}</button>
1289
- ${e.actions?.map(n=>a`
1286
+ <button class="rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-60" type="button" ?disabled=${t||n||r||i} @click=${()=>this.invoke(e,`start`)}>${w(`start`)}</button>
1287
+ <button class="rounded-md border border-input px-3 py-2 text-sm hover:bg-muted/20 disabled:opacity-60" type="button" ?disabled=${t||!n||r} @click=${()=>this.invoke(e,`stop`)}>${w(`stop`)}</button>
1288
+ <button class="rounded-md border border-input px-3 py-2 text-sm hover:bg-muted/20 disabled:opacity-60" type="button" ?disabled=${t||r||i} @click=${()=>this.invoke(e,`restart`)}>${w(`restart`)}</button>
1289
+ ${e.actions?.map(n=>u`
1290
1290
  <button class=${n.destructive?`rounded-md border border-destructive/40 px-3 py-2 text-sm text-destructive hover:bg-destructive/10 disabled:opacity-60`:`rounded-md border border-input px-3 py-2 text-sm hover:bg-muted/20 disabled:opacity-60`} type="button" ?disabled=${t} @click=${()=>this.invokeAction(e,n)}>${n.label}</button>
1291
1291
  `)}
1292
1292
  </div>
1293
1293
  </div>
1294
1294
 
1295
1295
  ${this.workspaceSection(e,t||n||r)}
1296
- ${i?a`<div class="mt-3 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${b(`channelNoWorkspaces`)}</div>`:null}
1296
+ ${i?u`<div class="mt-3 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${w(`channelNoWorkspaces`)}</div>`:null}
1297
1297
  <div class="mt-4">${this.channelMeta(e)}</div>
1298
- ${e.error?a`<div class="mt-4 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${e.error}</div>`:null}
1298
+ ${e.error?u`<div class="mt-4 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${e.error}</div>`:null}
1299
1299
  ${this.qrSection(e)}
1300
1300
  ${this.logsSection(e)}
1301
1301
  </section>
1302
- `}render(){return this.loading?a`<div class="text-sm text-muted-foreground">${b(`loading`)}</div>`:a`
1302
+ `}render(){return this.loading?u`<div class="text-sm text-muted-foreground">${w(`loading`)}</div>`:u`
1303
1303
  <div class="flex flex-col gap-6">
1304
1304
  <div>
1305
1305
  <h3 class="mb-2 inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
1306
- ${b(`channels`)}
1307
- <quickforge-info-tip .label=${b(`channelsDescription`)}></quickforge-info-tip>
1306
+ ${w(`channels`)}
1307
+ <quickforge-info-tip .label=${w(`channelsDescription`)}></quickforge-info-tip>
1308
1308
  </h3>
1309
1309
  </div>
1310
1310
 
1311
1311
  <section class="rounded-lg border border-amber-500/30 bg-amber-500/10 p-4 text-sm text-amber-800 dark:text-amber-200">
1312
- ${b(`channelsSecurityWarning`)}
1312
+ ${w(`channelsSecurityWarning`)}
1313
1313
  </section>
1314
1314
 
1315
- ${this.channels.length?a`<div class="grid gap-4">${this.channels.map(e=>this.channelCard(e))}</div>`:a`<div class="rounded-lg border border-border p-4 text-sm text-muted-foreground">${b(`channelsEmpty`)}</div>`}
1315
+ ${this.channels.length?u`<div class="grid gap-4">${this.channels.map(e=>this.channelCard(e))}</div>`:u`<div class="rounded-lg border border-border p-4 text-sm text-muted-foreground">${w(`channelsEmpty`)}</div>`}
1316
1316
 
1317
- ${this.message?a`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
1318
- ${this.error?a`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
1317
+ ${this.message?u`<div class="rounded-md border border-emerald-500/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-700 dark:text-emerald-300">${this.message}</div>`:null}
1318
+ ${this.error?u`<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">${this.error}</div>`:null}
1319
1319
  </div>
1320
- `}},J=`quickforge-channels-settings-tab`;customElements.get(J)||customElements.define(J,dt);function ft(){return document.createElement(J)}var pt=i(),Y=r(),mt=(0,C.lazy)(()=>c(()=>import(`./AgentProfilesPage-DFUA4KiP.js`).then(e=>({default:e.AgentProfilesPage})),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11]))),ht=(0,C.lazy)(()=>c(()=>import(`./mcp-servers-dialog-DXR3fnZY.js`).then(e=>({default:e.McpServersPanel})),__vite__mapDeps([12,1,2,3,4,5,6,7,8,9,10,11]))),gt=(0,C.lazy)(()=>c(()=>import(`./skills-dialog-Dax-_Ze5.js`).then(e=>e.n).then(e=>({default:e.SkillsManagerPanel})),__vite__mapDeps([9,1,2,3,4,5,6,7,8,10,11]))),_t=(0,C.lazy)(()=>c(()=>import(`./PluginsPage-CKOP-P02.js`).then(e=>({default:e.PluginsPage})),__vite__mapDeps([13,1,2,3,4,5,6,7,8,9,10,11,14]))),vt=(0,C.lazy)(()=>c(()=>import(`./ScheduledTasksPage-CRPvyfmE.js`).then(e=>({default:e.ScheduledTasksPage})),__vite__mapDeps([15,1,2,3,4,5,6,7,8,9,10,11]))),yt=class extends o{tabName=``;renderReact;root;getTabName(){return this.tabName}connectedCallback(){super.connectedCallback(),this.updateComplete.then(()=>this.mountReact())}disconnectedCallback(){this.root?.unmount(),this.root=void 0,super.disconnectedCallback()}render(){return a`<div class="quickforge-react-settings-tab h-full min-h-0"></div>`}mountReact(){let e=this.querySelector(`.quickforge-react-settings-tab`);!e||!this.renderReact||(this.root??=(0,pt.createRoot)(e),this.root.render(this.renderReact()))}},X=`quickforge-react-settings-tab`;customElements.get(X)||customElements.define(X,yt);function Z(e,t){let n=document.createElement(X);return n.tabName=e,n.renderReact=t,n}function Q({children:e}){return(0,Y.jsx)(`div`,{className:`h-full min-h-[30rem] overflow-hidden rounded-xl border border-border bg-background`,children:(0,Y.jsx)(C.Suspense,{fallback:(0,Y.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:b(`loading`)}),children:e})})}function $(e){window.dispatchEvent(new CustomEvent(`quickforge:open-session-from-settings`,{detail:{sessionId:e}}))}function bt(){return Z(b(`agentsTab`),()=>(0,Y.jsx)(Q,{children:(0,Y.jsx)(mt,{})}))}function xt(){return Z(b(`skills`),()=>(0,Y.jsx)(Q,{children:(0,Y.jsx)(gt,{active:!0,scope:`global`,embedded:!0,onSaved:()=>void 0})}))}function St(){return Z(b(`mcpServers`),()=>(0,Y.jsx)(Q,{children:(0,Y.jsx)(ht,{active:!0})}))}function Ct(){return Z(b(`plugins`),()=>(0,Y.jsx)(Q,{children:(0,Y.jsx)(_t,{})}))}function wt(){return Z(b(`scheduledTasks`),()=>(0,Y.jsx)(Q,{children:(0,Y.jsx)(vt,{onOpenSession:$})}))}function Tt(e){let t=[{key:`language`,tab:Se()},{key:`appearance`,tab:k()},{key:`defaults`,tab:Ae()},{key:`customModels`,tab:be(e)},{key:`agents`,tab:bt()},{key:`skills`,tab:xt()},{key:`mcp`,tab:St()},{key:`plugins`,tab:Ct()},{key:`scheduledTasks`,tab:wt()},{key:`projectCommands`,tab:st()},{key:`backup`,tab:Le()},{key:`archivedConversations`,tab:ze()},{key:`service`,tab:Xe()},{key:`channels`,tab:ft()},{key:`lanAccess`,tab:$e()},{key:`about`,tab:at()}];return{items:[...t],tabs:t.map(e=>e.tab),indexOf:e=>t.findIndex(t=>t.key===e)}}function Et({tab:e}){let t=(0,C.useRef)(null);return(0,C.useEffect)(()=>{let n=t.current;if(n)return n.replaceChildren(e),()=>{e.parentNode===n&&n.removeChild(e)}},[e]),(0,Y.jsx)(`div`,{ref:t,className:`quickforge-settings-tab-host min-h-0 flex-1`})}function Dt({initialTab:e,customProvider:t,onBack:r}){let i=(0,C.useMemo)(()=>Tt(t),[t]),a=Math.max(0,i.indexOf(e)),[o,s]=(0,C.useState)(),c=o??a,l=i.items[c]??i.items[0];return(0,Y.jsxs)(`div`,{className:`flex h-screen min-h-0 bg-[var(--quickforge-sidebar-bg)] text-foreground`,children:[(0,Y.jsxs)(`aside`,{className:`relative z-10 hidden w-80 shrink-0 overflow-hidden bg-[var(--quickforge-sidebar-bg)] md:flex md:min-h-0 md:flex-col`,children:[(0,Y.jsx)(`div`,{className:`shrink-0 px-3 pb-1 pt-3`,children:(0,Y.jsxs)(`button`,{type:`button`,className:`group relative flex w-full items-center gap-2 overflow-hidden rounded-lg px-2 py-1.5 text-left text-muted-foreground/72 transition-[background-color,color,box-shadow] duration-160 ease-out hover:bg-[var(--quickforge-sidebar-hover-bg)] hover:text-foreground/86 hover:shadow-[0_8px_20px_-18px_rgb(15_23_42_/_0.35)]`,onClick:r,"aria-label":`返回工作区`,children:[(0,Y.jsx)(`span`,{className:`inline-flex size-6 shrink-0 items-center justify-center rounded-full text-muted-foreground/55 transition-colors group-hover:text-foreground/70`,children:(0,Y.jsx)(n,{className:`size-4`})}),(0,Y.jsx)(`span`,{className:`truncate text-sm leading-5`,children:`返回工作区`})]})}),(0,Y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-3 pb-4 pt-4`,children:(0,Y.jsx)(`nav`,{className:`space-y-1`,"aria-label":b(`settings`),children:i.items.map((e,t)=>{let n=t===c;return(0,Y.jsx)(`button`,{type:`button`,className:y(`group relative flex w-full items-center gap-2 overflow-hidden rounded-lg px-2 py-1.5 text-left text-sm leading-5 transition-[background-color,color,box-shadow] duration-160 ease-out`,n?`bg-[var(--quickforge-sidebar-active-bg)] font-medium text-foreground/92 shadow-[0_8px_22px_-20px_rgb(15_23_42_/_0.32)]`:`text-muted-foreground/76 hover:bg-[var(--quickforge-sidebar-hover-bg)] hover:text-foreground/90 hover:shadow-[0_8px_20px_-18px_rgb(15_23_42_/_0.35)]`),onClick:()=>s(t),"aria-current":n?`page`:void 0,children:(0,Y.jsx)(`span`,{className:`truncate`,children:e.tab.getTabName()})},e.key)})})})]}),(0,Y.jsxs)(`main`,{className:`flex min-w-0 flex-1 flex-col bg-[var(--quickforge-main-bg)] md:overflow-hidden md:rounded-l-2xl`,children:[(0,Y.jsxs)(`header`,{className:`flex h-14 shrink-0 items-center gap-2 border-b-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-3 pr-4 md:px-5`,children:[(0,Y.jsx)(u,{variant:`ghost`,size:`icon`,className:`md:hidden`,onClick:r,"aria-label":`返回工作区`,children:(0,Y.jsx)(n,{className:`size-4`})}),(0,Y.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,Y.jsx)(`div`,{className:`min-w-0 truncate text-sm font-medium text-foreground/90`,children:l?.tab.getTabName()})})]}),(0,Y.jsx)(`div`,{className:`quickforge-settings-mobile-tabs flex shrink-0 gap-1 overflow-x-auto border-b-[0.5px] border-[color-mix(in_oklab,var(--border)_30%,transparent)] px-3 py-2 md:hidden`,children:i.items.map((e,t)=>(0,Y.jsx)(`button`,{type:`button`,className:y(`shrink-0 rounded-full px-3 py-1.5 text-sm transition-colors`,t===c?`bg-muted text-foreground`:`text-muted-foreground hover:bg-muted/55 hover:text-foreground`),onClick:()=>s(t),children:e.tab.getTabName()},e.key))}),(0,Y.jsx)(`section`,{className:`min-h-0 flex-1 overflow-y-auto px-4 py-5 md:px-8 md:py-7`,children:(0,Y.jsx)(`div`,{className:`mx-auto flex min-h-full w-full max-w-5xl flex-col`,children:l?(0,Y.jsx)(Et,{tab:l.tab}):null})})]})]})}export{Dt as SettingsWorkspacePage};
1320
+ `}},J=`quickforge-channels-settings-tab`;customElements.get(J)||customElements.define(J,Dt);function Ot(){return document.createElement(J)}var kt=ue(),Y=le(),At=(0,D.lazy)(()=>p(()=>import(`./AgentProfilesPage-wpt1cJV0.js`).then(e=>({default:e.AgentProfilesPage})),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11]))),jt=(0,D.lazy)(()=>p(()=>import(`./mcp-servers-dialog-DEyq3gmP.js`).then(e=>({default:e.McpServersPanel})),__vite__mapDeps([12,1,2,3,4,5,6,7,8,9,10,11]))),Mt=(0,D.lazy)(()=>p(()=>import(`./skills-dialog-CZ3CuVtQ.js`).then(e=>e.n).then(e=>({default:e.SkillsManagerPanel})),__vite__mapDeps([9,1,2,3,4,5,6,7,8,10,11]))),Nt=(0,D.lazy)(()=>p(()=>import(`./PluginsPage-0wwQydcP.js`).then(e=>({default:e.PluginsPage})),__vite__mapDeps([13,1,2,3,4,5,6,7,8,9,10,11,14]))),Pt=(0,D.lazy)(()=>p(()=>import(`./ScheduledTasksPage-qGHyGkjw.js`).then(e=>({default:e.ScheduledTasksPage})),__vite__mapDeps([15,1,2,3,4,5,6,7,8,9,10,11]))),Ft=class extends d{tabName=``;renderReact;root;getTabName(){return this.tabName}connectedCallback(){super.connectedCallback(),this.updateComplete.then(()=>this.mountReact())}disconnectedCallback(){this.root?.unmount(),this.root=void 0,super.disconnectedCallback()}render(){return u`<div class="quickforge-react-settings-tab h-full min-h-0"></div>`}mountReact(){let e=this.querySelector(`.quickforge-react-settings-tab`);!e||!this.renderReact||(this.root??=(0,kt.createRoot)(e),this.root.render(this.renderReact()))}},X=`quickforge-react-settings-tab`;customElements.get(X)||customElements.define(X,Ft);function Z(e,t){let n=document.createElement(X);return n.tabName=e,n.renderReact=t,n}function Q({children:e}){return(0,Y.jsx)(`div`,{className:`h-full min-h-[30rem] overflow-hidden rounded-xl border border-border bg-background`,children:(0,Y.jsx)(D.Suspense,{fallback:(0,Y.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:w(`loading`)}),children:e})})}function It(e){window.dispatchEvent(new CustomEvent(`quickforge:open-session-from-settings`,{detail:{sessionId:e}}))}function Lt(){return Z(w(`agentsTab`),()=>(0,Y.jsx)(Q,{children:(0,Y.jsx)(At,{})}))}function Rt(){return Z(w(`skills`),()=>(0,Y.jsx)(Q,{children:(0,Y.jsx)(Mt,{active:!0,scope:`global`,embedded:!0,onSaved:()=>void 0})}))}function zt(){return Z(w(`mcpServers`),()=>(0,Y.jsx)(Q,{children:(0,Y.jsx)(jt,{active:!0})}))}function Bt(){return Z(w(`plugins`),()=>(0,Y.jsx)(Q,{children:(0,Y.jsx)(Nt,{})}))}function Vt(){return Z(w(`scheduledTasks`),()=>(0,Y.jsx)(Q,{children:(0,Y.jsx)(Pt,{onOpenSession:It})}))}function Ht(e){let t=[{key:`language`,tab:Pe()},{key:`appearance`,tab:Le()},{key:`defaults`,tab:Ue()},{key:`customModels`,tab:Me(e)},{key:`agents`,tab:Lt()},{key:`skills`,tab:Rt()},{key:`mcp`,tab:zt()},{key:`plugins`,tab:Bt()},{key:`scheduledTasks`,tab:Vt()},{key:`projectCommands`,tab:Ct()},{key:`backup`,tab:Ze()},{key:`archivedConversations`,tab:tt()},{key:`service`,tab:ft()},{key:`channels`,tab:Ot()},{key:`lanAccess`,tab:ht()},{key:`about`,tab:xt()}];return{items:[...t],tabs:t.map(e=>e.tab),indexOf:e=>t.findIndex(t=>t.key===e)}}var $={language:ce,appearance:ne,defaults:ie,customModels:se,agents:r,skills:a,mcp:te,plugins:c,scheduledTasks:o,projectCommands:oe,backup:l,archivedConversations:t,service:s,channels:ee,lanAccess:ae,about:n};function Ut({tab:e}){let t=(0,D.useRef)(null);return(0,D.useEffect)(()=>{let n=t.current;if(n)return n.replaceChildren(e),()=>{e.parentNode===n&&n.removeChild(e)}},[e]),(0,Y.jsx)(`div`,{ref:t,className:`quickforge-settings-tab-host min-h-0 flex-1`})}function Wt({initialTab:e,customProvider:t,onBack:n}){let r=(0,D.useMemo)(()=>Ht(t),[t]),i=Math.max(0,r.indexOf(e)),[a,o]=(0,D.useState)(),s=a??i,c=r.items[s]??r.items[0],l=c?$[c.key]:void 0;return(0,Y.jsxs)(`div`,{className:`flex h-screen min-h-0 bg-[var(--quickforge-sidebar-bg)] text-foreground`,children:[(0,Y.jsxs)(`aside`,{className:`relative z-10 hidden w-80 shrink-0 overflow-hidden bg-[var(--quickforge-sidebar-bg)] md:flex md:min-h-0 md:flex-col`,children:[(0,Y.jsx)(`div`,{className:`shrink-0 px-3 pb-1 pt-3`,children:(0,Y.jsxs)(`button`,{type:`button`,className:`group relative flex w-full items-center gap-2 overflow-hidden rounded-lg px-2 py-1.5 text-left text-muted-foreground/72 transition-[background-color,color,box-shadow] duration-160 ease-out hover:bg-[var(--quickforge-sidebar-hover-bg)] hover:text-foreground/86 hover:shadow-[0_8px_20px_-18px_rgb(15_23_42_/_0.35)]`,onClick:n,"aria-label":`返回工作区`,children:[(0,Y.jsx)(`span`,{className:`inline-flex size-6 shrink-0 items-center justify-center rounded-full text-muted-foreground/55 transition-colors group-hover:text-foreground/70`,children:(0,Y.jsx)(re,{className:`size-4`})}),(0,Y.jsx)(`span`,{className:`truncate text-sm leading-5`,children:`返回工作区`})]})}),(0,Y.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-3 pb-4 pt-4`,children:(0,Y.jsx)(`nav`,{className:`space-y-1`,"aria-label":w(`settings`),children:r.items.map((e,t)=>{let n=t===s,r=$[e.key];return(0,Y.jsxs)(`button`,{type:`button`,className:C(`group relative flex w-full items-center gap-2.5 overflow-hidden rounded-lg px-2 py-1.5 text-left text-sm leading-5 transition-[background-color,color,box-shadow] duration-160 ease-out`,n?`bg-[var(--quickforge-sidebar-active-bg)] font-medium text-foreground/92 shadow-[0_8px_22px_-20px_rgb(15_23_42_/_0.32)]`:`text-muted-foreground/76 hover:bg-[var(--quickforge-sidebar-hover-bg)] hover:text-foreground/90 hover:shadow-[0_8px_20px_-18px_rgb(15_23_42_/_0.35)]`),onClick:()=>o(t),"aria-current":n?`page`:void 0,children:[(0,Y.jsx)(`span`,{className:C(`inline-flex size-5 shrink-0 items-center justify-center transition-colors`,n?`text-foreground/72`:`text-muted-foreground/52 group-hover:text-foreground/68`),children:(0,Y.jsx)(r,{className:`size-4`,"aria-hidden":`true`})}),(0,Y.jsx)(`span`,{className:`truncate`,children:e.tab.getTabName()})]},e.key)})})})]}),(0,Y.jsxs)(`main`,{className:`flex min-w-0 flex-1 flex-col bg-[var(--quickforge-main-bg)] md:overflow-hidden md:rounded-l-2xl`,children:[(0,Y.jsxs)(`header`,{className:`flex h-14 shrink-0 items-center gap-2 border-b-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-3 pr-4 md:px-5`,children:[(0,Y.jsx)(de,{variant:`ghost`,size:`icon`,className:`md:hidden`,onClick:n,"aria-label":`返回工作区`,children:(0,Y.jsx)(re,{className:`size-4`})}),(0,Y.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[l?(0,Y.jsx)(l,{className:`size-4 shrink-0 text-muted-foreground/65`,"aria-hidden":`true`}):null,(0,Y.jsx)(`div`,{className:`min-w-0 truncate text-sm font-medium text-foreground/90`,children:c?.tab.getTabName()})]})})]}),(0,Y.jsx)(`div`,{className:`quickforge-settings-mobile-tabs flex shrink-0 gap-1 overflow-x-auto border-b-[0.5px] border-[color-mix(in_oklab,var(--border)_30%,transparent)] px-3 py-2 md:hidden`,children:r.items.map((e,t)=>{let n=t===s,r=$[e.key];return(0,Y.jsxs)(`button`,{type:`button`,className:C(`inline-flex shrink-0 items-center gap-1.5 rounded-full px-3 py-1.5 text-sm transition-colors`,n?`bg-muted text-foreground`:`text-muted-foreground hover:bg-muted/55 hover:text-foreground`),onClick:()=>o(t),children:[(0,Y.jsx)(r,{className:`size-3.5 shrink-0`,"aria-hidden":`true`}),(0,Y.jsx)(`span`,{children:e.tab.getTabName()})]},e.key)})}),(0,Y.jsx)(`section`,{className:`min-h-0 flex-1 overflow-y-auto px-4 py-5 md:px-8 md:py-7`,children:(0,Y.jsx)(`div`,{className:`mx-auto flex min-h-full w-full max-w-5xl flex-col`,children:c?(0,Y.jsx)(Ut,{tab:c.tab}):null})})]})]})}export{Wt as SettingsWorkspacePage};