@muyichengshayu/promptx 0.2.12 → 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/WorkbenchView-pIUuQsCk.js","assets/vendor-misc-u-M8sNMf.js","assets/vendor-misc-ClI1dyrl.css","assets/vendor-ui-BglsaDbv.js","assets/vendor-markdown-9aQhqbjm.js","assets/vendor-tiptap-rwYdQb1L.js","assets/WorkbenchView-DlttkjeG.css"])))=>i.map(i=>d[i]);
2
- import{aC as re,aD as ie,aE as ae,aF as A,aG as se,b as S,c as f,aH as de}from"./vendor-misc-u-M8sNMf.js";import{c as ce,a as le}from"./vendor-router-Dn8q3tJM.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))o(r);new MutationObserver(r=>{for(const i of r)if(i.type==="childList")for(const a of i.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&o(a)}).observe(document,{childList:!0,subtree:!0});function n(r){const i={};return r.integrity&&(i.integrity=r.integrity),r.referrerPolicy&&(i.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?i.credentials="include":r.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(r){if(r.ep)return;r.ep=!0;const i=n(r);fetch(r.href,i)}})();const fe=(e,t)=>{const n=e.__vccOpts||e;for(const[o,r]of t)n[o]=r;return n},ue={},pe={class:"app-shell"},ge={class:"app-main flex min-h-0 flex-1 overflow-hidden px-3 py-3 sm:px-4 sm:py-4 lg:px-4 lg:py-4"},he={class:"app-stage h-full min-h-0 w-full overflow-hidden"};function me(e,t){const n=re("RouterView");return ie(),ae("div",pe,[A("main",ge,[A("div",he,[se(n)])])])}const be=fe(ue,[["render",me]]),ye="modulepreload",Te=function(e){return"/"+e},O={},Se=function(t,n,o){let r=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const a=document.querySelector("meta[property=csp-nonce]"),l=(a==null?void 0:a.nonce)||(a==null?void 0:a.getAttribute("nonce"));r=Promise.allSettled(n.map(u=>{if(u=Te(u),u in O)return;O[u]=!0;const P=u.endsWith(".css"),te=P?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${u}"]${te}`))return;const p=document.createElement("link");if(p.rel=P?"stylesheet":ye,P||(p.as="script"),p.crossOrigin="",p.href=u,l&&p.setAttribute("nonce",l),document.head.appendChild(p),P)return new Promise((ne,oe)=>{p.addEventListener("load",ne),p.addEventListener("error",()=>oe(new Error(`Unable to preload CSS for ${u}`)))})}))}function i(a){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=a,window.dispatchEvent(l),!l.defaultPrevented)throw a}return r.then(a=>{for(const l of a||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})},we=ce({history:le(),routes:[{path:"/",name:"workbench",component:()=>Se(()=>import("./WorkbenchView-pIUuQsCk.js").then(e=>e.B),__vite__mapDeps([0,1,2,3,4,5,6]))}]}),N="promptx:locale",y="zh-CN",D=[{value:"zh-CN",label:"简体中文",englishLabel:"Chinese (Simplified)"},{value:"en-US",label:"English",englishLabel:"English"}],B={"zh-CN":{common:{settings:"设置",save:"保存",saving:"保存中...",saved:"已保存",loading:"读取中...",unavailable:"不可用",cancel:"取消",confirm:"确认",processing:"处理中...",close:"关闭",enabled:"启用",select:"请选择",notAvailable:"暂无",noOptions:"暂无可选项",expand:"展开",collapse:"收起"},locale:{title:"语言",description:"切换 PromptX 界面语言,当前先支持中文和英文。",field:"界面语言",immediateHint:"切换后立即生效,并保存在当前浏览器里。",zhHans:"简体中文",enUs:"English"},workbench:{title:"PromptX 工作台",newMessageTitle:"PromptX 你有新消息...",tasks:"任务",settings:"设置",createTask:"新建任务",creatingTask:"创建中...",loadingTasks:"正在加载任务...",loadingTaskContent:"正在加载任务内容...",untitledTask:"未命名任务",running:"运行中",noMessagesYet:"还没有发送记录",dragToReorder:"拖动排序",filesCount:({count:e})=>`${e} 文件`,editTask:"编辑任务",deleteTask:"删除任务",deletingTask:"删除中...",activity:"执行",input:"输入",selectTask:"请选择一个任务",promptCopied:"已复制提示词",projectCreated:"已新建项目",codeContextTitle:"代码上下文",codeContextFile:({path:e})=>`文件:${e}`,codeContextRange:({range:e})=>`位置:${e}`,codeContextSource:({source:e})=>`来源:${e}`,codeContextSourceDiff:"代码变更",codeContextSourceFile:"源码查看",confirmClearTitle:"确认清空当前任务?",confirmClearDescription:"将清空右侧编辑区内容,但会保留当前任务本身。",confirmClearAction:"确认清空",continueEditing:"继续编辑",confirmDeleteTitle:"确认删除当前任务?",confirmDeleteDescription:({title:e})=>`将删除「${e}」,删除后无法恢复。`,confirmDeleteAction:"确认删除",keepForNow:"先保留",confirmDeleteTodoTitle:"确认删除这条代办?",confirmDeleteTodoDescription:"删除后这条代办将无法恢复。",replaceEditorTitle:"替换编辑区内容?",replaceEditorDescription:"编辑区已有内容。继续使用这条代办会清空当前内容,并替换成代办里的内容。",confirmReplaceAction:"确认替换",dontReplaceYet:"先不替换"},editor:{chooseFiles:"选文件",clear:"清空",todo:"代办",todoWithCount:({count:e})=>`代办 (${e})`,send:"发送",sending:"发送中",running:"执行中",selectAgent:"选择 Agent"},todoDialog:{title:"管理代办",intro:"把临时想法先挂在当前任务下,需要时再取回编辑区继续整理。",summary:({count:e})=>`当前任务共 ${e} 条代办`,summaryHint:"使用后会回填到编辑区并从列表移除",itemTitle:"代办",blockCount:({count:e})=>`共 ${e} 个块`,textCount:({count:e})=>`文本 ${e}`,importedCount:({count:e})=>`导入 ${e}`,imageCount:({count:e})=>`图片 ${e}`,use:"使用",delete:"删除",empty:"还没有代办,先把编辑区里的临时想法收进来吧。",imagePreview:({count:e})=>`包含 ${e} 张图片`,noPreview:"暂时没有可预览的文本内容",justAdded:"刚刚添加"},theme:{title:"主题",sectionDescription:"管理界面主题与语言偏好。",heading:"界面主题",currentTheme:({name:e})=>`当前:${e}`,helper:"像编辑器一样切换整套配色,而不只是深浅模式。",groupLight:"浅色主题",groupDark:"深色主题",description:{"promptx-stone-light":"温和石色,适合长时间白天工作。","promptx-glass-light":"雾面玻璃质感,保留石色与绿调。","promptx-aqua-classic":"复古 macOS Aqua / Snow Leopard 拟物工具台。","promptx-stone-dark":"延续当前工作台气质的深色主题。","github-light":"清爽、克制,适合评审和协作场景。","github-dark":"熟悉的深色代码托管风格。","solarized-light":"低对比暖色纸感,适合长文阅读。","solarized-dark":"经典 Solarized 深色版本,柔和不刺眼。","ink-mist":"偏冷的墨雾风格,适合长时间专注。","promptx-ink-landscape":"冷雾底色、墨青层次和卷轴感留白,像一张浮在山岚上的工作台。","tokyo-night":"更接近编辑器气质的冷调深色主题。"}},settingsDialog:{general:{sectionLabel:"通用",sectionDescription:"基础工作台偏好",title:"通用偏好",intro:"这里放工作台层面的基础交互偏好。后续新增的通用设置可以按配置项来源分别接入,不影响界面使用方式。",remoteCommandSecurityTitle:"远程命令安全",remoteCommandSecurityDescription:"配置远程页面是否允许执行 !git status、!pnpm test 这类高权限命令。",remoteCommandSecurityModeField:"安全模式",remoteCommandSecurityModeDisabled:"不允许",remoteCommandSecurityModeDisabledDescription:"除本机 loopback 访问外,所有远程入口都不允许执行命令模式。",remoteCommandSecurityModeRelay:"Relay",remoteCommandSecurityModeRelayDescription:"只允许通过 PromptX Relay 代理进来的远程请求执行命令模式。",remoteCommandSecurityModeTrustedProxy:"Trusted Proxy",remoteCommandSecurityModeTrustedProxyDescription:"只允许你信任的反向代理入口执行命令模式,并校验代理注入的 token。",trustedProxyTokenField:"Trusted Proxy Token",trustedProxyTokenPlaceholder:"首次启用时请输入 Trusted Proxy Token",trustedProxyTokenReplacePlaceholder:"如需更换请输入新的 Trusted Proxy Token",trustedProxyTokenConfiguredHint:"当前已配置 token。出于安全原因,这里不会回显明文。",trustedProxyTokenHint:"Nginx 需要同时注入 X-PromptX-Trusted-Proxy: 1 和 X-PromptX-Proxy-Token。",trustedProxyTokenReplaceHint:"留空表示保留当前 token,输入新值则覆盖原 token。",remoteCommandSecurityWarning:"这是高权限能力。只有在你信任当前远程入口时才建议开启。",remoteCommandSecuritySave:"保存远程命令设置",remoteCommandSecuritySaved:"已保存",sendBehavior:{title:"发送消息方式",description:"设置编辑区里使用回车发送还是只允许点击按钮发送。",hint:"发送按钮始终可用;这里仅控制编辑器里的键盘发送方式。",options:{enter:{label:"回车发送",description:"单击 Enter 发送,Shift + Enter 换行。"},shiftEnter:{label:"Shift + 回车发送",description:"单击 Enter 换行,Shift + Enter 发送。"},buttonOnly:{label:"仅按钮发送",description:"回车只用于编辑内容,必须点击发送按钮才会发送。"}}},notificationSound:{title:"通知音",description:"控制任务产生未读新进展时是否播放提示音。",switchLabel:"启用通知音",switchHint:"默认关闭。开启后,非当前聚焦任务出现新的未读结果时会播放提示音。"}},relay:{sectionLabel:"远程",sectionDescription:"Relay 与手机访问",title:"远程访问 Relay",enableTitle:"启用远程访问",enableDescription:"关闭后,本机会主动断开当前 Relay 连接。",relayUrl:"Relay 地址",deviceId:"设备 ID",deviceToken:"设备 Token",deviceTokenPlaceholder:"请输入云端 Relay 的设备 token",pausedReconnect:({reason:e})=>`当前已暂停自动重连:${e}`,managedByEnv:"当前 Relay 配置由环境变量接管,设置页仅展示实际值,修改环境变量后需重启服务。",lastError:({value:e})=>`最近错误:${e}`,lastClosed:({reason:e,code:t})=>`最近断开:${e}${t?`(code ${t})`:""}`,lastConnected:({value:e})=>`最近连接:${e}`,recentEvent:({value:e})=>`最近事件:${e}`,copied:"Relay 诊断信息已复制,可直接发给我排查。",defaultHint:"建议公网 Relay 使用 HTTPS,并确保云端与本机使用同一个设备 Token;多租户时每个人填写自己的子域名地址。",reconnectNow:"立即重连",reconnecting:"重连中...",copyDiagnostics:"复制 Relay 诊断信息",diagnosticsCopied:"已复制诊断信息",saveConfig:"保存远程访问配置",relayConfigLoadFailed:"远程访问配置读取失败。",relayConfigSavedEnabled:"远程访问配置已保存,PromptX 正在尝试连接 Relay。",relayConfigSavedDisabled:"远程访问已关闭。",relayConfigSaveFailed:"远程访问配置保存失败。",relayReconnectTriggered:"已触发重连,PromptX 正在重新建立 Relay 连接。",relayReconnectFailed:"触发 Relay 重连失败。",relayFieldsRequired:"请先填写完整的 Relay 地址、设备 ID 和设备 Token,再启用远程访问。",relayEnabledSaved:"远程访问已启用,PromptX 正在尝试连接 Relay。",relayToggleFailed:"远程访问开关保存失败。",relayDiagnosticsCopyFailed:"Relay 诊断信息复制失败。",reason:{invalid_tenant:"当前 Relay 域名未匹配到租户",invalid_token:"设备令牌不匹配",invalid_device:"设备 ID 不匹配",missing_hello:"缺少设备认证报文",missing_auth:"设备认证超时",replaced_by_new_connection:"已被新的设备连接替换",config_updated:"配置已更新,正在重连",heartbeat_timeout:"心跳超时,连接已失效"},event:{reconnect_paused:"已暂停自动重连",local_request_failed:"本地请求转发失败",dispatch_failed:"请求派发失败",connect_failed:"连接失败",reconnect_scheduled:"已计划重连",reconnect_requested:"已请求重连",system_resume_detected:"检测到系统恢复",heartbeat_stale:"检测到心跳过期",connect_start:"开始连接",ws_open:"WebSocket 已建立",auth_ok:"设备认证成功",stale_close_ignored:"已忽略旧连接关闭事件",close:"连接已关闭",error:"连接异常",disabled:"当前未启用",stopped:"已停止",config_updated:"配置已更新",unknown:"未知事件"},error:{connect_failed:"Relay 连接失败。",disconnected:({reason:e})=>`Relay 已断开:${e}`,rejected:({reason:e})=>`Relay 连接被拒绝:${e}`,closedWithCode:({code:e})=>`Relay 连接已关闭(code=${e})`},status:{reconnecting:"重连中...",saving:"保存中...",loading:"读取中...",paused:"已暂停重连",connected:"已连接",waitingReconnect:"等待重连",disconnected:"未连接",disabled:"未启用"}},system:{sectionLabel:"系统",sectionDescription:"Runner 与性能配置",title:"系统配置",intro:"这里同时放 runner 并发上限和运行诊断。后续排查卡顿、排队、stop 回收问题时,优先看下面这组实时统计。",maxConcurrentRuns:"真实 agent 最大并发数",maxConcurrentRunsHint:"超过这个数量的新 run 会进入 queued,等待 runner 空闲后再启动。",managedByEnv:"当前并发上限由环境变量 `PROMPTX_RUNNER_MAX_CONCURRENT_RUNS` 接管,设置页只展示实际值。",diagnosticsHint:"诊断口径已经和真实并发控制对齐:`active` 不再把 queued 误算进去。",saveConfig:"保存系统配置",runtimeDiagnostics:"运行诊断",runtimeDiagnosticsHint:"自动每 5 秒刷新一次,可直接观察 runner、恢复器和清理任务的运行情况。",refreshDiagnostics:"刷新诊断",refreshingDiagnostics:"刷新中...",copyDiagnostics:"复制诊断信息",diagnosticsCopied:"已复制诊断信息",diagnosticsCopiedHint:"系统诊断信息已复制,可直接发给我排查。",active:"真实占用并发槽位",tracked:"runner 内存中的全部上下文",queued:"等待启动的 run",maxConcurrent:"当前生效并发上限",completed:"已完成 run",stopped:"已停止 run",error:"异常结束 run",stopTimeout:"停止超时 run",eventWriteFailures:"事件批量回写失败次数",recoveredRuns:"服务端回收的失联 run",lastMaintenanceAt:"最近一次维护清理完成时间",baseStatus:"基础状态",available:"可用",unknown:"未知",stopReasonTitle:"Stop 原因分类",stopTimeoutPhaseTitle:"Stop Timeout 阶段",runnerUnavailable:"runner 暂不可用",runnerUnavailableDescription:"当前还没有拿到 runner diagnostics。",systemConfigLoadFailed:"系统配置读取失败。",systemConfigSaved:"系统配置已保存,runner 并发上限已更新。",systemConfigSaveFailed:"系统配置保存失败。",systemDiagnosticsLoadFailed:"系统诊断信息读取失败。",systemDiagnosticsCopyFailed:"系统诊断信息复制失败。",stopReasons:{queued_cancelled:"排队前取消",user_requested:"用户主动停止",user_requested_after_error:"停止后报错",stop_timeout:"停止超时"},stopTimeoutPhases:{runner_timeout_without_stop_request:"未记录 stop 请求",runner_timeout_before_cancel:"cancel 前超时",cli_not_exiting:"CLI 不退出",os_kill_slow:"OS kill 慢",runner_finalize_after_exit:"退出后收尾慢"}},shortcuts:{sectionLabel:"快捷键",sectionDescription:"全局操作快捷方式",title:"快捷键",intro:"下面这些是工作台里的全局快捷键,在工作台任意区域都可直接触发。",openSettingsTitle:"打开设置",openSettingsDescription:"快速打开全局设置面板。",openProjectManagerTitle:"打开项目管理",openProjectManagerDescription:"快速打开当前任务绑定的项目管理弹层。",openSourceBrowserTitle:"打开源码查看",openSourceBrowserDescription:"直接进入当前项目的只读源码查看弹层。",openDiffReviewTitle:"打开代码变更",openDiffReviewDescription:"快速打开当前任务所在项目的代码变更弹层。",closeTopDialogTitle:"关闭当前最上层弹层",closeTopDialogDescription:"优先关闭最上层的确认框、源码查看、项目管理或设置。",note:"当前快捷键优先面向桌面端;移动端仍以点击操作为主。"},about:{sectionLabel:"关于",sectionDescription:"版本与说明",title:"关于",intro:"这里先放版本信息,后面像更新日志、环境说明也可以继续往这里放。",versionTitle:"版本信息",versionDescription:"当前已安装的 PromptX 版本。",versionPending:"当前服务暂未返回版本号,请确认已重启到最新版本。",versionLoadFailed:"版本信息读取失败。"}},taskDialog:{title:"编辑任务",currentTask:({title:e})=>`当前任务:${e}`,loading:"正在读取任务配置...",sections:{basic:{label:"基础",description:"标题与任务信息",title:"基础信息",intro:"这里维护任务标题,留空时继续使用自动标题。",taskTitle:"任务标题",taskTitlePlaceholder:"留空则继续使用自动标题"},automation:{label:"定时",description:"自动运行设置",title:"定时运行",intro:"用可视化方式设置自动运行时间,不需要手填 Cron。",mode:"运行周期",time:"运行时间",weekday:"每周日期",timezone:"时区",concurrencyPolicy:"并发策略",lastTriggered:({value:e})=>`最近触发:${e}`,nextTriggered:({value:e})=>`下次触发:${e}`,modeDaily:"每天",modeWeekdays:"工作日",modeWeekly:"每周",weekday1:"周一",weekday2:"周二",weekday3:"周三",weekday4:"周四",weekday5:"周五",weekday6:"周六",weekday0:"周日",timezoneLocal:"跟随本机时区",concurrencySkip:"已有运行时跳过本次"},notification:{label:"通知",description:"运行结束通知",title:"运行通知",intro:"run 结束后按规则把结果推送到群机器人。",channelType:"渠道类型",triggerOn:"触发时机",webhookUrl:"Webhook 地址",webhookUrlPlaceholder:"请输入群机器人 Webhook 地址",secret:"签名密钥(可选)",secretPlaceholder:"开启签名时再填写",locale:"通知语言",localeZhCn:"简体中文",localeEnUs:"English",messageMode:"消息模式",status:({value:e})=>`通知状态:${e}`,lastSent:({value:e})=>`最近发送:${e}`,lastError:({value:e})=>`最近错误:${e}`,channelDingtalk:"钉钉 Webhook",channelFeishu:"飞书 Webhook",channelWebhook:"通用 Webhook",triggerCompleted:"本次运行结束后",triggerSuccess:"本次运行成功后",triggerError:"本次运行失败后",messageSummary:"摘要消息",statusDisabled:"未启用",statusSuccess:"最近发送成功",statusError:"最近发送失败",statusPending:"等待首次发送"}},enabled:"启用",footerHint:"定时运行会按 Cron 创建新的 run;运行通知会在本次 run 结束后按规则发送到群机器人。",saveTaskConfig:"保存任务配置",loadFailed:"任务配置读取失败。",saveFailed:"任务配置保存失败。"},taskActions:{taskSaved:"任务已保存",taskCreated:"已创建新任务",taskCleared:"已清空当前任务内容,稍后会自动保存",todoAdded:"已加入代办",fileProcessing:"文件仍在处理中,请稍后再操作任务。",fileProcessingBeforeSend:"文件仍在处理中,请稍后再发送给当前执行引擎。",sessionLocked:"该任务已有项目历史,不能再切换项目;如需使用新项目,请新建任务。",noTextImported:"没有读取到可插入的文本内容",textImportFailed:"文件读取失败,请确认使用 UTF-8 编码的纯文本文件。",noPdfContent:"没有从 PDF 中解析出可插入内容",pdfImportFailed:"PDF 解析失败,请确认文件不是扫描件,并且内容为单栏图文。",imageInserted:({count:e,appended:t})=>t?`已把 ${e} 张图片插入到当前导入块后方,稍后会自动保存`:`已插入 ${e} 张图片,稍后会自动保存`,importedBlocksInserted:({count:e,appended:t})=>t?`已把 ${e} 个文件块插入到当前导入块后方,稍后会自动保存`:`已插入 ${e} 个文件块,稍后会自动保存`,pdfBlocksInserted:({blockCount:e,pageCount:t})=>`已插入 ${e} 个图文块${t?`,共 ${t} 页`:""},稍后会自动保存`,insertedToEditor:"已插入到右侧编辑区"},projectManager:{managingTitle:"PromptX 项目管理",createTitle:"新建项目",editTitle:"编辑项目",newProject:"新建项目",projectList:"项目列表",noProjects:"还没有项目,先新建一个固定工作目录。",create:"新建",current:"当前",regular:"普通",untitledProject:"未命名项目",enginePrefix:"引擎:{value}",updatedAtPrefix:"最近更新:{value}",runtimeStatus:"运行状态",currentProject:"当前项目",engine:"执行引擎",workingDirectory:"工作目录",notSet:"未设置",updatedAt:"最近更新",note:"说明",noteDescription:"项目绑定目录与执行引擎,目录不变时会继续复用同一条引擎会话。",projectTitleOptional:"项目标题(可选)",workingDirectoryField:"工作目录",choose:"选择",chooseDirectory:"选择目录",engineField:"执行引擎",selectEngine:"请选择执行引擎",collaborationAgents:"协作 Agents",collaborationAgentsHint:"默认 Agent 继续使用上面的会话 ID;额外勾选的 Agent 会共享同一目录,并在首次发送时自动建立各自线程。",agentEnabled:"已加入当前项目",agentDisabled:"点击加入当前项目",agentCount:({count:e})=>`${e} 个 Agent`,noEngines:"暂无可用执行引擎",comingSoon:"即将支持",confirmDeleteTitle:"确认删除 PromptX 项目?",confirmDeleteDescription:({title:e})=>`将删除「${e}」这条本地记录,不会删除工作目录,也不会删除对应执行引擎的历史数据。`,confirmDelete:"确认删除",newSession:"新会话",resettingSession:"重置中...",confirmResetTitle:"确认新建项目会话?",confirmResetDescription:({title:e})=>`这会清空「${e}」当前绑定的会话,以及该项目下所有任务的执行历史;不会删除项目、工作目录和右侧编辑内容。下次运行将从新会话开始。`,confirmReset:"确认新会话",sessionReset:"已重置当前项目会话,下次运行将从新会话开始。",keep:"先保留",basicInfo:"基本信息",status:"状态",close:"关闭",backToList:"返回列表",deleteProject:"删除项目",deletingProject:"删除中...",createProject:"创建项目",creatingProject:"创建中...",saveChanges:"保存修改",savingChanges:"保存中...",directoryRequired:"请先填写工作目录。",projectMissing:"当前项目不存在,请重新选择。",duplicateDirectory:({labels:e,count:t})=>`该目录已被${e}${t>3?"等项目":"项目"}使用,建议优先复用,避免把同一目录拆成多个项目。`,cwdReadonly:"当前项目已绑定执行引擎会话,工作目录不能再修改;如需使用新目录,请新建项目。",engineReadonly:"当前项目已绑定执行引擎会话,执行引擎不能再修改;如需更换,请新建项目。",sessionId:"会话 ID",sessionIdHint:"留空则首次运行时自动创建;填写已有 ID 则继续复用该会话。",sessionIdReadonly:"当前项目已实际运行,会话 ID 不能再修改;如需切换,请新建项目。",sessionCandidates:"已有本机会话",sessionCandidatesLoading:"加载...",noSessionCandidates:"没有匹配的本机会话,仍可手动填写。",sessionCandidatesNeedDirectory:"请先选择工作目录,再选择已有会话;也可以直接手动填写。",copySessionId:"复制",sessionIdCopied:"已复制",copySessionIdFailed:"会话 ID 复制失败。",viewSource:"查看源码",running:"运行中",idle:"空闲",threadBound:"已绑定线程",notStarted:"未启动",unknown:"未知",syncingProjects:"加载...",syncingLatestProjects:"加载...",projectCount:({count:e})=>`共 ${e} 个项目`,selectProject:"请选择项目",noProjectsInSelect:"还没有项目,请先到管理弹窗里新建。"},sourceBrowser:{title:"查看源码",readOnlyHint:({title:e})=>`当前为「${e}」的只读源码浏览`,noWorkspace:"当前项目还没有绑定工作目录。",noProject:"请先选择项目。",searchLabel:"搜索文件",searchPlaceholder:"搜索文件名或路径片段",contentSearchPlaceholder:"按文件内容搜索",searchModePath:"路径",searchModeContent:"内容",searchAction:"搜索",searchMinKeywordHint:({count:e})=>`至少输入 ${e} 个字符后再开始搜索。`,searchEmpty:"没有找到匹配文件。",contentSearchPrompt:"正在等待搜索结果...",contentSearchEmpty:"没有找到匹配内容。",contentSearching:"正在搜索文件内容...",contentSearchFailed:"文件内容搜索失败。",contentSearchResultMeta:({path:e,line:t})=>`${e} · 第 ${t} 行`,contentSearchTruncated:"结果较多,当前只展示前一部分命中。",treeEmpty:"当前目录下没有可显示的文件。",loadingFiles:"正在加载文件列表...",recent:"最近",results:"结果",previewLoading:"正在加载文件内容...",previewFailed:"文件内容读取失败。",selectFile:"请先从左侧选择一个文件。",selectFileHint:"当前选中的是目录,请继续选择文件。",truncated:"已截断",binaryUnsupported:"当前文件为二进制内容,暂不支持在线预览。",binaryTooLarge:"当前文件较大,暂不支持在线预览。",selectCodeLineHint:"直接拖选代码,选区旁会显示插入按钮。",selectedLines:({count:e})=>`已选 ${e} 行`,insertSelection:"插入到编辑区"},directoryPicker:{title:"选择工作目录",intro:"默认只在当前用户目录下浏览和搜索;特殊路径继续用手动输入。",currentSelection:"当前选中",selectionPlaceholder:"请在目录树或搜索结果里选择目录",searchLabel:"搜索目录",searchPlaceholder:"输入目录名或路径片段,例如 promptx / code",searchMinKeywordHint:({count:e})=>`至少输入 ${e} 个字符后再开始搜索。`,searching:"搜索中...",treeLoading:"目录树加载中...",noSearchResults:"没搜到匹配目录,试试更短的关键词,或者直接用目录树浏览。",emptyTree:"当前没有可显示的目录。",truncatedHint:"搜索结果已截断,只展示最相关的一部分目录。",cancel:"取消",useCurrentDirectory:"使用当前目录",unnamedDirectory:"未命名目录",loadFailed:"目录加载失败。",treeLoadFailed:"目录树加载失败。",searchFailed:"搜索失败。"},pathPicker:{selectProjectFirst:"请先选择项目。",noResults:"无结果",emptyDirectory:"空目录",loading:"加载中...",recent:"最近",results:"结果"},diffReview:{dialogTitle:"代码变更",dialogTitleWithTask:({title:e})=>`代码变更 · ${e}`,scopeCurrentShort:"当前",scopeCurrent:"当前变更",scopeTaskShort:"累计",scopeTask:"任务累计",scopeRun:"本轮",refresh:"刷新",refreshing:"刷新中...",computing:"统计中...",selectRun:"请选择历史执行",noRuns:"暂无可查看的历史执行",runCount:({count:e})=>`共 ${e} 条可审查执行`,loading:"正在读取代码变更...",unavailableTitle:"暂时无法查看代码变更",unavailableReason:"当前没有可展示的代码变更。",unknownBranch:"未识别分支",fileCount:({count:e})=>`${e} 个文件`,waitingStats:"等待统计",filesTab:"文件",diffTab:"Diff",searchFilePath:"搜索文件路径",statsPending:"已先展示文件列表,整体增删行数正在后台统计...",noChanges:"当前范围内还没有检测到代码变更。",noMatches:"当前筛选或搜索条件下没有匹配文件。",statsOnDemand:"行数按需统计",changeIndex:({current:e,total:t})=>`改动 ${e}/${t}`,loadingFileDiff:"正在加载该文件的 diff...",noFileDiffContent:"当前文件没有可展示的 diff 内容。",selectFile:"请选择一个文件查看 diff。",binaryPreviewUnavailable:"二进制文件暂不支持在线 diff 预览。",binaryPreviewTitle:"二进制预览",binaryTag:"二进制",binaryMetaTitle:"文件元信息",binaryBefore:"变更前",binaryAfter:"变更后",binarySideMissing:"该侧文件不存在。",downloadBinarySide:"下载文件",binaryPreviewTooLarge:"文件较大,暂不支持在线预览。",binarySnapshotUnavailable:"历史快照中没有保存该二进制文件内容。",openImagePreview:"查看大图",fileTooLarge:"文件内容较大,暂不展示具体 diff。",diffTooLong:"diff 内容较长,暂不在页面内完整展示。",diffPreviewOnly:"diff 内容较长,当前仅展示摘要预览。",fileDiffTimedOut:"该文件 diff 计算较慢,暂不在线展示详细内容,请优先在本地查看。",notGitRepo:"当前工作目录不是 Git 仓库,暂不支持代码变更审查。",taskNotFound:"任务不存在。",runRequired:"请选择一轮执行后再查看本轮代码变更。",runNotFound:"没有找到对应的执行记录。",runBaselineMissing:"这轮执行还没有建立代码变更基线,暂时无法查看本轮 diff。",taskBaselineMissing:"当前任务还没有建立代码变更基线,请先让 Codex 执行一轮。",runSnapshotMissing:"这轮执行缺少结束快照,暂时无法准确还原本轮代码变更。",fileNotInDiff:"当前文件不在本次 diff 范围内。",originalRepoInvalid:"原工作目录已不是有效的 Git 仓库,暂时无法读取代码变更。",baselineCommitMissing:"基线对应的 commit 已不存在,仓库可能被 reset、rebase 或切换到无关历史,暂时无法准确读取该范围的代码变更。",warningBranchChanged:({from:e,to:t})=>`当前分支已从 ${e} 切换到 ${t}`,warningHeadDetachedFromBaseline:"当前 HEAD 已不在基线 commit 的后续历史中,仓库可能经历了 reset、rebase 或切分支",baselineTime:({value:e})=>`基线时间:${e}`,baselineBranch:({value:e})=>`基线分支:${e}`,baselineCommit:({value:e})=>`基线 commit:${e}`,currentHead:({value:e})=>`当前 HEAD:${e}`,completed:"已完成",failed:"失败",interrupted:"已中断",stopped:"已停止",added:"新增",deleted:"删除",modified:"修改",all:"全部",noReviewRuns:"当前还没有可用于审查的历史执行记录。",selectCodeLineHint:"直接拖选代码,选区旁会显示插入按钮。",selectedLines:({count:e})=>`已选 ${e} 行`,insertSelection:"插入到编辑区"},sessionPanel:{diff:"代码变更",manageProjects:"管理项目",agentFilter:"Agent 过滤",allAgents:"全部",emptyAgentFilter:"当前 Agent 暂无消息。",showProcessToggle:"显示执行过程",hideProcessToggle:"隐藏执行过程",empty:"这里会显示项目执行过程和模型回复。",promptTitleWithAgent:({agent:e})=>`PromptX → ${e}:`,expand:"展开",collapse:"收起",promptImageAlt:"本轮提示词图片",processTitle:"执行:",loading:"加载中...",loadingEvents:"正在加载执行过程...",hiddenEventsLoaded:({count:e})=>`已折叠 ${e} 条过程日志`,hiddenEventsLoadLater:({count:e})=>`共 ${e} 条过程日志,展开后加载`,waitingEvents:({agent:e})=>`正在等待 ${e} 返回事件...`,noEvents:"本轮没有记录执行过程。",view:"查看",insert:"插入",copyCode:"复制",copyCodeAria:"复制代码",codeCopied:"已复制代码",defaultAgent:"默认",agentNotEnabled:"当前项目没有启用这个 Agent,请先到项目管理里勾选。",shellUnsupportedBlocks:"命令模式暂不支持图片或导入文件,请只保留纯文本命令。",shellEmptyCommand:"请输入要执行的命令,例如 !git status",errorSuffix:({agent:e})=>`${e}:`,responseSuffix:({agent:e})=>`${e}:`,jumpToLatest:"有新消息,跳到底部",stop:"停止",stopping:"正在停止..."},runner:{status:{queued:"当前仍在排队,等待 runner 空闲后开始执行。",stopping:"正在停止执行,等待引擎退出...",thinking:({agentLabel:e})=>`${e} 正在思考中...`}},processDetail:{changeCreate:"新增",changeDelete:"删除",changeUpdate:"更新",changeGeneric:"变更",subAgentPending:"等待启动",subAgentRunning:"运行中",subAgentCompleted:"已完成",subAgentFailed:"失败",subAgentUnknown:"未知状态",directorySummary:({count:e})=>`${e} 项`,directoryHidden:({count:e})=>`,还有 ${e} 项未展示`,hiddenItems:({count:e})=>`还有 ${e} 项未展示`,hiddenLines:({count:e})=>`还有 ${e} 行未展示`,searchMatchCount:({count:e})=>`${e} 处命中`,searchHiddenMatches:({count:e})=>`该文件还有 ${e} 处命中未展示`,searchFileSummary:({fileCount:e,matchCount:t})=>`${e} 个文件,${t} 处命中`,searchHiddenFiles:({count:e})=>`,还有 ${e} 个文件未展示`},blockEditor:{stats:({lines:e,chars:t})=>`${e} 行 · ${t} 字符`,title:"输入文本、图片或文件",uploading:"正在处理文件",placeholderFirst:"从这里开始写需求...",placeholderNext:"继续输入...",delete:"删除",image:"图片",file:"文件",unnamedFile:"未命名文件",unnamedImage:"未命名图片",unnamedPdf:"未命名 PDF",fileSummary:({name:e,stats:t})=>`${e}(${t})`,expand:"展开",collapse:"折叠",convertToText:"转文本",emptyContent:"空内容",emptyImportPlaceholder:"导入内容为空",insertedImageAlt:"已插入图片",unsupportedFiles:({names:e,extra:t})=>`这些文件暂不支持:${e}${t?` 等 ${t} 个文件`:""}`,oversizedFiles:({names:e,extra:t,limit:n})=>`这些文件超过大小限制:${e}${t?` 等 ${t} 个文件`:""},请控制在 ${n} 以内`},imagePreview:{zoomOut:"缩小",zoomIn:"放大",previous:"上一张",next:"下一张",close:"关闭",alt:"图片预览"},misc:{promptxVersionDescription:"当前已安装的 PromptX 版本。"},errors:{requestFailed:"请求失败。",taskCreateFailed:"任务创建失败。",taskNotFound:"任务不存在。",taskExpired:"任务已过期。",taskUpdateFailed:"任务更新失败。",taskDeleteWhileRunning:"当前任务正在执行中,请先停止后再删除。",taskClearRunsWhileRunning:"当前任务正在执行中,请先停止后再清空记录。",taskSessionLocked:"该任务已有项目历史,不能再切换项目;如需使用新项目,请新建任务。",sessionRequired:"请先选择一个 PromptX 项目。",sessionNotFound:"没有找到对应的 PromptX 项目。",currentProjectRunning:"当前项目正在运行中,请等待完成后再发送。",currentProjectDeleteWhileRunning:"当前项目正在执行中,请先停止后再删除。",runNotFound:"没有找到对应的执行记录。",invalidDiffScope:"无效的 diff 范围。",gitDiffFailed:"git diff 计算失败。",invalidPath:"路径不合法。",pathOutsideWorkspace:"只能访问当前工作目录内的文件。",directoryNotFound:"目录不存在,请重新选择。",directoryOnly:"只能选择文件夹。",targetPathNotFound:"目标路径不存在。",directoryExpandOnly:"只能展开目录。",cwdRequired:"请先填写工作目录。",cwdNotFound:"工作目录不存在,请重新确认。",cwdMustBeDirectory:"工作目录必须是文件夹。",startedProjectCwdLocked:"已启动的 PromptX 项目不能直接修改工作目录。",startedProjectEngineLocked:"已启动的 PromptX 项目不能直接切换执行引擎,请新建项目。",startedProjectSessionLocked:"已启动的 PromptX 项目不能直接修改会话 ID,请新建项目。",agentEngineUnavailable:"当前执行引擎不可用。",noPromptToSend:"没有可发送的提示词。",shellUnsupportedBlocks:"命令模式暂不支持图片或导入文件,请只保留纯文本命令。",shellEmptyCommand:"请输入要执行的命令,例如 !git status",shellLocalOnly:"当前入口未被允许执行命令。请在设置 -> 通用 -> 远程命令安全中启用对应模式,或改为本机本地访问。",runnerRequestTimeout:"runner 请求超时。",runnerServiceUnavailable:"无法连接 runner 服务。",runnerDiagnosticsReadFailed:"无法读取 runner diagnostics",relayNotEnabled:"当前远程访问尚未启用,请先保存完整的 Relay 配置。",systemConfigHotReloadFailed:"系统配置已保存,但 runner 热更新失败。",systemConfigReadFailed:"系统配置读取失败。",uploadFileMissing:"没有收到上传文件。",uploadImageOnly:"只支持上传图片文件。",pdfFileMissing:"没有收到 PDF 文件。",pdfOnly:"只支持导入 PDF 文件。",pdfNoImportableContent:"没有从 PDF 中提取到可导入的文本或图片。",fileTooLarge:"文件太大了。",unexpectedServerError:"发生了意外错误。",streamUnsupported:"浏览器不支持流式响应。",uploadFailed:"上传失败。",pdfImportFailed:"PDF 导入失败。",transcriptOpenFailed:"无法打开本地会话存储",transcriptOperationFailed:"本地会话存储操作失败",transcriptAborted:"本地会话存储操作已中断"},sessionTurns:{currentProjectRunning:"当前项目正在运行中,请等待完成后再发送。",noPromptToSend:"没有可发送的提示词。"}},"en-US":{common:{settings:"Settings",save:"Save",saving:"Saving...",saved:"Saved",loading:"Loading...",unavailable:"Unavailable",cancel:"Cancel",confirm:"Confirm",processing:"Processing...",close:"Close",enabled:"Enabled",select:"Select",notAvailable:"N/A",noOptions:"No options available",expand:"Expand",collapse:"Collapse"},locale:{title:"Language",description:"Switch the PromptX UI language. Chinese and English are supported for now.",field:"Interface language",immediateHint:"Changes apply immediately and are stored in this browser.",zhHans:"简体中文",enUs:"English"},workbench:{title:"Workspace",newMessageTitle:"PromptX You Have New Messages...",tasks:"Tasks",settings:"Settings",createTask:"New",creatingTask:"Creating...",loadingTasks:"Loading tasks...",loadingTaskContent:"Loading task content...",untitledTask:"Untitled Task",running:"Running",noMessagesYet:"No messages sent yet",dragToReorder:"Drag to reorder",filesCount:({count:e})=>`${e} files`,editTask:"Edit",deleteTask:"Delete",deletingTask:"Deleting...",activity:"Activity",input:"Input",selectTask:"Select a task",promptCopied:"Prompt copied",projectCreated:"Project created",codeContextTitle:"Code context",codeContextFile:({path:e})=>`File: ${e}`,codeContextRange:({range:e})=>`Range: ${e}`,codeContextSource:({source:e})=>`Source: ${e}`,codeContextSourceDiff:"Code changes",codeContextSourceFile:"Source browser",confirmClearTitle:"Clear the current task?",confirmClearDescription:"This clears the editor content on the right, but keeps the current task itself.",confirmClearAction:"Clear Task",continueEditing:"Keep Editing",confirmDeleteTitle:"Delete the current task?",confirmDeleteDescription:({title:e})=>`This will delete "${e}". This action cannot be undone.`,confirmDeleteAction:"Delete Task",keepForNow:"Keep It",confirmDeleteTodoTitle:"Delete this todo?",confirmDeleteTodoDescription:"This todo cannot be restored after deletion.",replaceEditorTitle:"Replace editor content?",replaceEditorDescription:"The editor already has content. Using this todo will clear the current content and replace it with the todo content.",confirmReplaceAction:"Replace Content",dontReplaceYet:"Not Now"},editor:{chooseFiles:"Files",clear:"Clear",todo:"Todo",todoWithCount:({count:e})=>`Todo (${e})`,send:"Send",sending:"Sending",running:"Running",selectAgent:"Select Agent"},todoDialog:{title:"Manage Todo",intro:"Store temporary ideas under the current task and bring them back to the editor when needed.",summary:({count:e})=>`${e} todo item(s) in the current task`,summaryHint:"Using one fills the editor and removes it from the list",itemTitle:"Todo",blockCount:({count:e})=>`${e} block(s)`,textCount:({count:e})=>`Text ${e}`,importedCount:({count:e})=>`Imported ${e}`,imageCount:({count:e})=>`Image ${e}`,use:"Use",delete:"Delete",empty:"No todo items yet. Save a temporary idea from the editor first.",imagePreview:({count:e})=>`Contains ${e} image(s)`,noPreview:"No text preview is available yet",justAdded:"Just added"},theme:{title:"Theme",sectionDescription:"Manage theme and language preferences.",heading:"Interface theme",currentTheme:({name:e})=>`Current: ${e}`,helper:"Switch the full visual system like an editor, not just light and dark mode.",groupLight:"Light Themes",groupDark:"Dark Themes",description:{"promptx-stone-light":"Soft stone tones for long daytime sessions.","promptx-glass-light":"A frosted glass look with stone and green accents.","promptx-aqua-classic":"A retro macOS Aqua / Snow Leopard skeuomorphic workbench.","promptx-stone-dark":"A dark theme that keeps the current PromptX feel.","github-light":"Clean and restrained, good for review and collaboration.","github-dark":"A familiar dark code-hosting style.","solarized-light":"Warm paper-like contrast, great for long reading.","solarized-dark":"Classic Solarized dark, soft on the eyes.","ink-mist":"A cool ink-mist style for focused long sessions.","promptx-ink-landscape":"Cool mist, ink-blue layers, and scroll-like spacing for a floating landscape desk feel.","tokyo-night":"A cooler dark theme with a sharper editor-like feel."}},settingsDialog:{general:{sectionLabel:"General",sectionDescription:"Core workbench preferences",title:"General Preferences",intro:"This section holds core workbench interaction preferences. Future general settings can use different backing stores without changing the UI model.",remoteCommandSecurityTitle:"Remote Command Security",remoteCommandSecurityDescription:"Control whether remote pages may execute high-privilege commands such as !git status or !pnpm test.",remoteCommandSecurityModeField:"Security mode",remoteCommandSecurityModeDisabled:"Disabled",remoteCommandSecurityModeDisabledDescription:"Blocks command mode for all remote entry points except local loopback access.",remoteCommandSecurityModeRelay:"Relay",remoteCommandSecurityModeRelayDescription:"Allows command mode only for remote requests coming through PromptX Relay.",remoteCommandSecurityModeTrustedProxy:"Trusted Proxy",remoteCommandSecurityModeTrustedProxyDescription:"Allows command mode only for your trusted reverse proxy entry and validates the injected token.",trustedProxyTokenField:"Trusted Proxy Token",trustedProxyTokenPlaceholder:"Enter the Trusted Proxy Token when enabling this mode for the first time",trustedProxyTokenReplacePlaceholder:"Enter a new Trusted Proxy Token to replace the current one",trustedProxyTokenConfiguredHint:"A token is already configured. For safety the current value is not shown here.",trustedProxyTokenHint:"Your reverse proxy must inject both X-PromptX-Trusted-Proxy: 1 and X-PromptX-Proxy-Token.",trustedProxyTokenReplaceHint:"Leave this blank to keep the current token, or enter a new one to replace it.",remoteCommandSecurityWarning:"This is a high-privilege capability. Only enable it when you trust the current remote entry point.",remoteCommandSecuritySave:"Save Remote Command Settings",remoteCommandSecuritySaved:"Saved",sendBehavior:{title:"Send Message Behavior",description:"Choose whether Enter sends from the editor or sending is limited to the button.",hint:"The send button always works. This only changes keyboard sending inside the editor.",options:{enter:{label:"Enter Sends",description:"Press Enter to send and Shift + Enter to insert a new line."},shiftEnter:{label:"Shift + Enter Sends",description:"Press Enter to insert a new line and Shift + Enter to send."},buttonOnly:{label:"Button Only",description:"Enter is always used for editing. Sending only happens from the send button."}}},notificationSound:{title:"Notification Sound",description:"Control whether unread task updates play a notification sound.",switchLabel:"Enable Notification Sound",switchHint:"Disabled by default. When enabled, a sound plays when a non-focused task gets a new unread result."}},relay:{sectionLabel:"Remote",sectionDescription:"Relay and mobile access",title:"Remote Access Relay",enableTitle:"Enable remote access",enableDescription:"Turning this off disconnects the current Relay connection from this machine.",relayUrl:"Relay URL",deviceId:"Device ID",deviceToken:"Device Token",deviceTokenPlaceholder:"Enter the device token from your cloud Relay",pausedReconnect:({reason:e})=>`Auto reconnect is paused: ${e}`,managedByEnv:"Relay config is currently managed by environment variables. The settings page shows the effective values only, and the service must be restarted after changing env vars.",lastError:({value:e})=>`Last error: ${e}`,lastClosed:({reason:e,code:t})=>`Last disconnect: ${e}${t?` (code ${t})`:""}`,lastConnected:({value:e})=>`Last connected: ${e}`,recentEvent:({value:e})=>`Recent event: ${e}`,copied:"Relay diagnostics copied. You can send them to me for troubleshooting.",defaultHint:"HTTPS is recommended for public Relay deployments. Make sure the cloud Relay and local client use the same device token. In multi-tenant mode, each person should use their own subdomain.",reconnectNow:"Reconnect Now",reconnecting:"Reconnecting...",copyDiagnostics:"Copy Relay Diagnostics",diagnosticsCopied:"Diagnostics Copied",saveConfig:"Save Remote Access",relayConfigLoadFailed:"Failed to load remote access settings.",relayConfigSavedEnabled:"Remote access settings saved. PromptX is trying to connect to Relay.",relayConfigSavedDisabled:"Remote access disabled.",relayConfigSaveFailed:"Failed to save remote access settings.",relayReconnectTriggered:"Reconnect triggered. PromptX is re-establishing the Relay connection.",relayReconnectFailed:"Failed to trigger Relay reconnect.",relayFieldsRequired:"Fill in Relay URL, Device ID, and Device Token before enabling remote access.",relayEnabledSaved:"Remote access enabled. PromptX is trying to connect to Relay.",relayToggleFailed:"Failed to save the remote access toggle.",relayDiagnosticsCopyFailed:"Failed to copy Relay diagnostics.",reason:{invalid_tenant:"The current Relay domain does not match any tenant.",invalid_token:"Device token does not match.",invalid_device:"Device ID does not match.",missing_hello:"Missing device hello packet.",missing_auth:"Device authentication timed out.",replaced_by_new_connection:"Replaced by a newer device connection.",config_updated:"Configuration updated. Reconnecting.",heartbeat_timeout:"Heartbeat timed out and the connection became invalid."},event:{reconnect_paused:"Auto reconnect paused",local_request_failed:"Local request forwarding failed",dispatch_failed:"Request dispatch failed",connect_failed:"Connection failed",reconnect_scheduled:"Reconnect scheduled",reconnect_requested:"Reconnect requested",system_resume_detected:"System resume detected",heartbeat_stale:"Heartbeat became stale",connect_start:"Connecting",ws_open:"WebSocket opened",auth_ok:"Device authenticated",stale_close_ignored:"Ignored stale close event",close:"Connection closed",error:"Connection error",disabled:"Disabled",stopped:"Stopped",config_updated:"Configuration updated",unknown:"Unknown event"},error:{connect_failed:"Relay connection failed.",disconnected:({reason:e})=>`Relay disconnected: ${e}`,rejected:({reason:e})=>`Relay connection rejected: ${e}`,closedWithCode:({code:e})=>`Relay connection closed (code=${e})`},status:{reconnecting:"Reconnecting...",saving:"Saving...",loading:"Loading...",paused:"Reconnect Paused",connected:"Connected",waitingReconnect:"Waiting to Reconnect",disconnected:"Disconnected",disabled:"Disabled"}},system:{sectionLabel:"System",sectionDescription:"Runner and performance",title:"System",intro:"Runner concurrency limits and runtime diagnostics live here. When investigating lag, queueing, or stop/recovery issues, start with the realtime stats below.",maxConcurrentRuns:"Max concurrent real agent runs",maxConcurrentRunsHint:"New runs beyond this limit enter the queue and start when the runner becomes available.",managedByEnv:"The concurrency limit is managed by `PROMPTX_RUNNER_MAX_CONCURRENT_RUNS`. The settings page shows the effective value only.",diagnosticsHint:"Diagnostics now match real concurrency control: `active` no longer incorrectly counts queued runs.",saveConfig:"Save System Settings",runtimeDiagnostics:"Runtime Diagnostics",runtimeDiagnosticsHint:"Refreshes every 5 seconds so you can watch runner, recovery, and maintenance activity in real time.",refreshDiagnostics:"Refresh Diagnostics",refreshingDiagnostics:"Refreshing...",copyDiagnostics:"Copy Diagnostics",diagnosticsCopied:"Diagnostics Copied",diagnosticsCopiedHint:"System diagnostics copied. You can send them to me for troubleshooting.",active:"Actively occupying concurrency slots",tracked:"All tracked contexts in runner memory",queued:"Runs waiting to start",maxConcurrent:"Current active concurrency limit",completed:"Completed runs",stopped:"Stopped runs",error:"Errored runs",stopTimeout:"Stop-timeout runs",eventWriteFailures:"Batched event write failures",recoveredRuns:"Disconnected runs recovered by server",lastMaintenanceAt:"Last maintenance cleanup",baseStatus:"Base Status",available:"Available",unknown:"Unknown",stopReasonTitle:"Stop Reason Breakdown",stopTimeoutPhaseTitle:"Stop Timeout Phases",runnerUnavailable:"Runner unavailable",runnerUnavailableDescription:"Runner diagnostics are not available yet.",systemConfigLoadFailed:"Failed to load system settings.",systemConfigSaved:"System settings saved. Runner concurrency has been updated.",systemConfigSaveFailed:"Failed to save system settings.",systemDiagnosticsLoadFailed:"Failed to load system diagnostics.",systemDiagnosticsCopyFailed:"Failed to copy system diagnostics.",stopReasons:{queued_cancelled:"Cancelled before start",user_requested:"Stopped by user",user_requested_after_error:"Errored after stop request",stop_timeout:"Stop timeout"},stopTimeoutPhases:{runner_timeout_without_stop_request:"No stop request recorded",runner_timeout_before_cancel:"Timed out before cancel",cli_not_exiting:"CLI did not exit",os_kill_slow:"OS kill was slow",runner_finalize_after_exit:"Slow cleanup after exit"}},shortcuts:{sectionLabel:"Shortcuts",sectionDescription:"Global keyboard actions",title:"Shortcuts",intro:"These shortcuts work across the workbench and can be triggered from any area.",openSettingsTitle:"Open settings",openSettingsDescription:"Open the global settings dialog quickly.",openProjectManagerTitle:"Open project manager",openProjectManagerDescription:"Open the project manager for the current task.",openSourceBrowserTitle:"Open source browser",openSourceBrowserDescription:"Jump straight into the read-only source browser for the current project.",openDiffReviewTitle:"Open code changes",openDiffReviewDescription:"Open the code changes dialog for the current task project.",closeTopDialogTitle:"Close the top dialog",closeTopDialogDescription:"Closes the topmost confirm dialog, source browser, project manager, or settings panel first.",note:"These shortcuts are primarily designed for desktop. Mobile still relies on touch interactions."},about:{sectionLabel:"About",sectionDescription:"Version and info",title:"About",intro:"Version info lives here for now. Changelog and environment notes can join this section later.",versionTitle:"Version",versionDescription:"The currently installed PromptX version.",versionPending:"The current service has not returned a version yet. Please confirm it has been restarted to the latest version.",versionLoadFailed:"Failed to load version info."}},taskDialog:{title:"Edit Task",currentTask:({title:e})=>`Current task: ${e}`,loading:"Loading task settings...",sections:{basic:{label:"Basic",description:"Title and task info",title:"Basic Info",intro:"Manage the task title here. Leave it empty to keep using the auto title.",taskTitle:"Task Title",taskTitlePlaceholder:"Leave empty to keep the auto title"},automation:{label:"Schedule",description:"Automatic runs",title:"Scheduled Run",intro:"Configure the schedule visually. No need to type Cron by hand.",mode:"Run cycle",time:"Run time",weekday:"Weekday",timezone:"Timezone",concurrencyPolicy:"Concurrency policy",lastTriggered:({value:e})=>`Last triggered: ${e}`,nextTriggered:({value:e})=>`Next trigger: ${e}`,modeDaily:"Daily",modeWeekdays:"Weekdays",modeWeekly:"Weekly",weekday1:"Mon",weekday2:"Tue",weekday3:"Wed",weekday4:"Thu",weekday5:"Fri",weekday6:"Sat",weekday0:"Sun",timezoneLocal:"Follow local timezone",concurrencySkip:"Skip if another run is active"},notification:{label:"Notify",description:"Run completion notifications",title:"Run Notifications",intro:"Push run results to a group bot after the run finishes.",channelType:"Channel",triggerOn:"Trigger",webhookUrl:"Webhook URL",webhookUrlPlaceholder:"Enter the bot webhook URL",secret:"Signing secret (optional)",secretPlaceholder:"Fill this only if signing is enabled",locale:"Notification language",localeZhCn:"简体中文",localeEnUs:"English",messageMode:"Message mode",status:({value:e})=>`Notification status: ${e}`,lastSent:({value:e})=>`Last sent: ${e}`,lastError:({value:e})=>`Last error: ${e}`,channelDingtalk:"DingTalk Webhook",channelFeishu:"Feishu Webhook",channelWebhook:"Generic Webhook",triggerCompleted:"After this run finishes",triggerSuccess:"After this run succeeds",triggerError:"After this run fails",messageSummary:"Summary message",statusDisabled:"Disabled",statusSuccess:"Last send succeeded",statusError:"Last send failed",statusPending:"Waiting for first send"}},enabled:"Enabled",footerHint:"Scheduled runs create new runs from Cron. Notifications are sent to the group bot after the current run finishes.",saveTaskConfig:"Save Task Settings",loadFailed:"Failed to load task settings.",saveFailed:"Failed to save task settings."},taskActions:{taskSaved:"Task saved",taskCreated:"New task created",taskCleared:"Current task content cleared. It will be auto-saved shortly.",todoAdded:"Added to todo",fileProcessing:"Files are still being processed. Please wait before editing this task.",fileProcessingBeforeSend:"Files are still being processed. Please wait before sending to the current engine.",sessionLocked:"This task already has project history, so the project cannot be changed. Create a new task if you want to use a different project.",noTextImported:"No insertable text content was found.",textImportFailed:"Failed to read the file. Please use UTF-8 encoded plain text files.",noPdfContent:"No insertable content was parsed from the PDF.",pdfImportFailed:"Failed to parse the PDF. Please make sure it is not a scanned file and uses a single-column layout.",imageInserted:({count:e,appended:t})=>t?`${e} image(s) inserted after the current import block. They will be auto-saved shortly.`:`${e} image(s) inserted. They will be auto-saved shortly.`,importedBlocksInserted:({count:e,appended:t})=>t?`${e} imported block(s) inserted after the current import block. They will be auto-saved shortly.`:`${e} imported block(s) inserted. They will be auto-saved shortly.`,pdfBlocksInserted:({blockCount:e,pageCount:t})=>`${e} mixed content block(s) inserted${t?` across ${t} page(s)`:""}. They will be auto-saved shortly.`,insertedToEditor:"Inserted into the editor"},projectManager:{managingTitle:"PromptX Project Manager",createTitle:"Create Project",editTitle:"Edit Project",newProject:"New Project",projectList:"Projects",noProjects:"No projects yet. Create one with a fixed working directory first.",create:"Create",current:"Current",regular:"Normal",untitledProject:"Untitled Project",enginePrefix:"Engine: {value}",updatedAtPrefix:"Updated: {value}",runtimeStatus:"Runtime Status",currentProject:"Current Project",engine:"Engine",workingDirectory:"Working Directory",notSet:"Not set",updatedAt:"Updated",note:"Note",noteDescription:"A project binds a directory and engine. When the directory stays the same, PromptX keeps reusing the same engine session.",projectTitleOptional:"Project Title (optional)",workingDirectoryField:"Working Directory",choose:"Choose",chooseDirectory:"Choose Directory",engineField:"Engine",selectEngine:"Select an engine",collaborationAgents:"Collaborating Agents",collaborationAgentsHint:"The default agent continues to use the session ID above. Extra checked agents share the same workspace and create their own threads on first send.",agentEnabled:"Included in this project",agentDisabled:"Click to include",agentCount:({count:e})=>`${e} agent(s)`,noEngines:"No engine options available",comingSoon:"Coming soon",confirmDeleteTitle:"Delete this PromptX project?",confirmDeleteDescription:({title:e})=>`This deletes the local record "${e}". It will not delete the working directory or the engine history.`,confirmDelete:"Delete Project",newSession:"New Session",resettingSession:"Resetting...",confirmResetTitle:"Start a new project session?",confirmResetDescription:({title:e})=>`This clears the current session bound to "${e}" and removes the run history of tasks under this project. The project, working directory, and editor content stay intact. The next run starts from a fresh session.`,confirmReset:"Start New Session",sessionReset:"Project session reset. The next run will start fresh.",keep:"Keep It",basicInfo:"Basic Info",status:"Status",close:"Close",backToList:"Back to List",deleteProject:"Delete Project",deletingProject:"Deleting...",createProject:"Create Project",creatingProject:"Creating...",saveChanges:"Save Changes",savingChanges:"Saving...",directoryRequired:"Please enter a working directory first.",projectMissing:"The current project no longer exists. Please select it again.",duplicateDirectory:({labels:e,count:t})=>`This directory is already used by ${e}${t>3?" and others":""}. Reusing it is recommended so the same directory does not get split into multiple projects.`,cwdReadonly:"This project is already bound to an engine session, so the working directory can no longer be changed. Create a new project to use another directory.",engineReadonly:"This project is already bound to an engine session, so the engine can no longer be changed. Create a new project to switch engines.",sessionId:"Session ID",sessionIdHint:"Leave it empty to create one on first run, or fill an existing ID to resume that session.",sessionIdReadonly:"This project has already run, so the session ID can no longer be changed. Create a new project to switch it.",sessionCandidates:"Local sessions",sessionCandidatesLoading:"Loading...",noSessionCandidates:"No matching local sessions. Manual input is still supported.",sessionCandidatesNeedDirectory:"Choose a working directory before selecting a local session. Manual input is still allowed.",copySessionId:"Copy",sessionIdCopied:"Copied",copySessionIdFailed:"Failed to copy session ID.",viewSource:"View Source",running:"Running",idle:"Idle",threadBound:"Bound",notStarted:"New",unknown:"Unknown",syncingProjects:"Loading...",syncingLatestProjects:"Loading...",projectCount:({count:e})=>`${e} project(s)`,selectProject:"Select a project",noProjectsInSelect:"No projects yet. Create one in the manager first."},sourceBrowser:{title:"Source Browser",readOnlyHint:({title:e})=>`Read-only source view for "${e}"`,noWorkspace:"This project does not have a working directory yet.",noProject:"Select a project first.",searchLabel:"Search Files",searchPlaceholder:"Search by file name or path fragment",contentSearchPlaceholder:"Search inside file contents",searchModePath:"Path",searchModeContent:"Content",searchAction:"Search",searchMinKeywordHint:({count:e})=>`Enter at least ${e} characters to start searching.`,searchEmpty:"No matching files were found.",contentSearchPrompt:"Waiting for search results...",contentSearchEmpty:"No matching content was found.",contentSearching:"Searching file contents...",contentSearchFailed:"Failed to search file contents.",contentSearchResultMeta:({path:e,line:t})=>`${e} · line ${t}`,contentSearchTruncated:"Only the first portion of matches is shown.",treeEmpty:"There are no files to display in this directory.",loadingFiles:"Loading files...",recent:"Recent",results:"Results",previewLoading:"Loading file content...",previewFailed:"Failed to load file content.",selectFile:"Select a file from the left panel.",selectFileHint:"A directory is selected. Choose a file to preview.",truncated:"Truncated",binaryUnsupported:"This is a binary file and cannot be previewed inline right now.",binaryTooLarge:"This file is too large to preview inline right now.",selectCodeLineHint:"Select code directly. An insert button appears beside the selection.",selectedLines:({count:e})=>`${e} line(s) selected`,insertSelection:"Insert into editor"},directoryPicker:{title:"Choose Working Directory",intro:"Browsing and search are limited to the current user home by default. Use manual input for special paths.",currentSelection:"Current Selection",selectionPlaceholder:"Select a directory from the tree or search results",searchLabel:"Search Directories",searchPlaceholder:"Enter a directory name or path fragment, such as promptx / code",searchMinKeywordHint:({count:e})=>`Enter at least ${e} characters to start searching.`,searching:"Searching...",treeLoading:"Loading directory tree...",noSearchResults:"No matching directories found. Try a shorter keyword, or browse the directory tree directly.",emptyTree:"There are no directories to display.",truncatedHint:"Search results were truncated to show only the most relevant directories.",cancel:"Cancel",useCurrentDirectory:"Use Current Directory",unnamedDirectory:"Unnamed Directory",loadFailed:"Failed to load directories.",treeLoadFailed:"Failed to load the directory tree.",searchFailed:"Search failed."},pathPicker:{selectProjectFirst:"Select a project first.",noResults:"No results",emptyDirectory:"Empty directory",loading:"Loading...",recent:"Recent",results:"Results"},diffReview:{dialogTitle:"Changes",dialogTitleWithTask:({title:e})=>`Changes · ${e}`,scopeCurrentShort:"Now",scopeCurrent:"Current Changes",scopeTaskShort:"Total",scopeTask:"Task Total",scopeRun:"Run",refresh:"Refresh",refreshing:"Refreshing...",computing:"Computing...",selectRun:"Select a run",noRuns:"No historical runs are available",runCount:({count:e})=>`${e} reviewable run(s)`,loading:"Loading code changes...",unavailableTitle:"Code changes are unavailable right now",unavailableReason:"There are no code changes to display right now.",unknownBranch:"Unknown branch",fileCount:({count:e})=>`${e} file(s)`,waitingStats:"Waiting for stats",filesTab:"Files",diffTab:"Diff",searchFilePath:"Search file paths",statsPending:"The file list is already available. Total additions and deletions are still being computed in the background...",noChanges:"No code changes were detected in the current scope.",noMatches:"No files match the current filter or search.",statsOnDemand:"Stats loaded on demand",changeIndex:({current:e,total:t})=>`Change ${e}/${t}`,loadingFileDiff:"Loading diff for this file...",noFileDiffContent:"This file has no diff content to display.",selectFile:"Select a file to view the diff.",binaryPreviewUnavailable:"Binary files are not supported for inline diff preview yet.",binaryPreviewTitle:"Binary Preview",binaryTag:"Binary",binaryMetaTitle:"File Metadata",binaryBefore:"Before",binaryAfter:"After",binarySideMissing:"This side does not exist.",downloadBinarySide:"Download file",binaryPreviewTooLarge:"The file is too large to preview inline right now.",binarySnapshotUnavailable:"This historical snapshot did not store the binary file body.",openImagePreview:"Open image preview",fileTooLarge:"The file is too large to show its detailed diff.",diffTooLong:"The diff is too long to render in full on this page.",diffPreviewOnly:"The diff is long, so PromptX shows a summarized preview only.",fileDiffTimedOut:"This file diff took too long to compute, so PromptX does not render it inline right now.",notGitRepo:"The current working directory is not a Git repository, so code review is unavailable.",taskNotFound:"Task not found.",runRequired:"Select a run before reviewing code changes for that run.",runNotFound:"The requested run was not found.",runBaselineMissing:"This run has not established a code-change baseline yet, so its diff is unavailable for now.",taskBaselineMissing:"This task has not established a code-change baseline yet. Let the agent run once first.",runSnapshotMissing:"This run is missing its final snapshot, so PromptX cannot accurately reconstruct its code changes.",fileNotInDiff:"This file is not part of the current diff scope.",originalRepoInvalid:"The original working directory is no longer a valid Git repository, so PromptX cannot read these code changes.",baselineCommitMissing:"The baseline commit no longer exists. The repository may have been reset, rebased, or moved onto unrelated history, so PromptX cannot accurately read this diff range.",warningBranchChanged:({from:e,to:t})=>`Current branch changed from ${e} to ${t}`,warningHeadDetachedFromBaseline:"The current HEAD is no longer in the descendant history of the baseline commit. The repository may have been reset, rebased, or switched to another branch.",baselineTime:({value:e})=>`Baseline time: ${e}`,baselineBranch:({value:e})=>`Baseline branch: ${e}`,baselineCommit:({value:e})=>`Baseline commit: ${e}`,currentHead:({value:e})=>`Current HEAD: ${e}`,completed:"Completed",failed:"Failed",interrupted:"Interrupted",stopped:"Stopped",added:"Add",deleted:"Del",modified:"Edit",all:"All",noReviewRuns:"There are no historical runs available for review yet.",selectCodeLineHint:"Select code directly. An insert button appears beside the selection.",selectedLines:({count:e})=>`${e} line(s) selected`,insertSelection:"Insert into editor"},sessionPanel:{diff:"Changes",manageProjects:"Projects",agentFilter:"Agent filter",allAgents:"All",emptyAgentFilter:"No messages for this agent yet.",showProcessToggle:"Show execution details",hideProcessToggle:"Hide execution details",empty:"Project execution activity and model replies appear here.",promptTitleWithAgent:({agent:e})=>`PromptX → ${e}:`,expand:"Expand",collapse:"Collapse",promptImageAlt:"Prompt image",processTitle:"Run:",loading:"Loading...",loadingEvents:"Loading execution details...",hiddenEventsLoaded:({count:e})=>`${e} execution log(s) collapsed`,hiddenEventsLoadLater:({count:e})=>`${e} execution log(s) available. Expand to load.`,waitingEvents:({agent:e})=>`Waiting for more events from ${e}...`,noEvents:"No execution details were recorded for this run.",view:"View",insert:"Insert",copyCode:"Copy",copyCodeAria:"Copy code",codeCopied:"Code copied",defaultAgent:"Default",agentNotEnabled:"This project does not enable that agent yet. Add it in project settings first.",shellUnsupportedBlocks:"Shell mode only supports plain text commands. Remove images or imported files first.",shellEmptyCommand:"Enter a command to run, for example !git status",errorSuffix:({agent:e})=>`${e}:`,responseSuffix:({agent:e})=>`${e}:`,jumpToLatest:"New messages, jump to bottom",stop:"Stop",stopping:"Stopping..."},runner:{status:{queued:"Still queued, waiting for runner to become idle.",stopping:"Stopping execution, waiting for engine to exit...",thinking:({agentLabel:e})=>`${e} is thinking...`}},processDetail:{changeCreate:"Added",changeDelete:"Deleted",changeUpdate:"Updated",changeGeneric:"Changed",subAgentPending:"Pending start",subAgentRunning:"Running",subAgentCompleted:"Completed",subAgentFailed:"Failed",subAgentUnknown:"Unknown",directorySummary:({count:e})=>`${e} item(s)`,directoryHidden:({count:e})=>`, ${e} more hidden`,hiddenItems:({count:e})=>`${e} more item(s) hidden`,hiddenLines:({count:e})=>`${e} more line(s) hidden`,searchMatchCount:({count:e})=>`${e} match(es)`,searchHiddenMatches:({count:e})=>`${e} more match(es) hidden in this file`,searchFileSummary:({fileCount:e,matchCount:t})=>`${e} file(s), ${t} match(es)`,searchHiddenFiles:({count:e})=>`, ${e} more file(s) hidden`},blockEditor:{stats:({lines:e,chars:t})=>`${e} line(s) · ${t} char(s)`,title:"Input text, images, or files",uploading:"Processing files",placeholderFirst:"Start describing your task here...",placeholderNext:"Continue typing...",delete:"Delete",image:"Image",file:"File",unnamedFile:"Unnamed File",unnamedImage:"Unnamed Image",unnamedPdf:"Unnamed PDF",fileSummary:({name:e,stats:t})=>`${e} (${t})`,expand:"Expand",collapse:"Collapse",convertToText:"Convert to Text",emptyContent:"Empty content",emptyImportPlaceholder:"Imported content is empty",insertedImageAlt:"Inserted image",unsupportedFiles:({names:e,extra:t})=>`Unsupported files: ${e}${t?` and ${t} more`:""}`,oversizedFiles:({names:e,extra:t,limit:n})=>`These files exceed the size limit: ${e}${t?` and ${t} more`:""}. Keep each file within ${n}.`},imagePreview:{zoomOut:"Zoom Out",zoomIn:"Zoom In",previous:"Previous",next:"Next",close:"Close",alt:"Image preview"},misc:{promptxVersionDescription:"The currently installed PromptX version."},errors:{requestFailed:"Request failed.",taskCreateFailed:"Failed to create the task.",taskNotFound:"Task not found.",taskExpired:"Task has expired.",taskUpdateFailed:"Failed to update the task.",taskDeleteWhileRunning:"This task is still running. Stop it before deleting.",taskClearRunsWhileRunning:"This task is still running. Stop it before clearing its run history.",taskSessionLocked:"This task already has project history and can no longer switch projects. Create a new task if you need another project.",sessionRequired:"Please select a PromptX project first.",sessionNotFound:"The requested PromptX project was not found.",currentProjectRunning:"The current project is still running. Please wait until it finishes before sending again.",currentProjectDeleteWhileRunning:"This project is still running. Stop it before deleting.",runNotFound:"The requested run was not found.",invalidDiffScope:"Invalid diff scope.",gitDiffFailed:"Failed to calculate git diff.",invalidPath:"Invalid path.",pathOutsideWorkspace:"You can only access files inside the current working directory.",directoryNotFound:"Directory not found. Please choose again.",directoryOnly:"Only folders can be selected.",targetPathNotFound:"Target path not found.",directoryExpandOnly:"Only directories can be expanded.",cwdRequired:"Please enter a working directory first.",cwdNotFound:"The working directory does not exist. Please check it again.",cwdMustBeDirectory:"The working directory must be a folder.",startedProjectCwdLocked:"The working directory cannot be changed after the PromptX project has started.",startedProjectEngineLocked:"The engine cannot be changed after the PromptX project has started. Please create a new project.",startedProjectSessionLocked:"The session ID cannot be changed after the PromptX project has started. Please create a new project.",agentEngineUnavailable:"The selected engine is currently unavailable.",noPromptToSend:"There is no prompt to send.",shellUnsupportedBlocks:"Shell mode only supports plain text commands. Remove images or imported files first.",shellEmptyCommand:"Enter a command to run, for example !git status",shellLocalOnly:"This entry point is not allowed to execute shell commands. Enable the matching mode in Settings -> General -> Remote Command Security, or switch to local access.",runnerRequestTimeout:"The runner request timed out.",runnerServiceUnavailable:"Unable to connect to the runner service.",runnerDiagnosticsReadFailed:"Unable to read runner diagnostics.",relayNotEnabled:"Remote access is not enabled yet. Save a complete Relay configuration first.",systemConfigHotReloadFailed:"System settings were saved, but runner hot reload failed.",systemConfigReadFailed:"Failed to read system settings.",uploadFileMissing:"No file was uploaded.",uploadImageOnly:"Only image files can be uploaded.",pdfFileMissing:"No PDF file was uploaded.",pdfOnly:"Only PDF files can be imported.",pdfNoImportableContent:"No importable text or image content was extracted from the PDF.",fileTooLarge:"The file is too large.",unexpectedServerError:"An unexpected server error occurred.",streamUnsupported:"Streaming responses are not supported in this browser.",uploadFailed:"Upload failed.",pdfImportFailed:"PDF import failed.",transcriptOpenFailed:"Unable to open local transcript storage",transcriptOperationFailed:"Local transcript storage operation failed",transcriptAborted:"Local transcript storage operation was aborted"},sessionTurns:{currentProjectRunning:"The current project is still running. Please wait until it finishes before sending again.",noPromptToSend:"There is no prompt to send."}}};function ve(e="",t={}){return String(e).replace(/\{(\w+)\}/g,(n,o)=>String((t==null?void 0:t[o])??""))}function E(e=""){var n;const t=String(e||"").trim();return((n=D.find(o=>o.value===t))==null?void 0:n.value)||y}function ke(e=""){const t=E(e);return D.find(n=>n.value===t)||D[0]}function j(e={},t=""){return String(t||"").split(".").filter(Boolean).reduce((n,o)=>n==null?void 0:n[o],e)}const g=S(y),R=S(!1);function Pe(){return y}function q(e){typeof document>"u"||(document.documentElement.lang=e)}function X(){return g.value}function I(e="",t={},n=""){const o=E(g.value),r=B[o]||B[y],i=B[y]||{},a=j(r,e)??j(i,e);return typeof a=="function"?a(t):typeof a=="string"?ve(a,t):n||e}function Ce(){if(typeof window>"u")return g.value=y,R.value=!0,g.value;const e=window.localStorage.getItem(N),t=E(e||Pe());return g.value=t,window.localStorage.setItem(N,t),q(t),R.value=!0,t}function xe(e=""){const t=E(e);g.value=t,typeof window<"u"&&window.localStorage.setItem(N,t),q(t),R.value=!0}function Ie(e="",t={}){const n=String(e||"").trim();if(!n)return I("common.notAvailable");const o=new Date(n);return Number.isNaN(o.getTime())?I("common.notAvailable"):new Intl.DateTimeFormat(X(),t).format(o)}function Le(e="",t=""){return String(e||"").localeCompare(String(t||""),X())}function _e(){const e=f(()=>g.value),t=f(()=>D.map(o=>({value:o.value,label:o.label,englishLabel:o.englishLabel}))),n=f(()=>ke(g.value));return{locale:e,localeMeta:n,localeOptions:t,localeReady:R,setLocale:xe,t:I}}const C="promptx:theme-id",T="promptx-stone-light",z=[{id:"promptx-stone-light",name:"Stone Light",shortName:"Stone Light",mode:"light",description:"温和石色,适合长时间白天工作。",swatches:["#f1eee8","#fbfaf8","#d6cdc1","#3f7a67"],colors:{appBg:"#f1eee8",appPanel:"#fbfaf8",appPanelMuted:"#f5f1ea",appPanelStrong:"#ffffff",appPanelHover:"#efe8de",appPanelInset:"#e8e0d4",appOverlay:"rgba(255, 252, 246, 0.82)",borderDefault:"#d1c7ba",borderMuted:"#e4dbcf",borderStrong:"#b2a594",textPrimary:"#000000",textSecondary:"#302a25",textMuted:"#554c43",textInverse:"#fffdf9",buttonBg:"#f8f4ed",buttonHover:"#ede4d9",buttonBorder:"#cbbfb1",buttonText:"#221d19",primaryBg:"#221d19",primaryHover:"#3b342e",primaryBorder:"#221d19",primaryText:"#fffaf4",inputBg:"#fffdf9",inputBorder:"#cbbfb1",focusRing:"rgba(100, 86, 74, 0.22)",selectionBg:"#d8cec0",selectionText:"#241f1b",accent:"#2b7a66",accentSoft:"#e3f1ec",accentText:"#184d40",warning:"#b07a2c",warningSoft:"#fbedd4",warningText:"#7a521c",danger:"#b45151",dangerSoft:"#f9e3e3",dangerText:"#7e2f2f",success:"#2c8a57",successSoft:"#e5f4ea",successText:"#1d5d3b",info:"#2563a6",infoSoft:"#e3eefb",infoText:"#1f4a79",promptBg:"#f5dec2",promptBorder:"#d7aa77",promptText:"#58391d",processBg:"#f3eee6",processBorder:"#d6cab9",processText:"#312b26",responseBg:"#e6f2eb",responseBorder:"#9bc4ab",responseText:"#1f4f37",codeBg:"#f5f1ea",codeBorder:"#dbd1c3",shadowPanel:"0 14px 38px rgba(53, 38, 22, 0.08)",shadowPopover:"0 18px 48px rgba(43, 30, 18, 0.16)"}},{id:"promptx-glass-light",name:"Glass Light",shortName:"Glass Light",mode:"light",mobileEnabled:!1,description:"雾面玻璃质感,保留石色与绿调。",swatches:["#e5eeea","#f7fbf9","#bdd0c7","#2f7b68"],colors:{appBg:"#e4ebe7",appPanel:"#f4faf7",appPanelMuted:"#edf4f0",appPanelStrong:"#ffffff",appPanelHover:"#edf5f1",appPanelInset:"#e0ebe5",appOverlay:"rgba(248, 252, 250, 0.68)",borderDefault:"#b8cbc2",borderMuted:"#d7e4de",borderStrong:"#95aea4",textPrimary:"#000000",textSecondary:"#293630",textMuted:"#495952",textInverse:"#f7fffb",buttonBg:"rgba(247, 251, 249, 0.58)",buttonHover:"rgba(241, 247, 244, 0.82)",buttonBorder:"rgba(149, 174, 164, 0.56)",buttonText:"#183228",primaryBg:"#2f7b68",primaryHover:"#388773",primaryBorder:"#2f7b68",primaryText:"#f3fffa",inputBg:"rgba(255, 255, 255, 0.56)",inputBorder:"rgba(149, 174, 164, 0.62)",focusRing:"rgba(47, 123, 104, 0.2)",selectionBg:"#caded6",selectionText:"#18211d",accent:"#2f7b68",accentSoft:"rgba(220, 242, 234, 0.86)",accentText:"#1c5a49",warning:"#a77736",warningSoft:"#f9ecd7",warningText:"#6f4918",danger:"#b85d66",dangerSoft:"#f9e4e7",dangerText:"#7a343f",success:"#33845f",successSoft:"#e1f3e9",successText:"#1f5d42",info:"#2f6899",infoSoft:"#e1edf8",infoText:"#20486b",promptBg:"#efe2d0",promptBorder:"#cda87c",promptText:"#5b3f26",processBg:"rgba(240, 245, 243, 0.84)",processBorder:"#c3d2cb",processText:"#2d3833",responseBg:"#e2f0ea",responseBorder:"#8ab8a5",responseText:"#1e5440",codeBg:"rgba(241, 246, 244, 0.92)",codeBorder:"#cbdad3",shadowPanel:"0 18px 46px rgba(76, 95, 86, 0.16)",shadowPopover:"0 22px 56px rgba(64, 82, 74, 0.2)",shellGradient:"radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.92) 0%, rgba(255, 255, 255, 0.6) 22%, transparent 42%), radial-gradient(circle at 84% 12%, rgba(178, 219, 204, 0.34) 0%, transparent 34%), radial-gradient(circle at 78% 82%, rgba(240, 210, 176, 0.26) 0%, transparent 30%), linear-gradient(180deg, #e6efea 0%, #dce7e2 44%, #d7e2de 100%)",backdropBlur:"18px",backdropSaturate:"180%",panelHighlight:"rgba(255, 255, 255, 0.64)",panelChrome:"rgba(214, 228, 221, 0.42)",buttonHighlight:"rgba(255, 255, 255, 0.54)",inputHighlight:"rgba(255, 255, 255, 0.72)",modalBackdrop:"rgba(52, 63, 57, 0.22)"}},{id:"promptx-aqua-classic",name:"Aqua Classic",shortName:"Aqua",mode:"light",mobileEnabled:!1,description:"复古 macOS Aqua / Snow Leopard 拟物工具台。",swatches:["#d7dee7","#f7f9fb","#9aa9b8","#2f78c4"],colors:{appBg:"#dce3eb",appPanel:"#edf1f5",appPanelMuted:"#dfe6ee",appPanelStrong:"#fbfcfd",appPanelHover:"#e5ebf2",appPanelInset:"#c8d4df",appOverlay:"rgba(238, 244, 250, 0.78)",borderDefault:"#a9b4bf",borderMuted:"#c7d0d9",borderStrong:"#7d8b99",textPrimary:"#111820",textSecondary:"#273441",textMuted:"#5d6874",textInverse:"#ffffff",buttonBg:"#e8edf2",buttonHover:"#f4f8fc",buttonBorder:"#8f9baa",buttonText:"#1d2834",primaryBg:"#2f78c4",primaryHover:"#3d87d2",primaryBorder:"#2468af",primaryText:"#ffffff",inputBg:"#ffffff",inputBorder:"#94a4b4",focusRing:"rgba(47, 120, 196, 0.26)",selectionBg:"#b7d7fb",selectionText:"#102336",accent:"#2f78c4",accentSoft:"#d9ebff",accentText:"#174b83",warning:"#a66f22",warningSoft:"#fff0cf",warningText:"#6c4614",danger:"#b94b4b",dangerSoft:"#ffe2e2",dangerText:"#813131",success:"#2c8a55",successSoft:"#dff3e8",successText:"#1e5c3a",info:"#2f78c4",infoSoft:"#d9ebff",infoText:"#174b83",promptBg:"#f7efe4",promptBorder:"#c9a46f",promptText:"#4d3921",processBg:"#eef2f6",processBorder:"#b8c3cf",processText:"#2a3642",responseBg:"#e1effb",responseBorder:"#8eb7dc",responseText:"#173f63",codeBg:"#f6f8fb",codeBorder:"#b9c4cf",shadowPanel:"0 10px 24px rgba(54, 68, 82, 0.12)",shadowPopover:"0 14px 34px rgba(42, 54, 68, 0.18)",shellGradient:"linear-gradient(180deg, #edf1f5 0%, #dde4eb 46%, #d2dae3 100%)",backdropBlur:"0px",backdropSaturate:"100%",panelHighlight:"rgba(255, 255, 255, 0.68)",panelChrome:"rgba(139, 153, 168, 0.16)",buttonHighlight:"rgba(255, 255, 255, 0.66)",inputHighlight:"rgba(255, 255, 255, 0.84)",modalBackdrop:"rgba(22, 31, 42, 0.32)"}},{id:"promptx-stone-dark",name:"Stone Dark",shortName:"Stone Dark",mode:"dark",description:"延续当前工作台气质的深色主题。",swatches:["#211d1a","#2b2723","#5a4f47","#89c4ab"],colors:{appBg:"#211d1a",appPanel:"#2b2723",appPanelMuted:"#26221e",appPanelStrong:"#322d28",appPanelHover:"#36302b",appPanelInset:"#24201d",appOverlay:"rgba(39, 34, 29, 0.82)",borderDefault:"#4c433d",borderMuted:"#403832",borderStrong:"#665b53",textPrimary:"#eee7de",textSecondary:"#cbbfb1",textMuted:"#a89c90",textInverse:"#211d1a",buttonBg:"#35302b",buttonHover:"#3d3731",buttonBorder:"#5a4f47",buttonText:"#ebe2d8",primaryBg:"#d7d0c5",primaryHover:"#e4ddd2",primaryBorder:"#d7d0c5",primaryText:"#211d1a",inputBg:"#28231f",inputBorder:"#5a4f47",focusRing:"rgba(156, 141, 125, 0.28)",selectionBg:"#62574f",selectionText:"#f8f5ef",accent:"#78bda1",accentSoft:"#2b3a33",accentText:"#e0f0e8",warning:"#d1aa74",warningSoft:"#413428",warningText:"#f2dfbd",danger:"#cb8882",dangerSoft:"#402927",dangerText:"#f1e0dc",success:"#95c6a1",successSoft:"#2a382e",successText:"#eef7ef",info:"#97b8e1",infoSoft:"#273644",infoText:"#dde9fa",promptBg:"#584637",promptBorder:"#97765b",promptText:"#f8ecdc",processBg:"#25211e",processBorder:"#4d453f",processText:"#c4b8ab",responseBg:"#2b3a31",responseBorder:"#708f7b",responseText:"#eef7ef",codeBg:"#26211e",codeBorder:"#403832",shadowPanel:"0 18px 42px rgba(0, 0, 0, 0.28)",shadowPopover:"0 24px 56px rgba(0, 0, 0, 0.4)"}},{id:"github-light",name:"GitHub Light",shortName:"GitHub Light",mode:"light",description:"清爽、克制,适合评审和协作场景。",swatches:["#f6f8fa","#ffffff","#d0d7de","#0969da"],colors:{appBg:"#f6f8fa",appPanel:"#ffffff",appPanelMuted:"#f6f8fa",appPanelStrong:"#ffffff",appPanelHover:"#f3f4f6",appPanelInset:"#eef2f6",appOverlay:"rgba(255, 255, 255, 0.86)",borderDefault:"#d0d7de",borderMuted:"#d8dee4",borderStrong:"#afb8c1",textPrimary:"#000000",textSecondary:"#2b3138",textMuted:"#505962",textInverse:"#ffffff",buttonBg:"#f6f8fa",buttonHover:"#eef2f6",buttonBorder:"#d0d7de",buttonText:"#111418",primaryBg:"#24292f",primaryHover:"#363b42",primaryBorder:"#24292f",primaryText:"#ffffff",inputBg:"#ffffff",inputBorder:"#d0d7de",focusRing:"rgba(9, 105, 218, 0.18)",selectionBg:"#cce5ff",selectionText:"#0b1f33",accent:"#0969da",accentSoft:"#ddf4ff",accentText:"#0550ae",warning:"#9a6700",warningSoft:"#fff8c5",warningText:"#7d4e00",danger:"#cf222e",dangerSoft:"#ffebe9",dangerText:"#a40e26",success:"#1a7f37",successSoft:"#dafbe1",successText:"#116329",info:"#0969da",infoSoft:"#ddf4ff",infoText:"#0550ae",promptBg:"#fff1db",promptBorder:"#d4a458",promptText:"#6b4b16",processBg:"#f6f8fa",processBorder:"#d8dee4",processText:"#30363d",responseBg:"#eaf5ff",responseBorder:"#9ecbff",responseText:"#0a3069",codeBg:"#f6f8fa",codeBorder:"#d8dee4",shadowPanel:"0 12px 34px rgba(31, 35, 40, 0.08)",shadowPopover:"0 16px 42px rgba(31, 35, 40, 0.16)"}},{id:"promptx-wechat-light",name:"WeChat Light",shortName:"WeChat",mode:"light",description:"偏微信桌面端的轻白、浅灰、绿色强调主题。",swatches:["#ededed","#ffffff","#e5e5e5","#07c160"],colors:{appBg:"#ececec",appPanel:"#ffffff",appPanelMuted:"#f0f0f0",appPanelStrong:"#ffffff",appPanelHover:"#e7e7e7",appPanelInset:"#e4f7ee",appOverlay:"rgba(255, 255, 255, 0.82)",borderDefault:"#d0d0d0",borderMuted:"#e0e0e0",borderStrong:"#d8d8d8",textPrimary:"#000000",textSecondary:"#1f1f1f",textMuted:"#666666",textInverse:"#ffffff",buttonBg:"#ffffff",buttonHover:"#f2f2f2",buttonBorder:"#dfdfdf",buttonText:"#1f1f1f",primaryBg:"#18ac71",primaryHover:"#159865",primaryBorder:"#18ac71",primaryText:"#ffffff",inputBg:"#f7f7f7",inputBorder:"#e1e1e1",focusRing:"rgba(24, 172, 113, 0.16)",selectionBg:"#cfe2ff",selectionText:"#102a43",accent:"#18ac71",accentSoft:"#ddf5ea",accentText:"#0d7348",warning:"#b88230",warningSoft:"#fbf1df",warningText:"#7a5621",danger:"#cf4f4f",dangerSoft:"#fdeaea",dangerText:"#983434",success:"#18ac71",successSoft:"#ddf5ea",successText:"#0d7348",info:"#2563a6",infoSoft:"#eaf2fb",infoText:"#194878",promptBg:"#ddf5ea",promptBorder:"#18ac71",promptText:"#1f1f1f",processBg:"#ffffff",processBorder:"#ebebeb",processText:"#1f1f1f",responseBg:"#eeeef0",responseBorder:"#dddddf",responseText:"#1f1f1f",codeBg:"#f7f7f7",codeBorder:"#d8d8d8",shadowPanel:"0 1px 2px rgba(0, 0, 0, 0.04)",shadowPopover:"0 12px 28px rgba(0, 0, 0, 0.12)",shellGradient:"linear-gradient(180deg, #ededed 0%, #ededed 100%)",backdropBlur:"0px",backdropSaturate:"100%",panelHighlight:"rgba(255, 255, 255, 0)",panelChrome:"rgba(255, 255, 255, 0)",buttonHighlight:"rgba(255, 255, 255, 0)",inputHighlight:"rgba(255, 255, 255, 0)",modalBackdrop:"rgba(0, 0, 0, 0.28)"}},{id:"promptx-ink-landscape",name:"Ink Mist",shortName:"Ink Mist",mode:"light",mobileEnabled:!1,description:"冷雾底色、墨青层次和卷轴感留白,像一张浮在山岚上的工作台。",swatches:["#e8ecef","#f5f8fa","#aeb8c2","#465d70"],colors:{appBg:"#e8ecef",appPanel:"#f5f8fa",appPanelMuted:"#eef2f5",appPanelStrong:"#fbfdff",appPanelHover:"#e4eaee",appPanelInset:"#d7dfe6",appOverlay:"rgba(240, 245, 248, 0.44)",borderDefault:"#b4bec8",borderMuted:"#cfd8df",borderStrong:"#8c98a4",textPrimary:"#000000",textSecondary:"#2b3944",textMuted:"#56636d",textInverse:"#f8fbfd",buttonBg:"rgba(245, 248, 250, 0.42)",buttonHover:"rgba(233, 239, 243, 0.74)",buttonBorder:"rgba(140, 152, 164, 0.56)",buttonText:"#1d2830",primaryBg:"#1f262d",primaryHover:"#2a343d",primaryBorder:"#1f262d",primaryText:"#f7fafc",inputBg:"rgba(251, 253, 255, 0.5)",inputBorder:"rgba(145, 157, 168, 0.54)",focusRing:"rgba(70, 93, 112, 0.18)",selectionBg:"#d4dde4",selectionText:"#172026",accent:"#465d70",accentSoft:"#dfe8ee",accentText:"#2c4455",warning:"#8f7356",warningSoft:"#f1e8dd",warningText:"#614830",danger:"#85545c",dangerSoft:"#efe1e4",dangerText:"#5d3239",success:"#547268",successSoft:"#e2ebe7",successText:"#334d44",info:"#465d70",infoSoft:"#dfe8ee",infoText:"#2c4455",promptBg:"#ece1d5",promptBorder:"#c5ab93",promptText:"#533e30",processBg:"#eaf0f2",processBorder:"#c1ccd3",processText:"#2f3c46",responseBg:"#dfe7ec",responseBorder:"#a4b4c0",responseText:"#2a3e4d",codeBg:"#eef3f6",codeBorder:"#ced7de",shadowPanel:"0 18px 44px rgba(23, 29, 34, 0.08)",shadowPopover:"0 26px 60px rgba(18, 24, 29, 0.16)",shellGradient:"radial-gradient(circle at 14% 10%, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.12) 18%, transparent 44%), radial-gradient(circle at 82% 8%, rgba(100, 119, 133, 0.16) 0%, transparent 30%), radial-gradient(circle at 70% 72%, rgba(154, 166, 174, 0.12) 0%, transparent 26%), linear-gradient(180deg, #eef2f5 0%, #e7ecef 44%, #dfe5e9 100%)",backdropBlur:"18px",backdropSaturate:"112%",panelHighlight:"rgba(255, 255, 255, 0.18)",panelChrome:"rgba(90, 103, 114, 0.08)",buttonHighlight:"rgba(255, 255, 255, 0.08)",inputHighlight:"rgba(255, 255, 255, 0.12)",modalBackdrop:"rgba(17, 21, 24, 0.42)"}},{id:"tokyo-night",name:"Tokyo Night",shortName:"Tokyo Night",mode:"dark",description:"更接近编辑器气质的冷调深色主题。",swatches:["#202432","#272c3f","#4d567a","#89aef7"],colors:{appBg:"#202432",appPanel:"#272c3f",appPanelMuted:"#222638",appPanelStrong:"#2e3449",appPanelHover:"#343a52",appPanelInset:"#1f2333",appOverlay:"rgba(39, 44, 63, 0.84)",borderDefault:"#4d567a",borderMuted:"#434b6b",borderStrong:"#626c97",textPrimary:"#d6dcf6",textSecondary:"#aeb7da",textMuted:"#9098bb",textInverse:"#171a23",buttonBg:"#2b3045",buttonHover:"#343955",buttonBorder:"#4d567a",buttonText:"#d8def8",primaryBg:"#89aef7",primaryHover:"#9bbcff",primaryBorder:"#89aef7",primaryText:"#171a23",inputBg:"#202433",inputBorder:"#4d567a",focusRing:"rgba(137, 174, 247, 0.24)",selectionBg:"#42578e",selectionText:"#e7edff",accent:"#89aef7",accentSoft:"#2a3956",accentText:"#e3ecff",warning:"#d9b07a",warningSoft:"#433734",warningText:"#f4dfbf",danger:"#e28a9a",dangerSoft:"#472b39",dangerText:"#ffe1e7",success:"#a9cf81",successSoft:"#2c3a31",successText:"#e5f5d0",info:"#8fcff4",infoSoft:"#284254",infoText:"#ddf3ff",promptBg:"#4b4368",promptBorder:"#9385c8",promptText:"#f2ecff",processBg:"#232739",processBorder:"#474f73",processText:"#b5bde0",responseBg:"#294155",responseBorder:"#629ec0",responseText:"#e0f1ff",codeBg:"#232739",codeBorder:"#474f73",shadowPanel:"0 20px 48px rgba(9, 12, 24, 0.34)",shadowPopover:"0 24px 62px rgba(5, 8, 18, 0.44)"}}],H=Object.fromEntries(z.map(e=>[e.id,e])),m=S(T),L=S(!1);let w=null,v=null;function De(){return typeof window>"u"||typeof window.matchMedia!="function"?!1:window.matchMedia("(max-width: 1023px)").matches}function M(){return typeof window>"u"||typeof window.matchMedia!="function"?T:window.matchMedia("(prefers-color-scheme: dark)").matches?"promptx-stone-dark":T}function k(e=""){return H[String(e||"").trim()]||H[T]}function K(e){return e?De()?e.mobileEnabled!==!1:!0:!1}function h(e=""){const t=k(e);return K(t)?t:k(T)}function x(e){if(typeof document>"u"||!e)return;const t=document.documentElement;t.dataset.theme=e.id,t.classList.toggle("dark",e.mode==="dark"),t.style.colorScheme=e.mode,Object.entries(e.colors||{}).forEach(([n,o])=>{t.style.setProperty(`--theme-${n}`,String(o))})}function Re(){var o,r;if(typeof window>"u")return h(T);const e=window.localStorage.getItem(C),t=k(e||M()),n=h(t.id);return m.value=t.id,x(n),window.localStorage.setItem(C,t.id),L.value=!0,!w&&typeof window.matchMedia=="function"&&(w=window.matchMedia("(prefers-color-scheme: dark)"),(o=w.addEventListener)==null||o.call(w,"change",()=>{if(window.localStorage.getItem(C))return;const i=k(M());m.value=i.id,x(h(i.id))})),!v&&typeof window.matchMedia=="function"&&(v=window.matchMedia("(max-width: 1023px)"),(r=v.addEventListener)==null||r.call(v,"change",()=>{x(h(m.value))})),n}function $e(){const e=f(()=>h(m.value)),t=f(()=>e.value.mode==="dark"),n=f(()=>z.filter(r=>K(r)));function o(r){const i=k(r);m.value=i.id,typeof window<"u"&&window.localStorage.setItem(C,i.id),x(h(i.id)),L.value=!0}return{currentTheme:e,isDark:t,setTheme:o,themeId:m,themeReady:L,themes:n}}const d={ENTER:"enter",SHIFT_ENTER:"shift_enter",BUTTON_ONLY:"button_only"},Ae=[{value:d.ENTER,labelKey:"settingsDialog.general.sendBehavior.options.enter.label",descriptionKey:"settingsDialog.general.sendBehavior.options.enter.description"},{value:d.SHIFT_ENTER,labelKey:"settingsDialog.general.sendBehavior.options.shiftEnter.label",descriptionKey:"settingsDialog.general.sendBehavior.options.shiftEnter.description"},{value:d.BUTTON_ONLY,labelKey:"settingsDialog.general.sendBehavior.options.buttonOnly.label",descriptionKey:"settingsDialog.general.sendBehavior.options.buttonOnly.description"}],s={SEND_BEHAVIOR:"sendBehavior",NOTIFICATION_SOUND_ENABLED:"notificationSoundEnabled"},c={CLIENT:"client",SERVER:"server"},U="promptx:workbench-preferences",_={[s.SEND_BEHAVIOR]:{key:s.SEND_BEHAVIOR,section:"general",storage:c.CLIENT,defaultValue:d.SHIFT_ENTER},[s.NOTIFICATION_SOUND_ENABLED]:{key:s.NOTIFICATION_SOUND_ENABLED,section:"general",storage:c.CLIENT,defaultValue:!1}},V={[c.CLIENT]:{loadAll(){if(typeof window>"u")return{};try{const e=JSON.parse(window.localStorage.getItem(U)||"{}");return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}},saveAll(e={}){typeof window>"u"||window.localStorage.setItem(U,JSON.stringify(e))}},[c.SERVER]:{loadAll(){return{}},saveAll(){}}},b=S(G()),$=S(!1);function G(){return{[s.SEND_BEHAVIOR]:_[s.SEND_BEHAVIOR].defaultValue,[s.NOTIFICATION_SOUND_ENABLED]:_[s.NOTIFICATION_SOUND_ENABLED].defaultValue}}function Y(e=""){const t=String(e||"").trim().toLowerCase();return t===d.ENTER?d.ENTER:t===d.BUTTON_ONLY?d.BUTTON_ONLY:d.SHIFT_ENTER}function Ee(e=!1){if(typeof e=="string"){const t=String(e).trim().toLowerCase();if(["1","true","on","yes"].includes(t))return!0;if(["0","false","off","no",""].includes(t))return!1}return!!e}function J(e={}){return{[s.SEND_BEHAVIOR]:Y(e==null?void 0:e[s.SEND_BEHAVIOR]),[s.NOTIFICATION_SOUND_ENABLED]:Ee(e==null?void 0:e[s.NOTIFICATION_SOUND_ENABLED])}}function W(e=c.CLIENT){var t,n;return((n=(t=V[e])==null?void 0:t.loadAll)==null?void 0:n.call(t))||{}}function Z(e=c.CLIENT,t={}){var n,o;(o=(n=V[e])==null?void 0:n.saveAll)==null||o.call(n,t)}function Q(){const e=G(),t=W(c.CLIENT),n=W(c.SERVER),o=J({...e,...t,...n});return b.value=o,Z(c.CLIENT,o),$.value=!0,o}function ee(e=""){return _[String(e||"").trim()]||null}function F(e=""){const t=ee(e);if(t)return b.value[t.key]}function Be(e="",t){const n=ee(e);if(!n)return b.value;const o=J({...b.value,[n.key]:t});b.value=o;const r=n.storage||c.CLIENT;return r===c.CLIENT&&Z(r,o),$.value=!0,o}function Oe(e,t={}){const n=String((e==null?void 0:e.key)||""),o=Y(t==null?void 0:t.sendBehavior);return n!=="Enter"||t!=null&&t.isComposing||!(t!=null&&t.isEditing)||e!=null&&e.metaKey||e!=null&&e.ctrlKey||e!=null&&e.altKey||o===d.BUTTON_ONLY?!1:o===d.ENTER?!(e!=null&&e.shiftKey):!!(e!=null&&e.shiftKey)}function je(){const e=f(()=>b.value),t=f(()=>F(s.SEND_BEHAVIOR)),n=f(()=>F(s.NOTIFICATION_SOUND_ENABLED));return{preferences:e,sendBehavior:t,notificationSoundEnabled:n,workbenchPreferencesReady:$,initializeWorkbenchPreferences:Q,getPreference:F,setPreference:Be}}Re();Ce();Q();de(be).use(we).mount("#app");export{s as W,Se as _,fe as a,$e as b,je as c,Ae as d,Le as e,Ie as f,X as g,Oe as s,I as t,_e as u};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/WorkbenchView-noayQwj4.js","assets/vendor-misc-u-M8sNMf.js","assets/vendor-misc-ClI1dyrl.css","assets/vendor-ui-BglsaDbv.js","assets/vendor-markdown-9aQhqbjm.js","assets/vendor-tiptap-rwYdQb1L.js","assets/WorkbenchView-D1oxqNr4.css"])))=>i.map(i=>d[i]);
2
+ import{aC as re,aD as ie,aE as ae,aF as A,aG as se,b as S,c as f,aH as de}from"./vendor-misc-u-M8sNMf.js";import{c as ce,a as le}from"./vendor-router-Dn8q3tJM.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))o(r);new MutationObserver(r=>{for(const i of r)if(i.type==="childList")for(const a of i.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&o(a)}).observe(document,{childList:!0,subtree:!0});function n(r){const i={};return r.integrity&&(i.integrity=r.integrity),r.referrerPolicy&&(i.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?i.credentials="include":r.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(r){if(r.ep)return;r.ep=!0;const i=n(r);fetch(r.href,i)}})();const fe=(e,t)=>{const n=e.__vccOpts||e;for(const[o,r]of t)n[o]=r;return n},ue={},pe={class:"app-shell"},ge={class:"app-main flex min-h-0 flex-1 overflow-hidden px-3 py-3 sm:px-4 sm:py-4 lg:px-4 lg:py-4"},he={class:"app-stage h-full min-h-0 w-full overflow-hidden"};function me(e,t){const n=re("RouterView");return ie(),ae("div",pe,[A("main",ge,[A("div",he,[se(n)])])])}const be=fe(ue,[["render",me]]),ye="modulepreload",Te=function(e){return"/"+e},O={},Se=function(t,n,o){let r=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const a=document.querySelector("meta[property=csp-nonce]"),l=(a==null?void 0:a.nonce)||(a==null?void 0:a.getAttribute("nonce"));r=Promise.allSettled(n.map(u=>{if(u=Te(u),u in O)return;O[u]=!0;const P=u.endsWith(".css"),te=P?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${u}"]${te}`))return;const p=document.createElement("link");if(p.rel=P?"stylesheet":ye,P||(p.as="script"),p.crossOrigin="",p.href=u,l&&p.setAttribute("nonce",l),document.head.appendChild(p),P)return new Promise((ne,oe)=>{p.addEventListener("load",ne),p.addEventListener("error",()=>oe(new Error(`Unable to preload CSS for ${u}`)))})}))}function i(a){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=a,window.dispatchEvent(l),!l.defaultPrevented)throw a}return r.then(a=>{for(const l of a||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})},we=ce({history:le(),routes:[{path:"/",name:"workbench",component:()=>Se(()=>import("./WorkbenchView-noayQwj4.js").then(e=>e.B),__vite__mapDeps([0,1,2,3,4,5,6]))}]}),N="promptx:locale",y="zh-CN",D=[{value:"zh-CN",label:"简体中文",englishLabel:"Chinese (Simplified)"},{value:"en-US",label:"English",englishLabel:"English"}],B={"zh-CN":{common:{settings:"设置",save:"保存",saving:"保存中...",saved:"已保存",loading:"读取中...",unavailable:"不可用",cancel:"取消",confirm:"确认",processing:"处理中...",close:"关闭",enabled:"启用",select:"请选择",notAvailable:"暂无",noOptions:"暂无可选项",expand:"展开",collapse:"收起"},locale:{title:"语言",description:"切换 PromptX 界面语言,当前先支持中文和英文。",field:"界面语言",immediateHint:"切换后立即生效,并保存在当前浏览器里。",zhHans:"简体中文",enUs:"English"},workbench:{title:"PromptX 工作台",newMessageTitle:"PromptX 你有新消息...",tasks:"任务",settings:"设置",createTask:"新建任务",creatingTask:"创建中...",loadingTasks:"正在加载任务...",loadingTaskContent:"正在加载任务内容...",untitledTask:"未命名任务",running:"运行中",noMessagesYet:"还没有发送记录",dragToReorder:"拖动排序",filesCount:({count:e})=>`${e} 文件`,editTask:"编辑任务",deleteTask:"删除任务",deletingTask:"删除中...",activity:"执行",input:"输入",selectTask:"请选择一个任务",promptCopied:"已复制提示词",projectCreated:"已新建项目",codeContextTitle:"代码上下文",codeContextFile:({path:e})=>`文件:${e}`,codeContextRange:({range:e})=>`位置:${e}`,codeContextSource:({source:e})=>`来源:${e}`,codeContextSourceDiff:"代码变更",codeContextSourceFile:"源码查看",confirmClearTitle:"确认清空当前任务?",confirmClearDescription:"将清空右侧编辑区内容,但会保留当前任务本身。",confirmClearAction:"确认清空",continueEditing:"继续编辑",confirmDeleteTitle:"确认删除当前任务?",confirmDeleteDescription:({title:e})=>`将删除「${e}」,删除后无法恢复。`,confirmDeleteAction:"确认删除",keepForNow:"先保留",confirmDeleteTodoTitle:"确认删除这条代办?",confirmDeleteTodoDescription:"删除后这条代办将无法恢复。",replaceEditorTitle:"替换编辑区内容?",replaceEditorDescription:"编辑区已有内容。继续使用这条代办会清空当前内容,并替换成代办里的内容。",confirmReplaceAction:"确认替换",dontReplaceYet:"先不替换"},editor:{chooseFiles:"选文件",clear:"清空",todo:"代办",todoWithCount:({count:e})=>`代办 (${e})`,send:"发送",sending:"发送中",running:"执行中",selectAgent:"选择 Agent"},todoDialog:{title:"管理代办",intro:"把临时想法先挂在当前任务下,需要时再取回编辑区继续整理。",summary:({count:e})=>`当前任务共 ${e} 条代办`,summaryHint:"使用后会回填到编辑区并从列表移除",itemTitle:"代办",blockCount:({count:e})=>`共 ${e} 个块`,textCount:({count:e})=>`文本 ${e}`,importedCount:({count:e})=>`导入 ${e}`,imageCount:({count:e})=>`图片 ${e}`,use:"使用",delete:"删除",empty:"还没有代办,先把编辑区里的临时想法收进来吧。",imagePreview:({count:e})=>`包含 ${e} 张图片`,noPreview:"暂时没有可预览的文本内容",justAdded:"刚刚添加"},theme:{title:"主题",sectionDescription:"管理界面主题与语言偏好。",heading:"界面主题",currentTheme:({name:e})=>`当前:${e}`,helper:"像编辑器一样切换整套配色,而不只是深浅模式。",groupLight:"浅色主题",groupDark:"深色主题",description:{"promptx-stone-light":"温和石色,适合长时间白天工作。","promptx-glass-light":"雾面玻璃质感,保留石色与绿调。","promptx-aqua-classic":"复古 macOS Aqua / Snow Leopard 拟物工具台。","promptx-stone-dark":"延续当前工作台气质的深色主题。","github-light":"清爽、克制,适合评审和协作场景。","github-dark":"熟悉的深色代码托管风格。","solarized-light":"低对比暖色纸感,适合长文阅读。","solarized-dark":"经典 Solarized 深色版本,柔和不刺眼。","ink-mist":"偏冷的墨雾风格,适合长时间专注。","promptx-ink-landscape":"冷雾底色、墨青层次和卷轴感留白,像一张浮在山岚上的工作台。","tokyo-night":"更接近编辑器气质的冷调深色主题。"}},settingsDialog:{general:{sectionLabel:"通用",sectionDescription:"基础工作台偏好",title:"通用偏好",intro:"这里放工作台层面的基础交互偏好。后续新增的通用设置可以按配置项来源分别接入,不影响界面使用方式。",remoteCommandSecurityTitle:"远程命令安全",remoteCommandSecurityDescription:"配置远程页面是否允许执行 !git status、!pnpm test 这类高权限命令。",remoteCommandSecurityModeField:"安全模式",remoteCommandSecurityModeDisabled:"不允许",remoteCommandSecurityModeDisabledDescription:"除本机 loopback 访问外,所有远程入口都不允许执行命令模式。",remoteCommandSecurityModeRelay:"Relay",remoteCommandSecurityModeRelayDescription:"只允许通过 PromptX Relay 代理进来的远程请求执行命令模式。",remoteCommandSecurityModeTrustedProxy:"Trusted Proxy",remoteCommandSecurityModeTrustedProxyDescription:"只允许你信任的反向代理入口执行命令模式,并校验代理注入的 token。",trustedProxyTokenField:"Trusted Proxy Token",trustedProxyTokenPlaceholder:"首次启用时请输入 Trusted Proxy Token",trustedProxyTokenReplacePlaceholder:"如需更换请输入新的 Trusted Proxy Token",trustedProxyTokenConfiguredHint:"当前已配置 token。出于安全原因,这里不会回显明文。",trustedProxyTokenHint:"Nginx 需要同时注入 X-PromptX-Trusted-Proxy: 1 和 X-PromptX-Proxy-Token。",trustedProxyTokenReplaceHint:"留空表示保留当前 token,输入新值则覆盖原 token。",remoteCommandSecurityWarning:"这是高权限能力。只有在你信任当前远程入口时才建议开启。",remoteCommandSecuritySave:"保存远程命令设置",remoteCommandSecuritySaved:"已保存",sendBehavior:{title:"发送消息方式",description:"设置编辑区里使用回车发送还是只允许点击按钮发送。",hint:"发送按钮始终可用;这里仅控制编辑器里的键盘发送方式。",options:{enter:{label:"回车发送",description:"单击 Enter 发送,Shift + Enter 换行。"},shiftEnter:{label:"Shift + 回车发送",description:"单击 Enter 换行,Shift + Enter 发送。"},buttonOnly:{label:"仅按钮发送",description:"回车只用于编辑内容,必须点击发送按钮才会发送。"}}},notificationSound:{title:"通知音",description:"控制任务产生未读新进展时是否播放提示音。",switchLabel:"启用通知音",switchHint:"默认关闭。开启后,非当前聚焦任务出现新的未读结果时会播放提示音。"}},relay:{sectionLabel:"远程",sectionDescription:"Relay 与手机访问",title:"远程访问 Relay",enableTitle:"启用远程访问",enableDescription:"关闭后,本机会主动断开当前 Relay 连接。",relayUrl:"Relay 地址",deviceId:"设备 ID",deviceToken:"设备 Token",deviceTokenPlaceholder:"请输入云端 Relay 的设备 token",pausedReconnect:({reason:e})=>`当前已暂停自动重连:${e}`,managedByEnv:"当前 Relay 配置由环境变量接管,设置页仅展示实际值,修改环境变量后需重启服务。",lastError:({value:e})=>`最近错误:${e}`,lastClosed:({reason:e,code:t})=>`最近断开:${e}${t?`(code ${t})`:""}`,lastConnected:({value:e})=>`最近连接:${e}`,recentEvent:({value:e})=>`最近事件:${e}`,copied:"Relay 诊断信息已复制,可直接发给我排查。",defaultHint:"建议公网 Relay 使用 HTTPS,并确保云端与本机使用同一个设备 Token;多租户时每个人填写自己的子域名地址。",reconnectNow:"立即重连",reconnecting:"重连中...",copyDiagnostics:"复制 Relay 诊断信息",diagnosticsCopied:"已复制诊断信息",saveConfig:"保存远程访问配置",relayConfigLoadFailed:"远程访问配置读取失败。",relayConfigSavedEnabled:"远程访问配置已保存,PromptX 正在尝试连接 Relay。",relayConfigSavedDisabled:"远程访问已关闭。",relayConfigSaveFailed:"远程访问配置保存失败。",relayReconnectTriggered:"已触发重连,PromptX 正在重新建立 Relay 连接。",relayReconnectFailed:"触发 Relay 重连失败。",relayFieldsRequired:"请先填写完整的 Relay 地址、设备 ID 和设备 Token,再启用远程访问。",relayEnabledSaved:"远程访问已启用,PromptX 正在尝试连接 Relay。",relayToggleFailed:"远程访问开关保存失败。",relayDiagnosticsCopyFailed:"Relay 诊断信息复制失败。",reason:{invalid_tenant:"当前 Relay 域名未匹配到租户",invalid_token:"设备令牌不匹配",invalid_device:"设备 ID 不匹配",missing_hello:"缺少设备认证报文",missing_auth:"设备认证超时",replaced_by_new_connection:"已被新的设备连接替换",config_updated:"配置已更新,正在重连",heartbeat_timeout:"心跳超时,连接已失效"},event:{reconnect_paused:"已暂停自动重连",local_request_failed:"本地请求转发失败",dispatch_failed:"请求派发失败",connect_failed:"连接失败",reconnect_scheduled:"已计划重连",reconnect_requested:"已请求重连",system_resume_detected:"检测到系统恢复",heartbeat_stale:"检测到心跳过期",connect_start:"开始连接",ws_open:"WebSocket 已建立",auth_ok:"设备认证成功",stale_close_ignored:"已忽略旧连接关闭事件",close:"连接已关闭",error:"连接异常",disabled:"当前未启用",stopped:"已停止",config_updated:"配置已更新",unknown:"未知事件"},error:{connect_failed:"Relay 连接失败。",disconnected:({reason:e})=>`Relay 已断开:${e}`,rejected:({reason:e})=>`Relay 连接被拒绝:${e}`,closedWithCode:({code:e})=>`Relay 连接已关闭(code=${e})`},status:{reconnecting:"重连中...",saving:"保存中...",loading:"读取中...",paused:"已暂停重连",connected:"已连接",waitingReconnect:"等待重连",disconnected:"未连接",disabled:"未启用"}},system:{sectionLabel:"系统",sectionDescription:"Runner 与性能配置",title:"系统配置",intro:"这里同时放 runner 并发上限和运行诊断。后续排查卡顿、排队、stop 回收问题时,优先看下面这组实时统计。",maxConcurrentRuns:"真实 agent 最大并发数",maxConcurrentRunsHint:"超过这个数量的新 run 会进入 queued,等待 runner 空闲后再启动。",managedByEnv:"当前并发上限由环境变量 `PROMPTX_RUNNER_MAX_CONCURRENT_RUNS` 接管,设置页只展示实际值。",diagnosticsHint:"诊断口径已经和真实并发控制对齐:`active` 不再把 queued 误算进去。",saveConfig:"保存系统配置",runtimeDiagnostics:"运行诊断",runtimeDiagnosticsHint:"自动每 5 秒刷新一次,可直接观察 runner、恢复器和清理任务的运行情况。",refreshDiagnostics:"刷新诊断",refreshingDiagnostics:"刷新中...",copyDiagnostics:"复制诊断信息",diagnosticsCopied:"已复制诊断信息",diagnosticsCopiedHint:"系统诊断信息已复制,可直接发给我排查。",active:"真实占用并发槽位",tracked:"runner 内存中的全部上下文",queued:"等待启动的 run",maxConcurrent:"当前生效并发上限",completed:"已完成 run",stopped:"已停止 run",error:"异常结束 run",stopTimeout:"停止超时 run",eventWriteFailures:"事件批量回写失败次数",recoveredRuns:"服务端回收的失联 run",lastMaintenanceAt:"最近一次维护清理完成时间",baseStatus:"基础状态",available:"可用",unknown:"未知",stopReasonTitle:"Stop 原因分类",stopTimeoutPhaseTitle:"Stop Timeout 阶段",runnerUnavailable:"runner 暂不可用",runnerUnavailableDescription:"当前还没有拿到 runner diagnostics。",systemConfigLoadFailed:"系统配置读取失败。",systemConfigSaved:"系统配置已保存,runner 并发上限已更新。",systemConfigSaveFailed:"系统配置保存失败。",systemDiagnosticsLoadFailed:"系统诊断信息读取失败。",systemDiagnosticsCopyFailed:"系统诊断信息复制失败。",stopReasons:{queued_cancelled:"排队前取消",user_requested:"用户主动停止",user_requested_after_error:"停止后报错",stop_timeout:"停止超时"},stopTimeoutPhases:{runner_timeout_without_stop_request:"未记录 stop 请求",runner_timeout_before_cancel:"cancel 前超时",cli_not_exiting:"CLI 不退出",os_kill_slow:"OS kill 慢",runner_finalize_after_exit:"退出后收尾慢"}},shortcuts:{sectionLabel:"快捷键",sectionDescription:"全局操作快捷方式",title:"快捷键",intro:"下面这些是工作台里的全局快捷键,在工作台任意区域都可直接触发。",openSettingsTitle:"打开设置",openSettingsDescription:"快速打开全局设置面板。",openProjectManagerTitle:"打开项目管理",openProjectManagerDescription:"快速打开当前任务绑定的项目管理弹层。",openSourceBrowserTitle:"打开源码查看",openSourceBrowserDescription:"直接进入当前项目的只读源码查看弹层。",openDiffReviewTitle:"打开代码变更",openDiffReviewDescription:"快速打开当前任务所在项目的代码变更弹层。",closeTopDialogTitle:"关闭当前最上层弹层",closeTopDialogDescription:"优先关闭最上层的确认框、源码查看、项目管理或设置。",note:"当前快捷键优先面向桌面端;移动端仍以点击操作为主。"},about:{sectionLabel:"关于",sectionDescription:"版本与说明",title:"关于",intro:"这里先放版本信息,后面像更新日志、环境说明也可以继续往这里放。",versionTitle:"版本信息",versionDescription:"当前已安装的 PromptX 版本。",versionPending:"当前服务暂未返回版本号,请确认已重启到最新版本。",versionLoadFailed:"版本信息读取失败。"}},taskDialog:{title:"编辑任务",currentTask:({title:e})=>`当前任务:${e}`,loading:"正在读取任务配置...",sections:{basic:{label:"基础",description:"标题与任务信息",title:"基础信息",intro:"这里维护任务标题,留空时继续使用自动标题。",taskTitle:"任务标题",taskTitlePlaceholder:"留空则继续使用自动标题"},automation:{label:"定时",description:"自动运行设置",title:"定时运行",intro:"用可视化方式设置自动运行时间,不需要手填 Cron。",mode:"运行周期",time:"运行时间",weekday:"每周日期",timezone:"时区",concurrencyPolicy:"并发策略",lastTriggered:({value:e})=>`最近触发:${e}`,nextTriggered:({value:e})=>`下次触发:${e}`,modeDaily:"每天",modeWeekdays:"工作日",modeWeekly:"每周",weekday1:"周一",weekday2:"周二",weekday3:"周三",weekday4:"周四",weekday5:"周五",weekday6:"周六",weekday0:"周日",timezoneLocal:"跟随本机时区",concurrencySkip:"已有运行时跳过本次"},notification:{label:"通知",description:"运行结束通知",title:"运行通知",intro:"run 结束后按规则把结果推送到群机器人。",channelType:"渠道类型",triggerOn:"触发时机",webhookUrl:"Webhook 地址",webhookUrlPlaceholder:"请输入群机器人 Webhook 地址",secret:"签名密钥(可选)",secretPlaceholder:"开启签名时再填写",locale:"通知语言",localeZhCn:"简体中文",localeEnUs:"English",messageMode:"消息模式",status:({value:e})=>`通知状态:${e}`,lastSent:({value:e})=>`最近发送:${e}`,lastError:({value:e})=>`最近错误:${e}`,channelDingtalk:"钉钉 Webhook",channelFeishu:"飞书 Webhook",channelWebhook:"通用 Webhook",triggerCompleted:"本次运行结束后",triggerSuccess:"本次运行成功后",triggerError:"本次运行失败后",messageSummary:"摘要消息",statusDisabled:"未启用",statusSuccess:"最近发送成功",statusError:"最近发送失败",statusPending:"等待首次发送"}},enabled:"启用",footerHint:"定时运行会按 Cron 创建新的 run;运行通知会在本次 run 结束后按规则发送到群机器人。",saveTaskConfig:"保存任务配置",loadFailed:"任务配置读取失败。",saveFailed:"任务配置保存失败。"},taskActions:{taskSaved:"任务已保存",taskCreated:"已创建新任务",taskCleared:"已清空当前任务内容,稍后会自动保存",todoAdded:"已加入代办",fileProcessing:"文件仍在处理中,请稍后再操作任务。",fileProcessingBeforeSend:"文件仍在处理中,请稍后再发送给当前执行引擎。",sessionLocked:"该任务已有项目历史,不能再切换项目;如需使用新项目,请新建任务。",noTextImported:"没有读取到可插入的文本内容",textImportFailed:"文件读取失败,请确认使用 UTF-8 编码的纯文本文件。",noPdfContent:"没有从 PDF 中解析出可插入内容",pdfImportFailed:"PDF 解析失败,请确认文件不是扫描件,并且内容为单栏图文。",imageInserted:({count:e,appended:t})=>t?`已把 ${e} 张图片插入到当前导入块后方,稍后会自动保存`:`已插入 ${e} 张图片,稍后会自动保存`,importedBlocksInserted:({count:e,appended:t})=>t?`已把 ${e} 个文件块插入到当前导入块后方,稍后会自动保存`:`已插入 ${e} 个文件块,稍后会自动保存`,pdfBlocksInserted:({blockCount:e,pageCount:t})=>`已插入 ${e} 个图文块${t?`,共 ${t} 页`:""},稍后会自动保存`,insertedToEditor:"已插入到右侧编辑区"},projectManager:{managingTitle:"PromptX 项目管理",createTitle:"新建项目",editTitle:"编辑项目",newProject:"新建项目",projectList:"项目列表",noProjects:"还没有项目,先新建一个固定工作目录。",create:"新建",current:"当前",regular:"普通",untitledProject:"未命名项目",enginePrefix:"引擎:{value}",updatedAtPrefix:"最近更新:{value}",runtimeStatus:"运行状态",currentProject:"当前项目",engine:"执行引擎",workingDirectory:"工作目录",notSet:"未设置",updatedAt:"最近更新",note:"说明",noteDescription:"项目绑定目录与执行引擎,目录不变时会继续复用同一条引擎会话。",projectTitleOptional:"项目标题(可选)",workingDirectoryField:"工作目录",choose:"选择",chooseDirectory:"选择目录",engineField:"执行引擎",selectEngine:"请选择执行引擎",collaborationAgents:"协作 Agents",collaborationAgentsHint:"默认 Agent 继续使用上面的会话 ID;额外勾选的 Agent 会共享同一目录,并在首次发送时自动建立各自线程。",agentEnabled:"已加入当前项目",agentDisabled:"点击加入当前项目",agentCount:({count:e})=>`${e} 个 Agent`,noEngines:"暂无可用执行引擎",comingSoon:"即将支持",confirmDeleteTitle:"确认删除 PromptX 项目?",confirmDeleteDescription:({title:e})=>`将删除「${e}」这条本地记录,不会删除工作目录,也不会删除对应执行引擎的历史数据。`,confirmDelete:"确认删除",newSession:"新会话",resettingSession:"重置中...",confirmResetTitle:"确认新建项目会话?",confirmResetDescription:({title:e})=>`这会清空「${e}」当前绑定的会话,以及该项目下所有任务的执行历史;不会删除项目、工作目录和右侧编辑内容。下次运行将从新会话开始。`,confirmReset:"确认新会话",sessionReset:"已重置当前项目会话,下次运行将从新会话开始。",keep:"先保留",basicInfo:"基本信息",status:"状态",close:"关闭",backToList:"返回列表",deleteProject:"删除项目",deletingProject:"删除中...",createProject:"创建项目",creatingProject:"创建中...",saveChanges:"保存修改",savingChanges:"保存中...",directoryRequired:"请先填写工作目录。",projectMissing:"当前项目不存在,请重新选择。",duplicateDirectory:({labels:e,count:t})=>`该目录已被${e}${t>3?"等项目":"项目"}使用,建议优先复用,避免把同一目录拆成多个项目。`,cwdReadonly:"当前项目已绑定执行引擎会话,工作目录不能再修改;如需使用新目录,请新建项目。",engineReadonly:"当前项目已绑定执行引擎会话,执行引擎不能再修改;如需更换,请新建项目。",sessionId:"会话 ID",sessionIdHint:"留空则首次运行时自动创建;填写已有 ID 则继续复用该会话。",sessionIdReadonly:"当前项目已实际运行,会话 ID 不能再修改;如需切换,请新建项目。",sessionCandidates:"已有本机会话",sessionCandidatesLoading:"加载...",noSessionCandidates:"没有匹配的本机会话,仍可手动填写。",sessionCandidatesNeedDirectory:"请先选择工作目录,再选择已有会话;也可以直接手动填写。",copySessionId:"复制",sessionIdCopied:"已复制",copySessionIdFailed:"会话 ID 复制失败。",viewSource:"查看源码",running:"运行中",idle:"空闲",threadBound:"已绑定线程",notStarted:"未启动",unknown:"未知",syncingProjects:"加载...",syncingLatestProjects:"加载...",projectCount:({count:e})=>`共 ${e} 个项目`,selectProject:"请选择项目",noProjectsInSelect:"还没有项目,请先到管理弹窗里新建。"},sourceBrowser:{title:"查看源码",readOnlyHint:({title:e})=>`当前为「${e}」的只读源码浏览`,noWorkspace:"当前项目还没有绑定工作目录。",noProject:"请先选择项目。",searchLabel:"搜索文件",searchPlaceholder:"搜索文件名或路径片段",contentSearchPlaceholder:"按文件内容搜索",searchModePath:"路径",searchModeContent:"内容",searchAction:"搜索",searchMinKeywordHint:({count:e})=>`至少输入 ${e} 个字符后再开始搜索。`,searchEmpty:"没有找到匹配文件。",contentSearchPrompt:"正在等待搜索结果...",contentSearchEmpty:"没有找到匹配内容。",contentSearching:"正在搜索文件内容...",contentSearchFailed:"文件内容搜索失败。",contentSearchResultMeta:({path:e,line:t})=>`${e} · 第 ${t} 行`,contentSearchTruncated:"结果较多,当前只展示前一部分命中。",treeEmpty:"当前目录下没有可显示的文件。",loadingFiles:"正在加载文件列表...",recent:"最近",results:"结果",previewLoading:"正在加载文件内容...",previewFailed:"文件内容读取失败。",selectFile:"请先从左侧选择一个文件。",selectFileHint:"当前选中的是目录,请继续选择文件。",truncated:"已截断",binaryUnsupported:"当前文件为二进制内容,暂不支持在线预览。",binaryTooLarge:"当前文件较大,暂不支持在线预览。",selectCodeLineHint:"直接拖选代码,选区旁会显示插入按钮。",selectedLines:({count:e})=>`已选 ${e} 行`,insertSelection:"插入到编辑区"},directoryPicker:{title:"选择工作目录",intro:"默认只在当前用户目录下浏览和搜索;特殊路径继续用手动输入。",currentSelection:"当前选中",selectionPlaceholder:"请在目录树或搜索结果里选择目录",searchLabel:"搜索目录",searchPlaceholder:"输入目录名或路径片段,例如 promptx / code",searchMinKeywordHint:({count:e})=>`至少输入 ${e} 个字符后再开始搜索。`,searching:"搜索中...",treeLoading:"目录树加载中...",noSearchResults:"没搜到匹配目录,试试更短的关键词,或者直接用目录树浏览。",emptyTree:"当前没有可显示的目录。",truncatedHint:"搜索结果已截断,只展示最相关的一部分目录。",cancel:"取消",useCurrentDirectory:"使用当前目录",unnamedDirectory:"未命名目录",loadFailed:"目录加载失败。",treeLoadFailed:"目录树加载失败。",searchFailed:"搜索失败。"},pathPicker:{selectProjectFirst:"请先选择项目。",noResults:"无结果",emptyDirectory:"空目录",loading:"加载中...",recent:"最近",results:"结果"},diffReview:{dialogTitle:"代码变更",dialogTitleWithTask:({title:e})=>`代码变更 · ${e}`,scopeCurrentShort:"当前",scopeCurrent:"当前变更",scopeTaskShort:"累计",scopeTask:"任务累计",scopeRun:"本轮",refresh:"刷新",refreshing:"刷新中...",computing:"统计中...",selectRun:"请选择历史执行",noRuns:"暂无可查看的历史执行",runCount:({count:e})=>`共 ${e} 条可审查执行`,loading:"正在读取代码变更...",unavailableTitle:"暂时无法查看代码变更",unavailableReason:"当前没有可展示的代码变更。",unknownBranch:"未识别分支",fileCount:({count:e})=>`${e} 个文件`,waitingStats:"等待统计",filesTab:"文件",diffTab:"Diff",searchFilePath:"搜索文件路径",statsPending:"已先展示文件列表,整体增删行数正在后台统计...",noChanges:"当前范围内还没有检测到代码变更。",noMatches:"当前筛选或搜索条件下没有匹配文件。",statsOnDemand:"行数按需统计",changeIndex:({current:e,total:t})=>`改动 ${e}/${t}`,loadingFileDiff:"正在加载该文件的 diff...",noFileDiffContent:"当前文件没有可展示的 diff 内容。",selectFile:"请选择一个文件查看 diff。",binaryPreviewUnavailable:"二进制文件暂不支持在线 diff 预览。",binaryPreviewTitle:"二进制预览",binaryTag:"二进制",binaryMetaTitle:"文件元信息",binaryBefore:"变更前",binaryAfter:"变更后",binarySideMissing:"该侧文件不存在。",downloadBinarySide:"下载文件",binaryPreviewTooLarge:"文件较大,暂不支持在线预览。",binarySnapshotUnavailable:"历史快照中没有保存该二进制文件内容。",openImagePreview:"查看大图",fileTooLarge:"文件内容较大,暂不展示具体 diff。",diffTooLong:"diff 内容较长,暂不在页面内完整展示。",diffPreviewOnly:"diff 内容较长,当前仅展示摘要预览。",fileDiffTimedOut:"该文件 diff 计算较慢,暂不在线展示详细内容,请优先在本地查看。",notGitRepo:"当前工作目录不是 Git 仓库,暂不支持代码变更审查。",taskNotFound:"任务不存在。",runRequired:"请选择一轮执行后再查看本轮代码变更。",runNotFound:"没有找到对应的执行记录。",runBaselineMissing:"这轮执行还没有建立代码变更基线,暂时无法查看本轮 diff。",taskBaselineMissing:"当前任务还没有建立代码变更基线,请先让 Codex 执行一轮。",runSnapshotMissing:"这轮执行缺少结束快照,暂时无法准确还原本轮代码变更。",fileNotInDiff:"当前文件不在本次 diff 范围内。",originalRepoInvalid:"原工作目录已不是有效的 Git 仓库,暂时无法读取代码变更。",baselineCommitMissing:"基线对应的 commit 已不存在,仓库可能被 reset、rebase 或切换到无关历史,暂时无法准确读取该范围的代码变更。",warningBranchChanged:({from:e,to:t})=>`当前分支已从 ${e} 切换到 ${t}`,warningHeadDetachedFromBaseline:"当前 HEAD 已不在基线 commit 的后续历史中,仓库可能经历了 reset、rebase 或切分支",baselineTime:({value:e})=>`基线时间:${e}`,baselineBranch:({value:e})=>`基线分支:${e}`,baselineCommit:({value:e})=>`基线 commit:${e}`,currentHead:({value:e})=>`当前 HEAD:${e}`,completed:"已完成",failed:"失败",interrupted:"已中断",stopped:"已停止",added:"新增",deleted:"删除",modified:"修改",all:"全部",noReviewRuns:"当前还没有可用于审查的历史执行记录。",selectCodeLineHint:"直接拖选代码,选区旁会显示插入按钮。",selectedLines:({count:e})=>`已选 ${e} 行`,insertSelection:"插入到编辑区"},sessionPanel:{diff:"代码变更",manageProjects:"管理项目",agentFilter:"Agent 过滤",allAgents:"全部",emptyAgentFilter:"当前 Agent 暂无消息。",showProcessToggle:"显示执行过程",hideProcessToggle:"隐藏执行过程",empty:"这里会显示项目执行过程和模型回复。",promptTitleWithAgent:({agent:e})=>`PromptX → ${e}:`,expand:"展开",collapse:"收起",promptImageAlt:"本轮提示词图片",processTitle:"执行:",loading:"加载中...",loadingEvents:"正在加载执行过程...",hiddenEventsLoaded:({count:e})=>`已折叠 ${e} 条过程日志`,hiddenEventsLoadLater:({count:e})=>`共 ${e} 条过程日志,展开后加载`,waitingEvents:({agent:e})=>`正在等待 ${e} 返回事件...`,noEvents:"本轮没有记录执行过程。",view:"查看",insert:"插入",copyCode:"复制",copyCodeAria:"复制代码",codeCopied:"已复制代码",defaultAgent:"默认",agentNotEnabled:"当前项目没有启用这个 Agent,请先到项目管理里勾选。",shellUnsupportedBlocks:"命令模式暂不支持图片或导入文件,请只保留纯文本命令。",shellEmptyCommand:"请输入要执行的命令,例如 !git status",errorSuffix:({agent:e})=>`${e}:`,responseSuffix:({agent:e})=>`${e}:`,jumpToLatest:"有新消息,跳到底部",stop:"停止",stopping:"正在停止..."},runner:{status:{queued:"当前仍在排队,等待 runner 空闲后开始执行。",stopping:"正在停止执行,等待引擎退出...",thinking:({agentLabel:e})=>`${e} 正在思考中...`}},processDetail:{changeCreate:"新增",changeDelete:"删除",changeUpdate:"更新",changeGeneric:"变更",subAgentPending:"等待启动",subAgentRunning:"运行中",subAgentCompleted:"已完成",subAgentFailed:"失败",subAgentUnknown:"未知状态",directorySummary:({count:e})=>`${e} 项`,directoryHidden:({count:e})=>`,还有 ${e} 项未展示`,hiddenItems:({count:e})=>`还有 ${e} 项未展示`,hiddenLines:({count:e})=>`还有 ${e} 行未展示`,searchMatchCount:({count:e})=>`${e} 处命中`,searchHiddenMatches:({count:e})=>`该文件还有 ${e} 处命中未展示`,searchFileSummary:({fileCount:e,matchCount:t})=>`${e} 个文件,${t} 处命中`,searchHiddenFiles:({count:e})=>`,还有 ${e} 个文件未展示`},blockEditor:{stats:({lines:e,chars:t})=>`${e} 行 · ${t} 字符`,title:"输入文本、图片或文件",uploading:"正在处理文件",placeholderFirst:"从这里开始写需求...",placeholderNext:"继续输入...",delete:"删除",image:"图片",file:"文件",unnamedFile:"未命名文件",unnamedImage:"未命名图片",unnamedPdf:"未命名 PDF",fileSummary:({name:e,stats:t})=>`${e}(${t})`,expand:"展开",collapse:"折叠",convertToText:"转文本",emptyContent:"空内容",emptyImportPlaceholder:"导入内容为空",insertedImageAlt:"已插入图片",unsupportedFiles:({names:e,extra:t})=>`这些文件暂不支持:${e}${t?` 等 ${t} 个文件`:""}`,oversizedFiles:({names:e,extra:t,limit:n})=>`这些文件超过大小限制:${e}${t?` 等 ${t} 个文件`:""},请控制在 ${n} 以内`},imagePreview:{zoomOut:"缩小",zoomIn:"放大",previous:"上一张",next:"下一张",close:"关闭",alt:"图片预览"},misc:{promptxVersionDescription:"当前已安装的 PromptX 版本。"},errors:{requestFailed:"请求失败。",taskCreateFailed:"任务创建失败。",taskNotFound:"任务不存在。",taskExpired:"任务已过期。",taskUpdateFailed:"任务更新失败。",taskDeleteWhileRunning:"当前任务正在执行中,请先停止后再删除。",taskClearRunsWhileRunning:"当前任务正在执行中,请先停止后再清空记录。",taskSessionLocked:"该任务已有项目历史,不能再切换项目;如需使用新项目,请新建任务。",sessionRequired:"请先选择一个 PromptX 项目。",sessionNotFound:"没有找到对应的 PromptX 项目。",currentProjectRunning:"当前项目正在运行中,请等待完成后再发送。",currentProjectDeleteWhileRunning:"当前项目正在执行中,请先停止后再删除。",runNotFound:"没有找到对应的执行记录。",invalidDiffScope:"无效的 diff 范围。",gitDiffFailed:"git diff 计算失败。",invalidPath:"路径不合法。",pathOutsideWorkspace:"只能访问当前工作目录内的文件。",directoryNotFound:"目录不存在,请重新选择。",directoryOnly:"只能选择文件夹。",targetPathNotFound:"目标路径不存在。",directoryExpandOnly:"只能展开目录。",cwdRequired:"请先填写工作目录。",cwdNotFound:"工作目录不存在,请重新确认。",cwdMustBeDirectory:"工作目录必须是文件夹。",startedProjectCwdLocked:"已启动的 PromptX 项目不能直接修改工作目录。",startedProjectEngineLocked:"已启动的 PromptX 项目不能直接切换执行引擎,请新建项目。",startedProjectSessionLocked:"已启动的 PromptX 项目不能直接修改会话 ID,请新建项目。",agentEngineUnavailable:"当前执行引擎不可用。",noPromptToSend:"没有可发送的提示词。",shellUnsupportedBlocks:"命令模式暂不支持图片或导入文件,请只保留纯文本命令。",shellEmptyCommand:"请输入要执行的命令,例如 !git status",shellLocalOnly:"当前入口未被允许执行命令。请在设置 -> 通用 -> 远程命令安全中启用对应模式,或改为本机本地访问。",runnerRequestTimeout:"runner 请求超时。",runnerServiceUnavailable:"无法连接 runner 服务。",runnerDiagnosticsReadFailed:"无法读取 runner diagnostics",relayNotEnabled:"当前远程访问尚未启用,请先保存完整的 Relay 配置。",systemConfigHotReloadFailed:"系统配置已保存,但 runner 热更新失败。",systemConfigReadFailed:"系统配置读取失败。",uploadFileMissing:"没有收到上传文件。",uploadImageOnly:"只支持上传图片文件。",pdfFileMissing:"没有收到 PDF 文件。",pdfOnly:"只支持导入 PDF 文件。",pdfNoImportableContent:"没有从 PDF 中提取到可导入的文本或图片。",fileTooLarge:"文件太大了。",unexpectedServerError:"发生了意外错误。",streamUnsupported:"浏览器不支持流式响应。",uploadFailed:"上传失败。",pdfImportFailed:"PDF 导入失败。",transcriptOpenFailed:"无法打开本地会话存储",transcriptOperationFailed:"本地会话存储操作失败",transcriptAborted:"本地会话存储操作已中断"},sessionTurns:{currentProjectRunning:"当前项目正在运行中,请等待完成后再发送。",noPromptToSend:"没有可发送的提示词。"}},"en-US":{common:{settings:"Settings",save:"Save",saving:"Saving...",saved:"Saved",loading:"Loading...",unavailable:"Unavailable",cancel:"Cancel",confirm:"Confirm",processing:"Processing...",close:"Close",enabled:"Enabled",select:"Select",notAvailable:"N/A",noOptions:"No options available",expand:"Expand",collapse:"Collapse"},locale:{title:"Language",description:"Switch the PromptX UI language. Chinese and English are supported for now.",field:"Interface language",immediateHint:"Changes apply immediately and are stored in this browser.",zhHans:"简体中文",enUs:"English"},workbench:{title:"Workspace",newMessageTitle:"PromptX You Have New Messages...",tasks:"Tasks",settings:"Settings",createTask:"New",creatingTask:"Creating...",loadingTasks:"Loading tasks...",loadingTaskContent:"Loading task content...",untitledTask:"Untitled Task",running:"Running",noMessagesYet:"No messages sent yet",dragToReorder:"Drag to reorder",filesCount:({count:e})=>`${e} files`,editTask:"Edit",deleteTask:"Delete",deletingTask:"Deleting...",activity:"Activity",input:"Input",selectTask:"Select a task",promptCopied:"Prompt copied",projectCreated:"Project created",codeContextTitle:"Code context",codeContextFile:({path:e})=>`File: ${e}`,codeContextRange:({range:e})=>`Range: ${e}`,codeContextSource:({source:e})=>`Source: ${e}`,codeContextSourceDiff:"Code changes",codeContextSourceFile:"Source browser",confirmClearTitle:"Clear the current task?",confirmClearDescription:"This clears the editor content on the right, but keeps the current task itself.",confirmClearAction:"Clear Task",continueEditing:"Keep Editing",confirmDeleteTitle:"Delete the current task?",confirmDeleteDescription:({title:e})=>`This will delete "${e}". This action cannot be undone.`,confirmDeleteAction:"Delete Task",keepForNow:"Keep It",confirmDeleteTodoTitle:"Delete this todo?",confirmDeleteTodoDescription:"This todo cannot be restored after deletion.",replaceEditorTitle:"Replace editor content?",replaceEditorDescription:"The editor already has content. Using this todo will clear the current content and replace it with the todo content.",confirmReplaceAction:"Replace Content",dontReplaceYet:"Not Now"},editor:{chooseFiles:"Files",clear:"Clear",todo:"Todo",todoWithCount:({count:e})=>`Todo (${e})`,send:"Send",sending:"Sending",running:"Running",selectAgent:"Select Agent"},todoDialog:{title:"Manage Todo",intro:"Store temporary ideas under the current task and bring them back to the editor when needed.",summary:({count:e})=>`${e} todo item(s) in the current task`,summaryHint:"Using one fills the editor and removes it from the list",itemTitle:"Todo",blockCount:({count:e})=>`${e} block(s)`,textCount:({count:e})=>`Text ${e}`,importedCount:({count:e})=>`Imported ${e}`,imageCount:({count:e})=>`Image ${e}`,use:"Use",delete:"Delete",empty:"No todo items yet. Save a temporary idea from the editor first.",imagePreview:({count:e})=>`Contains ${e} image(s)`,noPreview:"No text preview is available yet",justAdded:"Just added"},theme:{title:"Theme",sectionDescription:"Manage theme and language preferences.",heading:"Interface theme",currentTheme:({name:e})=>`Current: ${e}`,helper:"Switch the full visual system like an editor, not just light and dark mode.",groupLight:"Light Themes",groupDark:"Dark Themes",description:{"promptx-stone-light":"Soft stone tones for long daytime sessions.","promptx-glass-light":"A frosted glass look with stone and green accents.","promptx-aqua-classic":"A retro macOS Aqua / Snow Leopard skeuomorphic workbench.","promptx-stone-dark":"A dark theme that keeps the current PromptX feel.","github-light":"Clean and restrained, good for review and collaboration.","github-dark":"A familiar dark code-hosting style.","solarized-light":"Warm paper-like contrast, great for long reading.","solarized-dark":"Classic Solarized dark, soft on the eyes.","ink-mist":"A cool ink-mist style for focused long sessions.","promptx-ink-landscape":"Cool mist, ink-blue layers, and scroll-like spacing for a floating landscape desk feel.","tokyo-night":"A cooler dark theme with a sharper editor-like feel."}},settingsDialog:{general:{sectionLabel:"General",sectionDescription:"Core workbench preferences",title:"General Preferences",intro:"This section holds core workbench interaction preferences. Future general settings can use different backing stores without changing the UI model.",remoteCommandSecurityTitle:"Remote Command Security",remoteCommandSecurityDescription:"Control whether remote pages may execute high-privilege commands such as !git status or !pnpm test.",remoteCommandSecurityModeField:"Security mode",remoteCommandSecurityModeDisabled:"Disabled",remoteCommandSecurityModeDisabledDescription:"Blocks command mode for all remote entry points except local loopback access.",remoteCommandSecurityModeRelay:"Relay",remoteCommandSecurityModeRelayDescription:"Allows command mode only for remote requests coming through PromptX Relay.",remoteCommandSecurityModeTrustedProxy:"Trusted Proxy",remoteCommandSecurityModeTrustedProxyDescription:"Allows command mode only for your trusted reverse proxy entry and validates the injected token.",trustedProxyTokenField:"Trusted Proxy Token",trustedProxyTokenPlaceholder:"Enter the Trusted Proxy Token when enabling this mode for the first time",trustedProxyTokenReplacePlaceholder:"Enter a new Trusted Proxy Token to replace the current one",trustedProxyTokenConfiguredHint:"A token is already configured. For safety the current value is not shown here.",trustedProxyTokenHint:"Your reverse proxy must inject both X-PromptX-Trusted-Proxy: 1 and X-PromptX-Proxy-Token.",trustedProxyTokenReplaceHint:"Leave this blank to keep the current token, or enter a new one to replace it.",remoteCommandSecurityWarning:"This is a high-privilege capability. Only enable it when you trust the current remote entry point.",remoteCommandSecuritySave:"Save Remote Command Settings",remoteCommandSecuritySaved:"Saved",sendBehavior:{title:"Send Message Behavior",description:"Choose whether Enter sends from the editor or sending is limited to the button.",hint:"The send button always works. This only changes keyboard sending inside the editor.",options:{enter:{label:"Enter Sends",description:"Press Enter to send and Shift + Enter to insert a new line."},shiftEnter:{label:"Shift + Enter Sends",description:"Press Enter to insert a new line and Shift + Enter to send."},buttonOnly:{label:"Button Only",description:"Enter is always used for editing. Sending only happens from the send button."}}},notificationSound:{title:"Notification Sound",description:"Control whether unread task updates play a notification sound.",switchLabel:"Enable Notification Sound",switchHint:"Disabled by default. When enabled, a sound plays when a non-focused task gets a new unread result."}},relay:{sectionLabel:"Remote",sectionDescription:"Relay and mobile access",title:"Remote Access Relay",enableTitle:"Enable remote access",enableDescription:"Turning this off disconnects the current Relay connection from this machine.",relayUrl:"Relay URL",deviceId:"Device ID",deviceToken:"Device Token",deviceTokenPlaceholder:"Enter the device token from your cloud Relay",pausedReconnect:({reason:e})=>`Auto reconnect is paused: ${e}`,managedByEnv:"Relay config is currently managed by environment variables. The settings page shows the effective values only, and the service must be restarted after changing env vars.",lastError:({value:e})=>`Last error: ${e}`,lastClosed:({reason:e,code:t})=>`Last disconnect: ${e}${t?` (code ${t})`:""}`,lastConnected:({value:e})=>`Last connected: ${e}`,recentEvent:({value:e})=>`Recent event: ${e}`,copied:"Relay diagnostics copied. You can send them to me for troubleshooting.",defaultHint:"HTTPS is recommended for public Relay deployments. Make sure the cloud Relay and local client use the same device token. In multi-tenant mode, each person should use their own subdomain.",reconnectNow:"Reconnect Now",reconnecting:"Reconnecting...",copyDiagnostics:"Copy Relay Diagnostics",diagnosticsCopied:"Diagnostics Copied",saveConfig:"Save Remote Access",relayConfigLoadFailed:"Failed to load remote access settings.",relayConfigSavedEnabled:"Remote access settings saved. PromptX is trying to connect to Relay.",relayConfigSavedDisabled:"Remote access disabled.",relayConfigSaveFailed:"Failed to save remote access settings.",relayReconnectTriggered:"Reconnect triggered. PromptX is re-establishing the Relay connection.",relayReconnectFailed:"Failed to trigger Relay reconnect.",relayFieldsRequired:"Fill in Relay URL, Device ID, and Device Token before enabling remote access.",relayEnabledSaved:"Remote access enabled. PromptX is trying to connect to Relay.",relayToggleFailed:"Failed to save the remote access toggle.",relayDiagnosticsCopyFailed:"Failed to copy Relay diagnostics.",reason:{invalid_tenant:"The current Relay domain does not match any tenant.",invalid_token:"Device token does not match.",invalid_device:"Device ID does not match.",missing_hello:"Missing device hello packet.",missing_auth:"Device authentication timed out.",replaced_by_new_connection:"Replaced by a newer device connection.",config_updated:"Configuration updated. Reconnecting.",heartbeat_timeout:"Heartbeat timed out and the connection became invalid."},event:{reconnect_paused:"Auto reconnect paused",local_request_failed:"Local request forwarding failed",dispatch_failed:"Request dispatch failed",connect_failed:"Connection failed",reconnect_scheduled:"Reconnect scheduled",reconnect_requested:"Reconnect requested",system_resume_detected:"System resume detected",heartbeat_stale:"Heartbeat became stale",connect_start:"Connecting",ws_open:"WebSocket opened",auth_ok:"Device authenticated",stale_close_ignored:"Ignored stale close event",close:"Connection closed",error:"Connection error",disabled:"Disabled",stopped:"Stopped",config_updated:"Configuration updated",unknown:"Unknown event"},error:{connect_failed:"Relay connection failed.",disconnected:({reason:e})=>`Relay disconnected: ${e}`,rejected:({reason:e})=>`Relay connection rejected: ${e}`,closedWithCode:({code:e})=>`Relay connection closed (code=${e})`},status:{reconnecting:"Reconnecting...",saving:"Saving...",loading:"Loading...",paused:"Reconnect Paused",connected:"Connected",waitingReconnect:"Waiting to Reconnect",disconnected:"Disconnected",disabled:"Disabled"}},system:{sectionLabel:"System",sectionDescription:"Runner and performance",title:"System",intro:"Runner concurrency limits and runtime diagnostics live here. When investigating lag, queueing, or stop/recovery issues, start with the realtime stats below.",maxConcurrentRuns:"Max concurrent real agent runs",maxConcurrentRunsHint:"New runs beyond this limit enter the queue and start when the runner becomes available.",managedByEnv:"The concurrency limit is managed by `PROMPTX_RUNNER_MAX_CONCURRENT_RUNS`. The settings page shows the effective value only.",diagnosticsHint:"Diagnostics now match real concurrency control: `active` no longer incorrectly counts queued runs.",saveConfig:"Save System Settings",runtimeDiagnostics:"Runtime Diagnostics",runtimeDiagnosticsHint:"Refreshes every 5 seconds so you can watch runner, recovery, and maintenance activity in real time.",refreshDiagnostics:"Refresh Diagnostics",refreshingDiagnostics:"Refreshing...",copyDiagnostics:"Copy Diagnostics",diagnosticsCopied:"Diagnostics Copied",diagnosticsCopiedHint:"System diagnostics copied. You can send them to me for troubleshooting.",active:"Actively occupying concurrency slots",tracked:"All tracked contexts in runner memory",queued:"Runs waiting to start",maxConcurrent:"Current active concurrency limit",completed:"Completed runs",stopped:"Stopped runs",error:"Errored runs",stopTimeout:"Stop-timeout runs",eventWriteFailures:"Batched event write failures",recoveredRuns:"Disconnected runs recovered by server",lastMaintenanceAt:"Last maintenance cleanup",baseStatus:"Base Status",available:"Available",unknown:"Unknown",stopReasonTitle:"Stop Reason Breakdown",stopTimeoutPhaseTitle:"Stop Timeout Phases",runnerUnavailable:"Runner unavailable",runnerUnavailableDescription:"Runner diagnostics are not available yet.",systemConfigLoadFailed:"Failed to load system settings.",systemConfigSaved:"System settings saved. Runner concurrency has been updated.",systemConfigSaveFailed:"Failed to save system settings.",systemDiagnosticsLoadFailed:"Failed to load system diagnostics.",systemDiagnosticsCopyFailed:"Failed to copy system diagnostics.",stopReasons:{queued_cancelled:"Cancelled before start",user_requested:"Stopped by user",user_requested_after_error:"Errored after stop request",stop_timeout:"Stop timeout"},stopTimeoutPhases:{runner_timeout_without_stop_request:"No stop request recorded",runner_timeout_before_cancel:"Timed out before cancel",cli_not_exiting:"CLI did not exit",os_kill_slow:"OS kill was slow",runner_finalize_after_exit:"Slow cleanup after exit"}},shortcuts:{sectionLabel:"Shortcuts",sectionDescription:"Global keyboard actions",title:"Shortcuts",intro:"These shortcuts work across the workbench and can be triggered from any area.",openSettingsTitle:"Open settings",openSettingsDescription:"Open the global settings dialog quickly.",openProjectManagerTitle:"Open project manager",openProjectManagerDescription:"Open the project manager for the current task.",openSourceBrowserTitle:"Open source browser",openSourceBrowserDescription:"Jump straight into the read-only source browser for the current project.",openDiffReviewTitle:"Open code changes",openDiffReviewDescription:"Open the code changes dialog for the current task project.",closeTopDialogTitle:"Close the top dialog",closeTopDialogDescription:"Closes the topmost confirm dialog, source browser, project manager, or settings panel first.",note:"These shortcuts are primarily designed for desktop. Mobile still relies on touch interactions."},about:{sectionLabel:"About",sectionDescription:"Version and info",title:"About",intro:"Version info lives here for now. Changelog and environment notes can join this section later.",versionTitle:"Version",versionDescription:"The currently installed PromptX version.",versionPending:"The current service has not returned a version yet. Please confirm it has been restarted to the latest version.",versionLoadFailed:"Failed to load version info."}},taskDialog:{title:"Edit Task",currentTask:({title:e})=>`Current task: ${e}`,loading:"Loading task settings...",sections:{basic:{label:"Basic",description:"Title and task info",title:"Basic Info",intro:"Manage the task title here. Leave it empty to keep using the auto title.",taskTitle:"Task Title",taskTitlePlaceholder:"Leave empty to keep the auto title"},automation:{label:"Schedule",description:"Automatic runs",title:"Scheduled Run",intro:"Configure the schedule visually. No need to type Cron by hand.",mode:"Run cycle",time:"Run time",weekday:"Weekday",timezone:"Timezone",concurrencyPolicy:"Concurrency policy",lastTriggered:({value:e})=>`Last triggered: ${e}`,nextTriggered:({value:e})=>`Next trigger: ${e}`,modeDaily:"Daily",modeWeekdays:"Weekdays",modeWeekly:"Weekly",weekday1:"Mon",weekday2:"Tue",weekday3:"Wed",weekday4:"Thu",weekday5:"Fri",weekday6:"Sat",weekday0:"Sun",timezoneLocal:"Follow local timezone",concurrencySkip:"Skip if another run is active"},notification:{label:"Notify",description:"Run completion notifications",title:"Run Notifications",intro:"Push run results to a group bot after the run finishes.",channelType:"Channel",triggerOn:"Trigger",webhookUrl:"Webhook URL",webhookUrlPlaceholder:"Enter the bot webhook URL",secret:"Signing secret (optional)",secretPlaceholder:"Fill this only if signing is enabled",locale:"Notification language",localeZhCn:"简体中文",localeEnUs:"English",messageMode:"Message mode",status:({value:e})=>`Notification status: ${e}`,lastSent:({value:e})=>`Last sent: ${e}`,lastError:({value:e})=>`Last error: ${e}`,channelDingtalk:"DingTalk Webhook",channelFeishu:"Feishu Webhook",channelWebhook:"Generic Webhook",triggerCompleted:"After this run finishes",triggerSuccess:"After this run succeeds",triggerError:"After this run fails",messageSummary:"Summary message",statusDisabled:"Disabled",statusSuccess:"Last send succeeded",statusError:"Last send failed",statusPending:"Waiting for first send"}},enabled:"Enabled",footerHint:"Scheduled runs create new runs from Cron. Notifications are sent to the group bot after the current run finishes.",saveTaskConfig:"Save Task Settings",loadFailed:"Failed to load task settings.",saveFailed:"Failed to save task settings."},taskActions:{taskSaved:"Task saved",taskCreated:"New task created",taskCleared:"Current task content cleared. It will be auto-saved shortly.",todoAdded:"Added to todo",fileProcessing:"Files are still being processed. Please wait before editing this task.",fileProcessingBeforeSend:"Files are still being processed. Please wait before sending to the current engine.",sessionLocked:"This task already has project history, so the project cannot be changed. Create a new task if you want to use a different project.",noTextImported:"No insertable text content was found.",textImportFailed:"Failed to read the file. Please use UTF-8 encoded plain text files.",noPdfContent:"No insertable content was parsed from the PDF.",pdfImportFailed:"Failed to parse the PDF. Please make sure it is not a scanned file and uses a single-column layout.",imageInserted:({count:e,appended:t})=>t?`${e} image(s) inserted after the current import block. They will be auto-saved shortly.`:`${e} image(s) inserted. They will be auto-saved shortly.`,importedBlocksInserted:({count:e,appended:t})=>t?`${e} imported block(s) inserted after the current import block. They will be auto-saved shortly.`:`${e} imported block(s) inserted. They will be auto-saved shortly.`,pdfBlocksInserted:({blockCount:e,pageCount:t})=>`${e} mixed content block(s) inserted${t?` across ${t} page(s)`:""}. They will be auto-saved shortly.`,insertedToEditor:"Inserted into the editor"},projectManager:{managingTitle:"PromptX Project Manager",createTitle:"Create Project",editTitle:"Edit Project",newProject:"New Project",projectList:"Projects",noProjects:"No projects yet. Create one with a fixed working directory first.",create:"Create",current:"Current",regular:"Normal",untitledProject:"Untitled Project",enginePrefix:"Engine: {value}",updatedAtPrefix:"Updated: {value}",runtimeStatus:"Runtime Status",currentProject:"Current Project",engine:"Engine",workingDirectory:"Working Directory",notSet:"Not set",updatedAt:"Updated",note:"Note",noteDescription:"A project binds a directory and engine. When the directory stays the same, PromptX keeps reusing the same engine session.",projectTitleOptional:"Project Title (optional)",workingDirectoryField:"Working Directory",choose:"Choose",chooseDirectory:"Choose Directory",engineField:"Engine",selectEngine:"Select an engine",collaborationAgents:"Collaborating Agents",collaborationAgentsHint:"The default agent continues to use the session ID above. Extra checked agents share the same workspace and create their own threads on first send.",agentEnabled:"Included in this project",agentDisabled:"Click to include",agentCount:({count:e})=>`${e} agent(s)`,noEngines:"No engine options available",comingSoon:"Coming soon",confirmDeleteTitle:"Delete this PromptX project?",confirmDeleteDescription:({title:e})=>`This deletes the local record "${e}". It will not delete the working directory or the engine history.`,confirmDelete:"Delete Project",newSession:"New Session",resettingSession:"Resetting...",confirmResetTitle:"Start a new project session?",confirmResetDescription:({title:e})=>`This clears the current session bound to "${e}" and removes the run history of tasks under this project. The project, working directory, and editor content stay intact. The next run starts from a fresh session.`,confirmReset:"Start New Session",sessionReset:"Project session reset. The next run will start fresh.",keep:"Keep It",basicInfo:"Basic Info",status:"Status",close:"Close",backToList:"Back to List",deleteProject:"Delete Project",deletingProject:"Deleting...",createProject:"Create Project",creatingProject:"Creating...",saveChanges:"Save Changes",savingChanges:"Saving...",directoryRequired:"Please enter a working directory first.",projectMissing:"The current project no longer exists. Please select it again.",duplicateDirectory:({labels:e,count:t})=>`This directory is already used by ${e}${t>3?" and others":""}. Reusing it is recommended so the same directory does not get split into multiple projects.`,cwdReadonly:"This project is already bound to an engine session, so the working directory can no longer be changed. Create a new project to use another directory.",engineReadonly:"This project is already bound to an engine session, so the engine can no longer be changed. Create a new project to switch engines.",sessionId:"Session ID",sessionIdHint:"Leave it empty to create one on first run, or fill an existing ID to resume that session.",sessionIdReadonly:"This project has already run, so the session ID can no longer be changed. Create a new project to switch it.",sessionCandidates:"Local sessions",sessionCandidatesLoading:"Loading...",noSessionCandidates:"No matching local sessions. Manual input is still supported.",sessionCandidatesNeedDirectory:"Choose a working directory before selecting a local session. Manual input is still allowed.",copySessionId:"Copy",sessionIdCopied:"Copied",copySessionIdFailed:"Failed to copy session ID.",viewSource:"View Source",running:"Running",idle:"Idle",threadBound:"Bound",notStarted:"New",unknown:"Unknown",syncingProjects:"Loading...",syncingLatestProjects:"Loading...",projectCount:({count:e})=>`${e} project(s)`,selectProject:"Select a project",noProjectsInSelect:"No projects yet. Create one in the manager first."},sourceBrowser:{title:"Source Browser",readOnlyHint:({title:e})=>`Read-only source view for "${e}"`,noWorkspace:"This project does not have a working directory yet.",noProject:"Select a project first.",searchLabel:"Search Files",searchPlaceholder:"Search by file name or path fragment",contentSearchPlaceholder:"Search inside file contents",searchModePath:"Path",searchModeContent:"Content",searchAction:"Search",searchMinKeywordHint:({count:e})=>`Enter at least ${e} characters to start searching.`,searchEmpty:"No matching files were found.",contentSearchPrompt:"Waiting for search results...",contentSearchEmpty:"No matching content was found.",contentSearching:"Searching file contents...",contentSearchFailed:"Failed to search file contents.",contentSearchResultMeta:({path:e,line:t})=>`${e} · line ${t}`,contentSearchTruncated:"Only the first portion of matches is shown.",treeEmpty:"There are no files to display in this directory.",loadingFiles:"Loading files...",recent:"Recent",results:"Results",previewLoading:"Loading file content...",previewFailed:"Failed to load file content.",selectFile:"Select a file from the left panel.",selectFileHint:"A directory is selected. Choose a file to preview.",truncated:"Truncated",binaryUnsupported:"This is a binary file and cannot be previewed inline right now.",binaryTooLarge:"This file is too large to preview inline right now.",selectCodeLineHint:"Select code directly. An insert button appears beside the selection.",selectedLines:({count:e})=>`${e} line(s) selected`,insertSelection:"Insert into editor"},directoryPicker:{title:"Choose Working Directory",intro:"Browsing and search are limited to the current user home by default. Use manual input for special paths.",currentSelection:"Current Selection",selectionPlaceholder:"Select a directory from the tree or search results",searchLabel:"Search Directories",searchPlaceholder:"Enter a directory name or path fragment, such as promptx / code",searchMinKeywordHint:({count:e})=>`Enter at least ${e} characters to start searching.`,searching:"Searching...",treeLoading:"Loading directory tree...",noSearchResults:"No matching directories found. Try a shorter keyword, or browse the directory tree directly.",emptyTree:"There are no directories to display.",truncatedHint:"Search results were truncated to show only the most relevant directories.",cancel:"Cancel",useCurrentDirectory:"Use Current Directory",unnamedDirectory:"Unnamed Directory",loadFailed:"Failed to load directories.",treeLoadFailed:"Failed to load the directory tree.",searchFailed:"Search failed."},pathPicker:{selectProjectFirst:"Select a project first.",noResults:"No results",emptyDirectory:"Empty directory",loading:"Loading...",recent:"Recent",results:"Results"},diffReview:{dialogTitle:"Changes",dialogTitleWithTask:({title:e})=>`Changes · ${e}`,scopeCurrentShort:"Now",scopeCurrent:"Current Changes",scopeTaskShort:"Total",scopeTask:"Task Total",scopeRun:"Run",refresh:"Refresh",refreshing:"Refreshing...",computing:"Computing...",selectRun:"Select a run",noRuns:"No historical runs are available",runCount:({count:e})=>`${e} reviewable run(s)`,loading:"Loading code changes...",unavailableTitle:"Code changes are unavailable right now",unavailableReason:"There are no code changes to display right now.",unknownBranch:"Unknown branch",fileCount:({count:e})=>`${e} file(s)`,waitingStats:"Waiting for stats",filesTab:"Files",diffTab:"Diff",searchFilePath:"Search file paths",statsPending:"The file list is already available. Total additions and deletions are still being computed in the background...",noChanges:"No code changes were detected in the current scope.",noMatches:"No files match the current filter or search.",statsOnDemand:"Stats loaded on demand",changeIndex:({current:e,total:t})=>`Change ${e}/${t}`,loadingFileDiff:"Loading diff for this file...",noFileDiffContent:"This file has no diff content to display.",selectFile:"Select a file to view the diff.",binaryPreviewUnavailable:"Binary files are not supported for inline diff preview yet.",binaryPreviewTitle:"Binary Preview",binaryTag:"Binary",binaryMetaTitle:"File Metadata",binaryBefore:"Before",binaryAfter:"After",binarySideMissing:"This side does not exist.",downloadBinarySide:"Download file",binaryPreviewTooLarge:"The file is too large to preview inline right now.",binarySnapshotUnavailable:"This historical snapshot did not store the binary file body.",openImagePreview:"Open image preview",fileTooLarge:"The file is too large to show its detailed diff.",diffTooLong:"The diff is too long to render in full on this page.",diffPreviewOnly:"The diff is long, so PromptX shows a summarized preview only.",fileDiffTimedOut:"This file diff took too long to compute, so PromptX does not render it inline right now.",notGitRepo:"The current working directory is not a Git repository, so code review is unavailable.",taskNotFound:"Task not found.",runRequired:"Select a run before reviewing code changes for that run.",runNotFound:"The requested run was not found.",runBaselineMissing:"This run has not established a code-change baseline yet, so its diff is unavailable for now.",taskBaselineMissing:"This task has not established a code-change baseline yet. Let the agent run once first.",runSnapshotMissing:"This run is missing its final snapshot, so PromptX cannot accurately reconstruct its code changes.",fileNotInDiff:"This file is not part of the current diff scope.",originalRepoInvalid:"The original working directory is no longer a valid Git repository, so PromptX cannot read these code changes.",baselineCommitMissing:"The baseline commit no longer exists. The repository may have been reset, rebased, or moved onto unrelated history, so PromptX cannot accurately read this diff range.",warningBranchChanged:({from:e,to:t})=>`Current branch changed from ${e} to ${t}`,warningHeadDetachedFromBaseline:"The current HEAD is no longer in the descendant history of the baseline commit. The repository may have been reset, rebased, or switched to another branch.",baselineTime:({value:e})=>`Baseline time: ${e}`,baselineBranch:({value:e})=>`Baseline branch: ${e}`,baselineCommit:({value:e})=>`Baseline commit: ${e}`,currentHead:({value:e})=>`Current HEAD: ${e}`,completed:"Completed",failed:"Failed",interrupted:"Interrupted",stopped:"Stopped",added:"Add",deleted:"Del",modified:"Edit",all:"All",noReviewRuns:"There are no historical runs available for review yet.",selectCodeLineHint:"Select code directly. An insert button appears beside the selection.",selectedLines:({count:e})=>`${e} line(s) selected`,insertSelection:"Insert into editor"},sessionPanel:{diff:"Changes",manageProjects:"Projects",agentFilter:"Agent filter",allAgents:"All",emptyAgentFilter:"No messages for this agent yet.",showProcessToggle:"Show execution details",hideProcessToggle:"Hide execution details",empty:"Project execution activity and model replies appear here.",promptTitleWithAgent:({agent:e})=>`PromptX → ${e}:`,expand:"Expand",collapse:"Collapse",promptImageAlt:"Prompt image",processTitle:"Run:",loading:"Loading...",loadingEvents:"Loading execution details...",hiddenEventsLoaded:({count:e})=>`${e} execution log(s) collapsed`,hiddenEventsLoadLater:({count:e})=>`${e} execution log(s) available. Expand to load.`,waitingEvents:({agent:e})=>`Waiting for more events from ${e}...`,noEvents:"No execution details were recorded for this run.",view:"View",insert:"Insert",copyCode:"Copy",copyCodeAria:"Copy code",codeCopied:"Code copied",defaultAgent:"Default",agentNotEnabled:"This project does not enable that agent yet. Add it in project settings first.",shellUnsupportedBlocks:"Shell mode only supports plain text commands. Remove images or imported files first.",shellEmptyCommand:"Enter a command to run, for example !git status",errorSuffix:({agent:e})=>`${e}:`,responseSuffix:({agent:e})=>`${e}:`,jumpToLatest:"New messages, jump to bottom",stop:"Stop",stopping:"Stopping..."},runner:{status:{queued:"Still queued, waiting for runner to become idle.",stopping:"Stopping execution, waiting for engine to exit...",thinking:({agentLabel:e})=>`${e} is thinking...`}},processDetail:{changeCreate:"Added",changeDelete:"Deleted",changeUpdate:"Updated",changeGeneric:"Changed",subAgentPending:"Pending start",subAgentRunning:"Running",subAgentCompleted:"Completed",subAgentFailed:"Failed",subAgentUnknown:"Unknown",directorySummary:({count:e})=>`${e} item(s)`,directoryHidden:({count:e})=>`, ${e} more hidden`,hiddenItems:({count:e})=>`${e} more item(s) hidden`,hiddenLines:({count:e})=>`${e} more line(s) hidden`,searchMatchCount:({count:e})=>`${e} match(es)`,searchHiddenMatches:({count:e})=>`${e} more match(es) hidden in this file`,searchFileSummary:({fileCount:e,matchCount:t})=>`${e} file(s), ${t} match(es)`,searchHiddenFiles:({count:e})=>`, ${e} more file(s) hidden`},blockEditor:{stats:({lines:e,chars:t})=>`${e} line(s) · ${t} char(s)`,title:"Input text, images, or files",uploading:"Processing files",placeholderFirst:"Start describing your task here...",placeholderNext:"Continue typing...",delete:"Delete",image:"Image",file:"File",unnamedFile:"Unnamed File",unnamedImage:"Unnamed Image",unnamedPdf:"Unnamed PDF",fileSummary:({name:e,stats:t})=>`${e} (${t})`,expand:"Expand",collapse:"Collapse",convertToText:"Convert to Text",emptyContent:"Empty content",emptyImportPlaceholder:"Imported content is empty",insertedImageAlt:"Inserted image",unsupportedFiles:({names:e,extra:t})=>`Unsupported files: ${e}${t?` and ${t} more`:""}`,oversizedFiles:({names:e,extra:t,limit:n})=>`These files exceed the size limit: ${e}${t?` and ${t} more`:""}. Keep each file within ${n}.`},imagePreview:{zoomOut:"Zoom Out",zoomIn:"Zoom In",previous:"Previous",next:"Next",close:"Close",alt:"Image preview"},misc:{promptxVersionDescription:"The currently installed PromptX version."},errors:{requestFailed:"Request failed.",taskCreateFailed:"Failed to create the task.",taskNotFound:"Task not found.",taskExpired:"Task has expired.",taskUpdateFailed:"Failed to update the task.",taskDeleteWhileRunning:"This task is still running. Stop it before deleting.",taskClearRunsWhileRunning:"This task is still running. Stop it before clearing its run history.",taskSessionLocked:"This task already has project history and can no longer switch projects. Create a new task if you need another project.",sessionRequired:"Please select a PromptX project first.",sessionNotFound:"The requested PromptX project was not found.",currentProjectRunning:"The current project is still running. Please wait until it finishes before sending again.",currentProjectDeleteWhileRunning:"This project is still running. Stop it before deleting.",runNotFound:"The requested run was not found.",invalidDiffScope:"Invalid diff scope.",gitDiffFailed:"Failed to calculate git diff.",invalidPath:"Invalid path.",pathOutsideWorkspace:"You can only access files inside the current working directory.",directoryNotFound:"Directory not found. Please choose again.",directoryOnly:"Only folders can be selected.",targetPathNotFound:"Target path not found.",directoryExpandOnly:"Only directories can be expanded.",cwdRequired:"Please enter a working directory first.",cwdNotFound:"The working directory does not exist. Please check it again.",cwdMustBeDirectory:"The working directory must be a folder.",startedProjectCwdLocked:"The working directory cannot be changed after the PromptX project has started.",startedProjectEngineLocked:"The engine cannot be changed after the PromptX project has started. Please create a new project.",startedProjectSessionLocked:"The session ID cannot be changed after the PromptX project has started. Please create a new project.",agentEngineUnavailable:"The selected engine is currently unavailable.",noPromptToSend:"There is no prompt to send.",shellUnsupportedBlocks:"Shell mode only supports plain text commands. Remove images or imported files first.",shellEmptyCommand:"Enter a command to run, for example !git status",shellLocalOnly:"This entry point is not allowed to execute shell commands. Enable the matching mode in Settings -> General -> Remote Command Security, or switch to local access.",runnerRequestTimeout:"The runner request timed out.",runnerServiceUnavailable:"Unable to connect to the runner service.",runnerDiagnosticsReadFailed:"Unable to read runner diagnostics.",relayNotEnabled:"Remote access is not enabled yet. Save a complete Relay configuration first.",systemConfigHotReloadFailed:"System settings were saved, but runner hot reload failed.",systemConfigReadFailed:"Failed to read system settings.",uploadFileMissing:"No file was uploaded.",uploadImageOnly:"Only image files can be uploaded.",pdfFileMissing:"No PDF file was uploaded.",pdfOnly:"Only PDF files can be imported.",pdfNoImportableContent:"No importable text or image content was extracted from the PDF.",fileTooLarge:"The file is too large.",unexpectedServerError:"An unexpected server error occurred.",streamUnsupported:"Streaming responses are not supported in this browser.",uploadFailed:"Upload failed.",pdfImportFailed:"PDF import failed.",transcriptOpenFailed:"Unable to open local transcript storage",transcriptOperationFailed:"Local transcript storage operation failed",transcriptAborted:"Local transcript storage operation was aborted"},sessionTurns:{currentProjectRunning:"The current project is still running. Please wait until it finishes before sending again.",noPromptToSend:"There is no prompt to send."}}};function ve(e="",t={}){return String(e).replace(/\{(\w+)\}/g,(n,o)=>String((t==null?void 0:t[o])??""))}function E(e=""){var n;const t=String(e||"").trim();return((n=D.find(o=>o.value===t))==null?void 0:n.value)||y}function ke(e=""){const t=E(e);return D.find(n=>n.value===t)||D[0]}function j(e={},t=""){return String(t||"").split(".").filter(Boolean).reduce((n,o)=>n==null?void 0:n[o],e)}const g=S(y),R=S(!1);function Pe(){return y}function q(e){typeof document>"u"||(document.documentElement.lang=e)}function X(){return g.value}function I(e="",t={},n=""){const o=E(g.value),r=B[o]||B[y],i=B[y]||{},a=j(r,e)??j(i,e);return typeof a=="function"?a(t):typeof a=="string"?ve(a,t):n||e}function Ce(){if(typeof window>"u")return g.value=y,R.value=!0,g.value;const e=window.localStorage.getItem(N),t=E(e||Pe());return g.value=t,window.localStorage.setItem(N,t),q(t),R.value=!0,t}function xe(e=""){const t=E(e);g.value=t,typeof window<"u"&&window.localStorage.setItem(N,t),q(t),R.value=!0}function Ie(e="",t={}){const n=String(e||"").trim();if(!n)return I("common.notAvailable");const o=new Date(n);return Number.isNaN(o.getTime())?I("common.notAvailable"):new Intl.DateTimeFormat(X(),t).format(o)}function Le(e="",t=""){return String(e||"").localeCompare(String(t||""),X())}function _e(){const e=f(()=>g.value),t=f(()=>D.map(o=>({value:o.value,label:o.label,englishLabel:o.englishLabel}))),n=f(()=>ke(g.value));return{locale:e,localeMeta:n,localeOptions:t,localeReady:R,setLocale:xe,t:I}}const C="promptx:theme-id",T="promptx-stone-light",z=[{id:"promptx-stone-light",name:"Stone Light",shortName:"Stone Light",mode:"light",description:"温和石色,适合长时间白天工作。",swatches:["#f1eee8","#fbfaf8","#d6cdc1","#3f7a67"],colors:{appBg:"#f1eee8",appPanel:"#fbfaf8",appPanelMuted:"#f5f1ea",appPanelStrong:"#ffffff",appPanelHover:"#efe8de",appPanelInset:"#e8e0d4",appOverlay:"rgba(255, 252, 246, 0.82)",borderDefault:"#d1c7ba",borderMuted:"#e4dbcf",borderStrong:"#b2a594",textPrimary:"#000000",textSecondary:"#302a25",textMuted:"#554c43",textInverse:"#fffdf9",buttonBg:"#f8f4ed",buttonHover:"#ede4d9",buttonBorder:"#cbbfb1",buttonText:"#221d19",primaryBg:"#221d19",primaryHover:"#3b342e",primaryBorder:"#221d19",primaryText:"#fffaf4",inputBg:"#fffdf9",inputBorder:"#cbbfb1",focusRing:"rgba(100, 86, 74, 0.22)",selectionBg:"#d8cec0",selectionText:"#241f1b",accent:"#2b7a66",accentSoft:"#e3f1ec",accentText:"#184d40",warning:"#b07a2c",warningSoft:"#fbedd4",warningText:"#7a521c",danger:"#b45151",dangerSoft:"#f9e3e3",dangerText:"#7e2f2f",success:"#2c8a57",successSoft:"#e5f4ea",successText:"#1d5d3b",info:"#2563a6",infoSoft:"#e3eefb",infoText:"#1f4a79",promptBg:"#f5dec2",promptBorder:"#d7aa77",promptText:"#58391d",processBg:"#f3eee6",processBorder:"#d6cab9",processText:"#312b26",responseBg:"#e6f2eb",responseBorder:"#9bc4ab",responseText:"#1f4f37",codeBg:"#f5f1ea",codeBorder:"#dbd1c3",shadowPanel:"0 14px 38px rgba(53, 38, 22, 0.08)",shadowPopover:"0 18px 48px rgba(43, 30, 18, 0.16)"}},{id:"promptx-glass-light",name:"Glass Light",shortName:"Glass Light",mode:"light",mobileEnabled:!1,description:"雾面玻璃质感,保留石色与绿调。",swatches:["#e5eeea","#f7fbf9","#bdd0c7","#2f7b68"],colors:{appBg:"#e4ebe7",appPanel:"#f4faf7",appPanelMuted:"#edf4f0",appPanelStrong:"#ffffff",appPanelHover:"#edf5f1",appPanelInset:"#e0ebe5",appOverlay:"rgba(248, 252, 250, 0.68)",borderDefault:"#b8cbc2",borderMuted:"#d7e4de",borderStrong:"#95aea4",textPrimary:"#000000",textSecondary:"#293630",textMuted:"#495952",textInverse:"#f7fffb",buttonBg:"rgba(247, 251, 249, 0.58)",buttonHover:"rgba(241, 247, 244, 0.82)",buttonBorder:"rgba(149, 174, 164, 0.56)",buttonText:"#183228",primaryBg:"#2f7b68",primaryHover:"#388773",primaryBorder:"#2f7b68",primaryText:"#f3fffa",inputBg:"rgba(255, 255, 255, 0.56)",inputBorder:"rgba(149, 174, 164, 0.62)",focusRing:"rgba(47, 123, 104, 0.2)",selectionBg:"#caded6",selectionText:"#18211d",accent:"#2f7b68",accentSoft:"rgba(220, 242, 234, 0.86)",accentText:"#1c5a49",warning:"#a77736",warningSoft:"#f9ecd7",warningText:"#6f4918",danger:"#b85d66",dangerSoft:"#f9e4e7",dangerText:"#7a343f",success:"#33845f",successSoft:"#e1f3e9",successText:"#1f5d42",info:"#2f6899",infoSoft:"#e1edf8",infoText:"#20486b",promptBg:"#efe2d0",promptBorder:"#cda87c",promptText:"#5b3f26",processBg:"rgba(240, 245, 243, 0.84)",processBorder:"#c3d2cb",processText:"#2d3833",responseBg:"#e2f0ea",responseBorder:"#8ab8a5",responseText:"#1e5440",codeBg:"rgba(241, 246, 244, 0.92)",codeBorder:"#cbdad3",shadowPanel:"0 18px 46px rgba(76, 95, 86, 0.16)",shadowPopover:"0 22px 56px rgba(64, 82, 74, 0.2)",shellGradient:"radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.92) 0%, rgba(255, 255, 255, 0.6) 22%, transparent 42%), radial-gradient(circle at 84% 12%, rgba(178, 219, 204, 0.34) 0%, transparent 34%), radial-gradient(circle at 78% 82%, rgba(240, 210, 176, 0.26) 0%, transparent 30%), linear-gradient(180deg, #e6efea 0%, #dce7e2 44%, #d7e2de 100%)",backdropBlur:"18px",backdropSaturate:"180%",panelHighlight:"rgba(255, 255, 255, 0.64)",panelChrome:"rgba(214, 228, 221, 0.42)",buttonHighlight:"rgba(255, 255, 255, 0.54)",inputHighlight:"rgba(255, 255, 255, 0.72)",modalBackdrop:"rgba(52, 63, 57, 0.22)"}},{id:"promptx-aqua-classic",name:"Aqua Classic",shortName:"Aqua",mode:"light",mobileEnabled:!1,description:"复古 macOS Aqua / Snow Leopard 拟物工具台。",swatches:["#d7dee7","#f7f9fb","#9aa9b8","#2f78c4"],colors:{appBg:"#dce3eb",appPanel:"#edf1f5",appPanelMuted:"#dfe6ee",appPanelStrong:"#fbfcfd",appPanelHover:"#e5ebf2",appPanelInset:"#c8d4df",appOverlay:"rgba(238, 244, 250, 0.78)",borderDefault:"#a9b4bf",borderMuted:"#c7d0d9",borderStrong:"#7d8b99",textPrimary:"#111820",textSecondary:"#273441",textMuted:"#5d6874",textInverse:"#ffffff",buttonBg:"#e8edf2",buttonHover:"#f4f8fc",buttonBorder:"#8f9baa",buttonText:"#1d2834",primaryBg:"#2f78c4",primaryHover:"#3d87d2",primaryBorder:"#2468af",primaryText:"#ffffff",inputBg:"#ffffff",inputBorder:"#94a4b4",focusRing:"rgba(47, 120, 196, 0.26)",selectionBg:"#b7d7fb",selectionText:"#102336",accent:"#2f78c4",accentSoft:"#d9ebff",accentText:"#174b83",warning:"#a66f22",warningSoft:"#fff0cf",warningText:"#6c4614",danger:"#b94b4b",dangerSoft:"#ffe2e2",dangerText:"#813131",success:"#2c8a55",successSoft:"#dff3e8",successText:"#1e5c3a",info:"#2f78c4",infoSoft:"#d9ebff",infoText:"#174b83",promptBg:"#f7efe4",promptBorder:"#c9a46f",promptText:"#4d3921",processBg:"#eef2f6",processBorder:"#b8c3cf",processText:"#2a3642",responseBg:"#e1effb",responseBorder:"#8eb7dc",responseText:"#173f63",codeBg:"#f6f8fb",codeBorder:"#b9c4cf",shadowPanel:"0 10px 24px rgba(54, 68, 82, 0.12)",shadowPopover:"0 14px 34px rgba(42, 54, 68, 0.18)",shellGradient:"linear-gradient(180deg, #edf1f5 0%, #dde4eb 46%, #d2dae3 100%)",backdropBlur:"0px",backdropSaturate:"100%",panelHighlight:"rgba(255, 255, 255, 0.68)",panelChrome:"rgba(139, 153, 168, 0.16)",buttonHighlight:"rgba(255, 255, 255, 0.66)",inputHighlight:"rgba(255, 255, 255, 0.84)",modalBackdrop:"rgba(22, 31, 42, 0.32)"}},{id:"promptx-stone-dark",name:"Stone Dark",shortName:"Stone Dark",mode:"dark",description:"延续当前工作台气质的深色主题。",swatches:["#211d1a","#2b2723","#5a4f47","#89c4ab"],colors:{appBg:"#211d1a",appPanel:"#2b2723",appPanelMuted:"#26221e",appPanelStrong:"#322d28",appPanelHover:"#36302b",appPanelInset:"#24201d",appOverlay:"rgba(39, 34, 29, 0.82)",borderDefault:"#4c433d",borderMuted:"#403832",borderStrong:"#665b53",textPrimary:"#eee7de",textSecondary:"#cbbfb1",textMuted:"#a89c90",textInverse:"#211d1a",buttonBg:"#35302b",buttonHover:"#3d3731",buttonBorder:"#5a4f47",buttonText:"#ebe2d8",primaryBg:"#d7d0c5",primaryHover:"#e4ddd2",primaryBorder:"#d7d0c5",primaryText:"#211d1a",inputBg:"#28231f",inputBorder:"#5a4f47",focusRing:"rgba(156, 141, 125, 0.28)",selectionBg:"#62574f",selectionText:"#f8f5ef",accent:"#78bda1",accentSoft:"#2b3a33",accentText:"#e0f0e8",warning:"#d1aa74",warningSoft:"#413428",warningText:"#f2dfbd",danger:"#cb8882",dangerSoft:"#402927",dangerText:"#f1e0dc",success:"#95c6a1",successSoft:"#2a382e",successText:"#eef7ef",info:"#97b8e1",infoSoft:"#273644",infoText:"#dde9fa",promptBg:"#584637",promptBorder:"#97765b",promptText:"#f8ecdc",processBg:"#25211e",processBorder:"#4d453f",processText:"#c4b8ab",responseBg:"#2b3a31",responseBorder:"#708f7b",responseText:"#eef7ef",codeBg:"#26211e",codeBorder:"#403832",shadowPanel:"0 18px 42px rgba(0, 0, 0, 0.28)",shadowPopover:"0 24px 56px rgba(0, 0, 0, 0.4)"}},{id:"github-light",name:"GitHub Light",shortName:"GitHub Light",mode:"light",description:"清爽、克制,适合评审和协作场景。",swatches:["#f6f8fa","#ffffff","#d0d7de","#0969da"],colors:{appBg:"#f6f8fa",appPanel:"#ffffff",appPanelMuted:"#f6f8fa",appPanelStrong:"#ffffff",appPanelHover:"#f3f4f6",appPanelInset:"#eef2f6",appOverlay:"rgba(255, 255, 255, 0.86)",borderDefault:"#d0d7de",borderMuted:"#d8dee4",borderStrong:"#afb8c1",textPrimary:"#000000",textSecondary:"#2b3138",textMuted:"#505962",textInverse:"#ffffff",buttonBg:"#f6f8fa",buttonHover:"#eef2f6",buttonBorder:"#d0d7de",buttonText:"#111418",primaryBg:"#24292f",primaryHover:"#363b42",primaryBorder:"#24292f",primaryText:"#ffffff",inputBg:"#ffffff",inputBorder:"#d0d7de",focusRing:"rgba(9, 105, 218, 0.18)",selectionBg:"#cce5ff",selectionText:"#0b1f33",accent:"#0969da",accentSoft:"#ddf4ff",accentText:"#0550ae",warning:"#9a6700",warningSoft:"#fff8c5",warningText:"#7d4e00",danger:"#cf222e",dangerSoft:"#ffebe9",dangerText:"#a40e26",success:"#1a7f37",successSoft:"#dafbe1",successText:"#116329",info:"#0969da",infoSoft:"#ddf4ff",infoText:"#0550ae",promptBg:"#fff1db",promptBorder:"#d4a458",promptText:"#6b4b16",processBg:"#f6f8fa",processBorder:"#d8dee4",processText:"#30363d",responseBg:"#eaf5ff",responseBorder:"#9ecbff",responseText:"#0a3069",codeBg:"#f6f8fa",codeBorder:"#d8dee4",shadowPanel:"0 12px 34px rgba(31, 35, 40, 0.08)",shadowPopover:"0 16px 42px rgba(31, 35, 40, 0.16)"}},{id:"promptx-wechat-light",name:"WeChat Light",shortName:"WeChat",mode:"light",description:"偏微信桌面端的轻白、浅灰、绿色强调主题。",swatches:["#ededed","#ffffff","#e5e5e5","#07c160"],colors:{appBg:"#ececec",appPanel:"#ffffff",appPanelMuted:"#f0f0f0",appPanelStrong:"#ffffff",appPanelHover:"#e7e7e7",appPanelInset:"#e4f7ee",appOverlay:"rgba(255, 255, 255, 0.82)",borderDefault:"#d0d0d0",borderMuted:"#e0e0e0",borderStrong:"#d8d8d8",textPrimary:"#000000",textSecondary:"#1f1f1f",textMuted:"#666666",textInverse:"#ffffff",buttonBg:"#ffffff",buttonHover:"#f2f2f2",buttonBorder:"#dfdfdf",buttonText:"#1f1f1f",primaryBg:"#18ac71",primaryHover:"#159865",primaryBorder:"#18ac71",primaryText:"#ffffff",inputBg:"#f7f7f7",inputBorder:"#e1e1e1",focusRing:"rgba(24, 172, 113, 0.16)",selectionBg:"#cfe2ff",selectionText:"#102a43",accent:"#18ac71",accentSoft:"#ddf5ea",accentText:"#0d7348",warning:"#b88230",warningSoft:"#fbf1df",warningText:"#7a5621",danger:"#cf4f4f",dangerSoft:"#fdeaea",dangerText:"#983434",success:"#18ac71",successSoft:"#ddf5ea",successText:"#0d7348",info:"#2563a6",infoSoft:"#eaf2fb",infoText:"#194878",promptBg:"#ddf5ea",promptBorder:"#18ac71",promptText:"#1f1f1f",processBg:"#ffffff",processBorder:"#ebebeb",processText:"#1f1f1f",responseBg:"#eeeef0",responseBorder:"#dddddf",responseText:"#1f1f1f",codeBg:"#f7f7f7",codeBorder:"#d8d8d8",shadowPanel:"0 1px 2px rgba(0, 0, 0, 0.04)",shadowPopover:"0 12px 28px rgba(0, 0, 0, 0.12)",shellGradient:"linear-gradient(180deg, #ededed 0%, #ededed 100%)",backdropBlur:"0px",backdropSaturate:"100%",panelHighlight:"rgba(255, 255, 255, 0)",panelChrome:"rgba(255, 255, 255, 0)",buttonHighlight:"rgba(255, 255, 255, 0)",inputHighlight:"rgba(255, 255, 255, 0)",modalBackdrop:"rgba(0, 0, 0, 0.28)"}},{id:"promptx-ink-landscape",name:"Ink Mist",shortName:"Ink Mist",mode:"light",mobileEnabled:!1,description:"冷雾底色、墨青层次和卷轴感留白,像一张浮在山岚上的工作台。",swatches:["#e8ecef","#f5f8fa","#aeb8c2","#465d70"],colors:{appBg:"#e8ecef",appPanel:"#f5f8fa",appPanelMuted:"#eef2f5",appPanelStrong:"#fbfdff",appPanelHover:"#e4eaee",appPanelInset:"#d7dfe6",appOverlay:"rgba(240, 245, 248, 0.44)",borderDefault:"#b4bec8",borderMuted:"#cfd8df",borderStrong:"#8c98a4",textPrimary:"#000000",textSecondary:"#2b3944",textMuted:"#56636d",textInverse:"#f8fbfd",buttonBg:"rgba(245, 248, 250, 0.42)",buttonHover:"rgba(233, 239, 243, 0.74)",buttonBorder:"rgba(140, 152, 164, 0.56)",buttonText:"#1d2830",primaryBg:"#1f262d",primaryHover:"#2a343d",primaryBorder:"#1f262d",primaryText:"#f7fafc",inputBg:"rgba(251, 253, 255, 0.5)",inputBorder:"rgba(145, 157, 168, 0.54)",focusRing:"rgba(70, 93, 112, 0.18)",selectionBg:"#d4dde4",selectionText:"#172026",accent:"#465d70",accentSoft:"#dfe8ee",accentText:"#2c4455",warning:"#8f7356",warningSoft:"#f1e8dd",warningText:"#614830",danger:"#85545c",dangerSoft:"#efe1e4",dangerText:"#5d3239",success:"#547268",successSoft:"#e2ebe7",successText:"#334d44",info:"#465d70",infoSoft:"#dfe8ee",infoText:"#2c4455",promptBg:"#ece1d5",promptBorder:"#c5ab93",promptText:"#533e30",processBg:"#eaf0f2",processBorder:"#c1ccd3",processText:"#2f3c46",responseBg:"#dfe7ec",responseBorder:"#a4b4c0",responseText:"#2a3e4d",codeBg:"#eef3f6",codeBorder:"#ced7de",shadowPanel:"0 18px 44px rgba(23, 29, 34, 0.08)",shadowPopover:"0 26px 60px rgba(18, 24, 29, 0.16)",shellGradient:"radial-gradient(circle at 14% 10%, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.12) 18%, transparent 44%), radial-gradient(circle at 82% 8%, rgba(100, 119, 133, 0.16) 0%, transparent 30%), radial-gradient(circle at 70% 72%, rgba(154, 166, 174, 0.12) 0%, transparent 26%), linear-gradient(180deg, #eef2f5 0%, #e7ecef 44%, #dfe5e9 100%)",backdropBlur:"18px",backdropSaturate:"112%",panelHighlight:"rgba(255, 255, 255, 0.18)",panelChrome:"rgba(90, 103, 114, 0.08)",buttonHighlight:"rgba(255, 255, 255, 0.08)",inputHighlight:"rgba(255, 255, 255, 0.12)",modalBackdrop:"rgba(17, 21, 24, 0.42)"}},{id:"tokyo-night",name:"Tokyo Night",shortName:"Tokyo Night",mode:"dark",description:"更接近编辑器气质的冷调深色主题。",swatches:["#202432","#272c3f","#4d567a","#89aef7"],colors:{appBg:"#202432",appPanel:"#272c3f",appPanelMuted:"#222638",appPanelStrong:"#2e3449",appPanelHover:"#343a52",appPanelInset:"#1f2333",appOverlay:"rgba(39, 44, 63, 0.84)",borderDefault:"#4d567a",borderMuted:"#434b6b",borderStrong:"#626c97",textPrimary:"#d6dcf6",textSecondary:"#aeb7da",textMuted:"#9098bb",textInverse:"#171a23",buttonBg:"#2b3045",buttonHover:"#343955",buttonBorder:"#4d567a",buttonText:"#d8def8",primaryBg:"#89aef7",primaryHover:"#9bbcff",primaryBorder:"#89aef7",primaryText:"#171a23",inputBg:"#202433",inputBorder:"#4d567a",focusRing:"rgba(137, 174, 247, 0.24)",selectionBg:"#42578e",selectionText:"#e7edff",accent:"#89aef7",accentSoft:"#2a3956",accentText:"#e3ecff",warning:"#d9b07a",warningSoft:"#433734",warningText:"#f4dfbf",danger:"#e28a9a",dangerSoft:"#472b39",dangerText:"#ffe1e7",success:"#a9cf81",successSoft:"#2c3a31",successText:"#e5f5d0",info:"#8fcff4",infoSoft:"#284254",infoText:"#ddf3ff",promptBg:"#4b4368",promptBorder:"#9385c8",promptText:"#f2ecff",processBg:"#232739",processBorder:"#474f73",processText:"#b5bde0",responseBg:"#294155",responseBorder:"#629ec0",responseText:"#e0f1ff",codeBg:"#232739",codeBorder:"#474f73",shadowPanel:"0 20px 48px rgba(9, 12, 24, 0.34)",shadowPopover:"0 24px 62px rgba(5, 8, 18, 0.44)"}}],H=Object.fromEntries(z.map(e=>[e.id,e])),m=S(T),L=S(!1);let w=null,v=null;function De(){return typeof window>"u"||typeof window.matchMedia!="function"?!1:window.matchMedia("(max-width: 1023px)").matches}function M(){return typeof window>"u"||typeof window.matchMedia!="function"?T:window.matchMedia("(prefers-color-scheme: dark)").matches?"promptx-stone-dark":T}function k(e=""){return H[String(e||"").trim()]||H[T]}function K(e){return e?De()?e.mobileEnabled!==!1:!0:!1}function h(e=""){const t=k(e);return K(t)?t:k(T)}function x(e){if(typeof document>"u"||!e)return;const t=document.documentElement;t.dataset.theme=e.id,t.classList.toggle("dark",e.mode==="dark"),t.style.colorScheme=e.mode,Object.entries(e.colors||{}).forEach(([n,o])=>{t.style.setProperty(`--theme-${n}`,String(o))})}function Re(){var o,r;if(typeof window>"u")return h(T);const e=window.localStorage.getItem(C),t=k(e||M()),n=h(t.id);return m.value=t.id,x(n),window.localStorage.setItem(C,t.id),L.value=!0,!w&&typeof window.matchMedia=="function"&&(w=window.matchMedia("(prefers-color-scheme: dark)"),(o=w.addEventListener)==null||o.call(w,"change",()=>{if(window.localStorage.getItem(C))return;const i=k(M());m.value=i.id,x(h(i.id))})),!v&&typeof window.matchMedia=="function"&&(v=window.matchMedia("(max-width: 1023px)"),(r=v.addEventListener)==null||r.call(v,"change",()=>{x(h(m.value))})),n}function $e(){const e=f(()=>h(m.value)),t=f(()=>e.value.mode==="dark"),n=f(()=>z.filter(r=>K(r)));function o(r){const i=k(r);m.value=i.id,typeof window<"u"&&window.localStorage.setItem(C,i.id),x(h(i.id)),L.value=!0}return{currentTheme:e,isDark:t,setTheme:o,themeId:m,themeReady:L,themes:n}}const d={ENTER:"enter",SHIFT_ENTER:"shift_enter",BUTTON_ONLY:"button_only"},Ae=[{value:d.ENTER,labelKey:"settingsDialog.general.sendBehavior.options.enter.label",descriptionKey:"settingsDialog.general.sendBehavior.options.enter.description"},{value:d.SHIFT_ENTER,labelKey:"settingsDialog.general.sendBehavior.options.shiftEnter.label",descriptionKey:"settingsDialog.general.sendBehavior.options.shiftEnter.description"},{value:d.BUTTON_ONLY,labelKey:"settingsDialog.general.sendBehavior.options.buttonOnly.label",descriptionKey:"settingsDialog.general.sendBehavior.options.buttonOnly.description"}],s={SEND_BEHAVIOR:"sendBehavior",NOTIFICATION_SOUND_ENABLED:"notificationSoundEnabled"},c={CLIENT:"client",SERVER:"server"},U="promptx:workbench-preferences",_={[s.SEND_BEHAVIOR]:{key:s.SEND_BEHAVIOR,section:"general",storage:c.CLIENT,defaultValue:d.SHIFT_ENTER},[s.NOTIFICATION_SOUND_ENABLED]:{key:s.NOTIFICATION_SOUND_ENABLED,section:"general",storage:c.CLIENT,defaultValue:!1}},V={[c.CLIENT]:{loadAll(){if(typeof window>"u")return{};try{const e=JSON.parse(window.localStorage.getItem(U)||"{}");return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}},saveAll(e={}){typeof window>"u"||window.localStorage.setItem(U,JSON.stringify(e))}},[c.SERVER]:{loadAll(){return{}},saveAll(){}}},b=S(G()),$=S(!1);function G(){return{[s.SEND_BEHAVIOR]:_[s.SEND_BEHAVIOR].defaultValue,[s.NOTIFICATION_SOUND_ENABLED]:_[s.NOTIFICATION_SOUND_ENABLED].defaultValue}}function Y(e=""){const t=String(e||"").trim().toLowerCase();return t===d.ENTER?d.ENTER:t===d.BUTTON_ONLY?d.BUTTON_ONLY:d.SHIFT_ENTER}function Ee(e=!1){if(typeof e=="string"){const t=String(e).trim().toLowerCase();if(["1","true","on","yes"].includes(t))return!0;if(["0","false","off","no",""].includes(t))return!1}return!!e}function J(e={}){return{[s.SEND_BEHAVIOR]:Y(e==null?void 0:e[s.SEND_BEHAVIOR]),[s.NOTIFICATION_SOUND_ENABLED]:Ee(e==null?void 0:e[s.NOTIFICATION_SOUND_ENABLED])}}function W(e=c.CLIENT){var t,n;return((n=(t=V[e])==null?void 0:t.loadAll)==null?void 0:n.call(t))||{}}function Z(e=c.CLIENT,t={}){var n,o;(o=(n=V[e])==null?void 0:n.saveAll)==null||o.call(n,t)}function Q(){const e=G(),t=W(c.CLIENT),n=W(c.SERVER),o=J({...e,...t,...n});return b.value=o,Z(c.CLIENT,o),$.value=!0,o}function ee(e=""){return _[String(e||"").trim()]||null}function F(e=""){const t=ee(e);if(t)return b.value[t.key]}function Be(e="",t){const n=ee(e);if(!n)return b.value;const o=J({...b.value,[n.key]:t});b.value=o;const r=n.storage||c.CLIENT;return r===c.CLIENT&&Z(r,o),$.value=!0,o}function Oe(e,t={}){const n=String((e==null?void 0:e.key)||""),o=Y(t==null?void 0:t.sendBehavior);return n!=="Enter"||t!=null&&t.isComposing||!(t!=null&&t.isEditing)||e!=null&&e.metaKey||e!=null&&e.ctrlKey||e!=null&&e.altKey||o===d.BUTTON_ONLY?!1:o===d.ENTER?!(e!=null&&e.shiftKey):!!(e!=null&&e.shiftKey)}function je(){const e=f(()=>b.value),t=f(()=>F(s.SEND_BEHAVIOR)),n=f(()=>F(s.NOTIFICATION_SOUND_ENABLED));return{preferences:e,sendBehavior:t,notificationSoundEnabled:n,workbenchPreferencesReady:$,initializeWorkbenchPreferences:Q,getPreference:F,setPreference:Be}}Re();Ce();Q();de(be).use(we).mount("#app");export{s as W,Se as _,fe as a,$e as b,je as c,Ae as d,Le as e,Ie as f,X as g,Oe as s,I as t,_e as u};
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>PromptX</title>
7
7
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
8
- <script type="module" crossorigin src="/assets/index-Ch8uSQYT.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-HLkdzIYF.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/vendor-misc-u-M8sNMf.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/vendor-router-Dn8q3tJM.js">
11
11
  <link rel="stylesheet" crossorigin href="/assets/vendor-misc-ClI1dyrl.css">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muyichengshayu/promptx",
3
- "version": "0.2.12",
3
+ "version": "0.2.13",
4
4
  "description": "PromptX 本机 AI 协作工作台",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -152,7 +152,7 @@ async function startRelayService() {
152
152
  return
153
153
  }
154
154
 
155
- const { pidFile, stateFile, logFile } = getRuntimePaths()
155
+ const { pidFile, stateFile, logDir, logFile } = getRuntimePaths()
156
156
  const host = String(process.env.PROMPTX_RELAY_HOST || process.env.HOST || DEFAULT_RELAY_HOST).trim() || DEFAULT_RELAY_HOST
157
157
  const port = Math.max(1, Number(process.env.PROMPTX_RELAY_PORT || process.env.PORT) || DEFAULT_RELAY_PORT)
158
158
  const baseUrl = getBaseUrl(host, port)