@jetcrab/pi-desk 1.1.31-dev → 1.1.32-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +24 -10
  2. package/README.zh-CN.md +24 -10
  3. package/package.json +1 -1
  4. package/src/client/l2_biz/workbench/hooks/l2-workbench-model-context.ts +39 -7
  5. package/src/client/l2_biz/workbench/l2-workbench-model-context-dialog.tsx +7 -8
  6. package/src/client/l2_biz/workbench/native-ui/l2-native-ui-mcp.tsx +66 -99
  7. package/src/client/l2_biz/workbench/native-ui/l2-native-ui-notices.tsx +2 -2
  8. package/src/client/l2_biz/workbench/native-ui/l2-native-ui-view.tsx +5 -2
  9. package/src/client/l4_foundation/desktop-window/l4-desktop-titlebar.tsx +8 -15
  10. package/src/client/l4_foundation/desktop-window/l4-desktop-window.css +0 -4
  11. package/src/common/l2_biz/workbench/l2-workbench-locale-messages.ts +12 -16
  12. package/src/common/l4_foundation/locale/l4-host-error-messages.ts +0 -2
  13. package/src/server/l1_entry/api/l1-chat-context-get-route.ts +0 -4
  14. package/src/server/l4_foundation/pi/l4-pi-chat-worker.ts +0 -19
  15. package/src/server/l4_foundation/pi/l4-pi-mcp-command.ts +48 -0
  16. package/src/server/l4_foundation/pi/l4-pi-session-resources.ts +11 -2
  17. package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
  18. package/temp/build/pi-desk/release/.next/build-manifest.json +2 -2
  19. package/temp/build/pi-desk/release/.next/required-server-files.js +2 -2
  20. package/temp/build/pi-desk/release/.next/required-server-files.json +2 -2
  21. package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  22. package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
  23. package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +1 -1
  24. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  25. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  26. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  27. package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  28. package/temp/build/pi-desk/release/.next/server/app/api/chat/context/get/route.js +1 -1
  29. package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
  30. package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
  31. package/temp/build/pi-desk/release/.next/server/app/page.js +2 -2
  32. package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
  33. package/temp/build/pi-desk/release/.next/server/app/project-preview/page_client-reference-manifest.js +1 -1
  34. package/temp/build/pi-desk/release/.next/server/chunks/25406.js +11 -11
  35. package/temp/build/pi-desk/release/.next/server/chunks/35985.js +1 -1
  36. package/temp/build/pi-desk/release/.next/server/chunks/92386.js +10 -10
  37. package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
  38. package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
  39. package/temp/build/pi-desk/release/.next/static/chunks/11937-d5d4d2199356c3ed.js +1 -0
  40. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-fdea504082053156.js +1 -0
  41. package/temp/build/pi-desk/release/.next/static/chunks/app/{page-f42381b1eed4310d.js → page-20eb04ea250423e4.js} +6 -6
  42. package/temp/build/pi-desk/release/.next/static/css/e44d06d81c9535c0.css +1 -0
  43. package/temp/build/pi-desk/release/.next/trace-build +1 -1
  44. package/temp/build/pi-desk/release/.next/static/chunks/11937-ac71fb0f7cef482a.js +0 -1
  45. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-ca5ef5994165eb2e.js +0 -1
  46. package/temp/build/pi-desk/release/.next/static/css/3c59ac068ae404da.css +0 -1
  47. /package/temp/build/pi-desk/release/.next/static/{SUWCp0trQPQnnw0za1R_Y → OKkvmSoIKvwTgI3I2x3yp}/_buildManifest.js +0 -0
  48. /package/temp/build/pi-desk/release/.next/static/{SUWCp0trQPQnnw0za1R_Y → OKkvmSoIKvwTgI3I2x3yp}/_ssgManifest.js +0 -0
@@ -3,18 +3,18 @@
3
3
  ${e(i)}`)}if("required"===i.scope&&void 0===b)throw Error(`必须指定 --scope global
4
4
  ${e(i)}`);if(void 0!==b&&"global"!==b)throw Error("当前插件管理只支持 global 范围,不支持项目级操作");if(i.name){if(0===j.length)throw Error(`缺少插件名字
5
5
  ${e(i)}`);for(let a of j)if(!/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(a)||"node_modules"===a)throw Error(`插件名字必须是扩展名字或完整 npm 包名,不接受路径或内嵌版本号:${a}`)}if(void 0!==c&&!/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/.test(c))throw Error("--version 必须是完整版本号,例如 1.2.3;版本可省略");if(void 0!==g&&(g.length>128||!/^[a-zA-Z][a-zA-Z0-9._-]*$/.test(g)))throw Error("--tag 必须是有效的渠道标签,例如 latest 或 dev");if(void 0!==g&&void 0!==c)throw Error("--tag 与 --version 互斥,不能同时指定");return"--version"===i.path[0]?{kind:"version"}:"info"===i.path[0]?{kind:"info"}:"session"===i.path[0]?{kind:"session",action:"reload"}:{kind:"plugins",action:i.path[1],...1===j.length?{name:j[0]}:j.length>1?{names:j}:{},...void 0===c?{}:{version:c},...void 0===g?{}:{tag:g},...void 0===h?{}:{checkUpdates:h}}}},2476:(a,b,c)=>{c.d(b,{N:()=>l,l:()=>i});var d=c(77598),e=c(51455),f=c(76760);let g=new Set([".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs",".json",".md",".css",".yaml",".yml",".toml",".wasm",".node"]),h=new Set(["node_modules","temp","logs","coverage"]);class i extends Error{constructor(a){super(`插件来源不存在:${a}`),this.source=a,this.name="L4PiPluginSourceNotFoundError"}}async function j(a){let b=(0,d.createHash)("sha256").update(JSON.stringify({path:a.path,enabled:a.enabled,nativePaths:[...a.nativePaths].sort(),piDeskRoot:a.piDeskRoot,hasPiResources:a.hasPiResources}));if(!a.path||a.error||!a.enabled)return b.update(a.error??"").digest("hex");let c=await (0,e.realpath)(a.path),i=0,j=0,k=async(a,d,l)=>{if(++j>8192)throw Error("源码目录条目超过8192项,请使用独立插件目录");let m=await (0,e.realpath)(a),n=(0,f.relative)(c,m);if(n.startsWith("..")||(0,f.isAbsolute)(n))return;let o=await (0,e.stat)(m);if(o.isDirectory()){if(l.has(m))throw Error("源码目录存在符号链接循环");let a=new Set(l).add(m);for(let b of(await (0,e.readdir)(m,{withFileTypes:!0})).sort((a,b)=>a.name.localeCompare(b.name)))b.name.startsWith(".")||h.has(b.name)||await k((0,f.join)(m,b.name),`${d}/${b.name}`,a)}else if(o.isFile()&&(""===d||g.has((0,f.extname)(d)))){if(o.size>0x1000000||i+o.size>0x4000000)throw Error("源码指纹内容超过容量上限");let a=await (0,e.readFile)(m),c=await (0,e.stat)(m);if(c.size!==o.size||c.mtimeMs!==o.mtimeMs||a.length!==o.size)throw Error("插件源码正在变化,请保存或构建完成后重新加载");i+=a.length,b.update(d).update("\0").update(a).update("\0")}};return await k(c,"",new Set),b.digest("hex")}async function k(a){try{return{source:a,fingerprint:await j(a)}}catch(c){let b={...a,error:c instanceof Error?c.message:String(c)};return{source:b,fingerprint:`failed:${b.error}`}}}class l{async initialize(a){for(let b of(this.applied.clear(),a.sources))this.applied.set(b.source,await k(b))}async scan(a,b){let c=new Map(a.sources.map(a=>[a.source,a])),d=b?[...new Set(b)]:[...new Set([...this.applied.keys(),...c.keys()])],e=[];for(let f of d){let d=this.applied.get(f),g=c.get(f);if(!d&&!g)throw new i(f);if(!g&&a.errors.length>0){if(b)throw Error(`来源发现不完整,不能确认已删除:${f}`);continue}let h=g?await k(g):null;(b||d?.fingerprint!==h?.fingerprint)&&e.push({source:f,previous:d?.source??null,current:h?.source??null,fingerprint:h?.fingerprint??null})}return e}commit(a){a.current&&null!==a.fingerprint?this.applied.set(a.source,{source:a.current,fingerprint:a.fingerprint}):this.applied.delete(a.source)}constructor(){this.applied=new Map}}},5782:(a,b,c)=>{c.d(b,{l:()=>g});var d=c(77598),e=c(73024),f=c(76760);function g(a){let b=a.getSessionFile();if(!b)throw Error("Persisted Pi session is missing a session file");if((0,e.existsSync)(b))return b;let c=a.getHeader();if(!c||c.id!==a.getSessionId())throw Error(`Pi session ${a.getSessionId()} has an invalid header`);(0,e.mkdirSync)((0,f.dirname)(b),{recursive:!0});let g=`${[c,...a.getEntries()].map(a=>JSON.stringify(a)).join("\n")}
6
- `,h=`${b}.${(0,d.randomUUID)()}.tmp`;try{(0,e.writeFileSync)(h,g,{encoding:"utf8",flag:"wx"});try{(0,e.linkSync)(h,b)}catch(a){if("EEXIST"!==a.code)throw a}}finally{(0,e.existsSync)(h)&&(0,e.unlinkSync)(h)}if(!(0,e.existsSync)(b))throw Error(`Failed to materialize Pi session: ${a.getSessionId()}`);return b}},9753:(a,b,c)=>{c.d(b,{LO:()=>d.L,Nb:()=>e.Nb,Nx:()=>e.Nx,O0:()=>e.O0,Sl:()=>e.Sl,k0:()=>e.k0}),c(47511),c(41904);var d=c(41966),e=c(85273)},12727:(a,b,c)=>{c.d(b,{B4:()=>x,Wl:()=>r,b7:()=>u,xf:()=>z,xm:()=>y,zG:()=>k,zK:()=>v,zz:()=>l});var d=c(54174);let e=new Intl.NumberFormat("en-US",{maximumFractionDigits:0});function f(a){if("string"!=typeof a)return null;let b=a.replace(/\s+/g," ").trim();return b?b.length<=500?b:`${b.slice(0,499)}…`:null}function g(a,...b){for(let c of b){let b=f(a[c]);if(b)return b}return null}function h(a,b){let c=a[b];return"number"==typeof c&&Number.isSafeInteger(c)&&c>=0?c:null}function i(a){if(0===a.length)return 0;let b=1;for(let c of a)"\n"===c&&(b+=1);return b}function j(a){let b=0;for(let c of a)b+=1;return b}function k(a,b,c){return{reasoning:f(b.reasoning),inputPreview:function(a,b){switch(a.toLowerCase().split(".").at(-1)??a.toLowerCase()){case"bash":return g(b,"command");case"read":case"write":case"edit":return g(b,"path","file_path");case"grep":{let a=g(b,"pattern","query"),c=g(b,"path");return a&&c?f(`${a} \xb7 ${c}`):a??c}case"find":return g(b,"pattern","path");case"ls":return g(b,"path");case"agent":return g(b,"description");case"agent_resume":return g(b,"description","prompt");default:return g(b,"command","path","file_path","pattern","query","description","prompt")}}(a,b),activity:function(a,b,c){switch(a.toLowerCase().split(".").at(-1)??a.toLowerCase()){case"read":let d=h(b,"offset"),f=h(b,"limit");if(null!==f){let a=d??1;return`${a}-${a+Math.max(0,f-1)}`}return null===d?null:`${d}-`;case"write":return function(a,b){let c,d,f=a.content;if("string"!=typeof f)return null;let g=b?.writeContent;if(b&&void 0!==g&&void 0!==b.writeCharacters&&void 0!==b.writeLines&&f.startsWith(g)){let a=f.slice(g.length);0===a.length?(c=b.writeCharacters,d=b.writeLines):(c=b.writeCharacters+j(a),d=b.writeLines+i(a)-(0!==g.length))}else c=j(f),d=i(f);return b&&(b.writeContent=f,b.writeCharacters=c,b.writeLines=d),`${e.format(c)} \xb7 L${e.format(d)}`}(b,c);case"edit":return function(a){let b=Array.isArray(a.edits)?a.edits.filter(a=>null!==a&&"object"==typeof a&&!Array.isArray(a)):"string"==typeof a.oldText||"string"==typeof a.newText?[a]:[];if(0===b.length)return null;let c=0,d=0,f=!1,g=!1;for(let a of b)"string"==typeof a.oldText&&(f=!0,c+=i(a.oldText)),"string"==typeof a.newText&&(g=!0,d+=i(a.newText));let h=[...f?[`-${e.format(c)}`]:[],...g?[`+${e.format(d)}`]:[]].join(" ");return h?`${e.format(b.length)} \xb7 ${h}`:e.format(b.length)}(b);default:return null}}(a,b,c)}}function l(a){if(!Array.isArray(a))return[];let b=[];for(let c of a){if(!c||"object"!=typeof c||"toolCall"!==c.type||"string"!=typeof c.id||!c.id||"string"!=typeof c.name||!c.name)continue;let a=c.arguments&&"object"==typeof c.arguments&&!Array.isArray(c.arguments)?c.arguments:{};b.push({id:c.id,name:c.name,input:a})}return b}function m(a){try{let b=JSON.stringify(a);return void 0===b?null:JSON.parse(b)}catch{return null}}function n(a){let b=m(a);return b&&"object"==typeof b&&!Array.isArray(b)?b:{}}function o(a){return"string"==typeof a?a:Array.isArray(a)?a.flatMap(a=>a&&"object"==typeof a&&"text"===a.type&&"string"==typeof a.text?[a.text]:[]).join("\n"):""}function p(a){return Array.isArray(a)?a.flatMap(a=>{if(!a||"object"!=typeof a||"image"!==a.type||"string"!=typeof a.data)return[];try{return[{data:a.data,metadata:(0,d.Z)(a.data).metadata}]}catch(a){return console.warn("[Pi Desk][PiChatProjection] 已忽略损坏的历史图片",{errorName:a instanceof Error?a.name:"UnknownError"}),[]}}):[]}function q(a){return p(a).map(a=>a.metadata)}function r(a,b){let c=p(a)[b];return c?{mimeType:c.metadata.mimeType,data:c.data}:null}function s(a,b){return Array.isArray(a)?a.flatMap(a=>{if(!a||"object"!=typeof a||a.type!==b)return[];let c="text"===b?a.text:a.thinking;return"string"==typeof c?[c]:[]}).join("\n"):""}function t(a){return a?{inputTokens:a.input,outputTokens:a.output,cacheReadTokens:a.cacheRead,costUsd:a.cost.total}:null}function u(a,b,c){switch(a.role){case"user":{let b=o(a.content),c=q(a.content);return{type:"user",text:b,images:c,declaration:{message:{kind:"user",text:b,images:c},raw:a}}}case"assistant":{b&&function(a,b,c){for(let d of l(a))b.set(d.id,k(d.name,d.input)),c?.set(d.id,{...d.input})}(a.content,b,c);let d=s(a.content,"text"),e=s(a.content,"thinking");return{type:"assistant",text:d,thinking:e,model:"pi-virtual"!==a.api&&"string"==typeof a.provider&&"string"==typeof(a.responseModel??a.model)?{provider:a.provider,modelId:a.responseModel??a.model}:null,status:function(a){switch(a){case"pending":return"running";case"stop":case"length":case"toolUse":return"completed";case"aborted":return"aborted";default:return"error"}}(a.stopReason),errorMessage:a.errorMessage??null,usage:t(a.usage),declaration:{message:{kind:"assistant",text:d,thinking:e,stopReason:a.stopReason},raw:a}}}case"toolResult":{let d=b?.get(a.toolCallId),e=c?.get(a.toolCallId);b?.delete(a.toolCallId),c?.delete(a.toolCallId);let f=o(a.content),g=q(a.content),h=a.nestedCalls?{complete:a.nestedCalls.complete,calls:a.nestedCalls.calls.map(a=>({name:a.name,...void 0===a.arguments?{}:{arguments:n(a.arguments)},...void 0===a.argumentsBytes?{}:{argumentsBytes:a.argumentsBytes},status:a.status,...void 0===a.durationMs?{}:{durationMs:a.durationMs},...void 0===a.error?{}:{error:a.error}}))}:null;return{type:"tool",name:a.toolName,reasoning:d?.reasoning??null,inputPreview:d?.inputPreview??null,activity:d?.activity??null,status:a.isError?"error":"completed",usage:t(a.usage),output:f,...g.length>0?{images:g}:{},...h?{nestedCalls:h}:{},startedAtMs:null,durationMs:function(a,b){if("bash"!==a||!b||"object"!=typeof b||Array.isArray(b))return null;let c=b.durationMs;return"number"==typeof c&&Number.isSafeInteger(c)&&c>=0?c:null}(a.toolName,a.details),declaration:{message:{kind:"tool",toolName:a.toolName,toolCallId:a.toolCallId,arguments:n(e),partialResult:null,result:m({content:a.content,details:a.details,output:f}),isError:a.isError},raw:a}}}case"bashExecution":return{type:"bash",command:a.command,status:a.cancelled?"aborted":0===a.exitCode?"completed":"error",output:a.output,declaration:{message:{kind:"bash",command:a.command,output:a.output,exitCode:a.exitCode??null,cancelled:a.cancelled,truncated:a.truncated},raw:a}};case"custom":{if(!a.display)return null;let b=o(a.content);return{type:"custom",text:b,declaration:{message:{kind:"custom",customType:a.customType,content:b,details:m(a.details)},raw:a}}}default:return null}}function v(a,b,c,d){let e=new Map,f=new Map;return c&&e.set(b,c),d&&f.set(b,d),u(a,e,f)}function w(a,b,c){let d="message"===a.type?u(a.message,b,c):"custom_message"===a.type?function(a){if(!a.display)return null;let b=o(a.content);return{type:"custom",text:b,declaration:{message:{kind:"custom",customType:a.customType,content:b,details:m(a.details)},raw:a}}}(a):"compaction"===a.type?{type:"compaction",summary:a.summary,declaration:{message:{kind:"custom",customType:"pi-desk/compaction",content:"",details:{text:a.summary}},raw:a}}:null;if(!d)return null;let e=Date.parse(a.timestamp);if(!Number.isSafeInteger(e)||e<0)throw Error(`Pi session entry has an invalid timestamp: ${a.id}`);return{entryId:a.id,timestampMs:e,message:d}}function x(a){return w(a,new Map,new Map)}function y(a,b){let c=[],d=new Map,e=new Map;for(let f of a){let a=w(f,d,e);a&&(c.push(a),void 0!==b&&c.length>b&&c.shift())}return c}function z(a){return{sessionName:a.getSessionName()?.trim()||null,entries:y(a.getBranch())}}},20369:(a,b,c)=>{c.d(b,{HE:()=>e,IS:()=>d.Dl,Wu:()=>d.j0,f$:()=>d.Qg,rY:()=>d.a4});var d=c(47511);function e(a){return Object.fromEntries(Object.entries(a).map(([a,b])=>[a,b.name]))}},23272:(a,b,c)=>{c.d(b,{H:()=>g,k:()=>h});var d=c(77598),e=c(57975),f=c(67062);class g extends Error{constructor(a,b){super(b),this.code=a,this.name="L4PiUiResponseError"}}class h{get hasPending(){return this.pending.size>0}snapshot(){return structuredClone(this.state)}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}bind(a,b){let c=()=>{b()},d=(a,b)=>(c(),this.request(a,b));return{...a,select:async(a,b,c)=>await d({method:"select",title:a,options:b},c),confirm:async(a,b,c)=>await d({method:"confirm",title:a,message:b},c)===!0,input:async(a,b="",c)=>await d({method:"input",title:a,placeholder:b},c),editor:async(a,b="")=>await d({method:"editor",title:a,prefill:b}),notify:(a,b="info")=>{c(),this.active&&this.emit({type:"notify",message:(0,e.stripVTControlCharacters)(a).slice(0,65536),level:b})},setStatus:(a,b)=>{if(c(),!this.active)return;let d={...this.state.statuses};void 0===b?delete d[a]:d[a]=(0,e.stripVTControlCharacters)(b),this.replace({...this.state,statuses:d})},setWidget:(a,b,d)=>{if(c(),!this.active)return;if("function"==typeof b)return void this.emit({type:"notify",level:"warning",message:"该插件挂件需要终端界面,当前仅支持文本挂件。"});let f={...this.state.widgets};void 0===b?delete f[a]:f[a]={lines:b.map(e.stripVTControlCharacters),placement:d?.placement??"aboveEditor"},this.replace({...this.state,widgets:f})},setEditorText:a=>{c(),this.active&&this.emit({type:"editor_text",mode:"replace",text:a.slice(0,65536)})},pasteToEditor:a=>{c(),this.active&&this.emit({type:"editor_text",mode:"paste",text:a.slice(0,65536)})},custom:async()=>{throw c(),Error("当前界面不支持自定义终端组件,请使用插件提供的网页界面。")}}}respond(a){let b=this.pending.get(a.id);if(!b)throw new g(409,"问题已结束或已失效,请查看最新状态");let{request:c}=b;if(null!==c.expiresAt&&c.expiresAt<=Date.now())throw this.finish(a.id,void 0),new g(409,"问题已超时");if(null!==a.value){if("confirm"===c.method?"boolean"!=typeof a.value:"string"!=typeof a.value)throw new g(400,"回答类型不正确");if("select"===c.method&&!c.options.includes(a.value))throw new g(400,"选择的选项已无效")}this.finish(a.id,a.value??void 0)}cancelAll(){let a=[...this.pending.values()];for(let b of(this.pending.clear(),this.state={...this.state,requests:[]},a))b.cleanup();for(let b of(a.length>0&&(this.publishSnapshot(),console.info("[Pi Desk][NativeUI] 已取消待处理交互",{count:a.length})),a))b.resolve(void 0)}reset(a=!0){this.active=a,this.cancelAll(),this.state=(0,f.l3)(),this.publishSnapshot()}dispose(){this.reset(!1),this.listeners.clear()}async waitForOperation(a,b,c){let d,e=b,f=performance.now(),g=()=>void 0,h=new Promise((a,b)=>{g=b}),i=()=>{d&&(e-=performance.now()-f,clearTimeout(d),d=void 0),this.hasPending||(f=performance.now(),d=setTimeout(()=>g(c()),Math.max(0,e)))},j=this.subscribe(a=>{"snapshot"===a.type&&i()});i();try{return await Promise.race([a,h])}finally{d&&clearTimeout(d),j()}}request(a,b){if(!this.active||b?.signal?.aborted)return Promise.resolve(void 0);let c=f.WR.parse({...a,id:(0,d.randomUUID)(),expiresAt:b?.timeout===void 0?null:Date.now()+Math.max(0,b.timeout)}),e={...this.state,requests:[...this.state.requests,c]};return this.validate(e),new Promise(a=>{let d=()=>this.finish(c.id,void 0),f=null===c.expiresAt?void 0:setTimeout(d,Math.max(0,c.expiresAt-Date.now()));b?.signal?.addEventListener("abort",d,{once:!0}),this.pending.set(c.id,{request:c,resolve:a,cleanup:()=>{f&&clearTimeout(f),b?.signal?.removeEventListener("abort",d)}}),this.state=e,this.publishSnapshot()})}finish(a,b){let c=this.pending.get(a);c&&(this.pending.delete(a),c.cleanup(),this.state={...this.state,requests:this.state.requests.filter(b=>b.id!==a)},c.resolve(b),null===this.snapshotImmediate&&(this.snapshotImmediate=setImmediate(()=>{this.snapshotImmediate=null,this.publishSnapshot()})))}validate(a){if(f.P.parse(a),Object.keys(a.statuses).length>32||Object.keys(a.widgets).length>16||Buffer.byteLength(JSON.stringify(a),"utf8")>262144)throw Error("插件交互内容过多,请先清理已有状态或缩短内容")}replace(a){this.validate(a),this.state=a,this.publishSnapshot()}publishSnapshot(){null!==this.snapshotImmediate&&(clearImmediate(this.snapshotImmediate),this.snapshotImmediate=null),this.emit({type:"snapshot",snapshot:this.snapshot()})}emit(a){for(let b of this.listeners)try{b(a)}catch(a){console.error("[Pi Desk][NativeUI] 交互推送失败",{message:a instanceof Error?a.message:String(a)})}}constructor(){this.state=(0,f.l3)(),this.pending=new Map,this.listeners=new Set,this.active=!0,this.snapshotImmediate=null}}},23404:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{O:()=>i});var e=c(28802),f=c(85273),g=c(47511),h=a([e]);e=(h.then?(await h)():h)[0];class i{constructor(a){this.readMode=a,this.registrations=new Map,this.session=null,this.requestedTools=new Set,this.setTools=null,this.originalSetTools=null,this.ready=!1,this.disposed=!1,this.rules=a()}eventBus(a){return{on:(b,c)=>a.on(b,c),emit:(b,c)=>{this.disposed||(b===f.Hj?this.register(c):a.emit(b,c))}}}createHostExtension(a,b){let c="<inline:pi-desk-input-validator>",d=new Map;return d.set("input",[async(b,c)=>a(b,c)]),d.set("tool_call",[async a=>{if(!this.isToolAllowed(a.toolName))return{block:!0,reason:`当前能力模式不允许工具:${a.toolName}`}}]),d.set("session_shutdown",[async()=>{this.ready=!1,this.registrations.clear(),b?.()}]),{path:c,resolvedPath:c,hidden:!0,sourceInfo:{path:c,source:"inline",scope:"temporary",origin:"top-level"},handlers:d,tools:new Map,commands:new Map,flags:new Map,shortcuts:new Map,messageRenderers:new Map}}resources(a){return new Proxy(a,{get:(a,b)=>{if("getSkills"===b)return()=>{let b=a.getSkills();return{...b,skills:b.skills.filter(a=>(0,g.RC)(this.rules?.skills,a.name))}};let c=Reflect.get(a,b,a);return"function"==typeof c?c.bind(a):c}})}attach(a){this.session!==a&&(this.session=a,this.requestedTools=new Set(a.getActiveToolNames()),this.originalSetTools=a.setActiveToolsByName,this.setTools=a.setActiveToolsByName.bind(a),a.setActiveToolsByName=a=>{this.rememberRequestedTools(a),this.refreshTools()},this.refreshTools())}isToolAllowed(a){return(0,g.RC)(this.rules?.tools,a)}restoreBranchSelection(){let a=this.session;!this.disposed&&a&&((0,e.getCurrentSystemMessage)(a.messages)&&(this.requestedTools=new Set(a.getActiveToolNames())),this.refreshTools())}async apply(){let a=this.session;if(this.disposed||!a)return;this.rememberRequestedTools(a.getActiveToolNames()),this.rules=this.readMode(),this.ready=!0,this.refreshTools();let b=[];for(let c of[...this.registrations.values()])try{await this.applyRegistration(c)}catch(e){let d=e instanceof Error?e.message:String(e);console.error("[Pi Desk][Capabilities] 插件应用能力规则失败",{sessionId:a.sessionId,pluginName:c.pluginName,message:d}),b.push(`${c.pluginName}:${d}`)}if(this.refreshTools(),b.length>0)throw Error(`能力规则应用失败:${b.join(";")}`)}dispose(){this.disposed=!0,this.detach()}detach(){this.ready=!1,this.registrations.clear(),this.session&&this.originalSetTools&&(this.session.setActiveToolsByName=this.originalSetTools),this.session=null,this.setTools=null,this.originalSetTools=null,this.requestedTools.clear()}rememberRequestedTools(a){let b=new Set(this.session?.getAllTools().filter(a=>"hidden"!==a.exposure).map(a=>a.name)),c=[...this.requestedTools].filter(a=>b.has(a)&&!(0,g.RC)(this.rules?.tools,a));this.requestedTools=new Set([...a,...c].filter(a=>b.has(a)))}refreshTools(){this.setTools?.([...this.requestedTools].filter(a=>(0,g.RC)(this.rules?.tools,a)))}async applyRegistration(a){let b=this.session;if(!b||this.disposed||this.registrations.get(a.pluginName)!==a)return;let c={tools:this.rules?.tools??{},skills:this.rules?.skills??{},capabilities:this.rules?.plugins?.[a.pluginName]??{}};await a.execute(structuredClone(c),b.extensionRunner.createContext())}register(a){if(!a||"object"!=typeof a)throw Error("能力回调注册无效");let b=a.registration;if(!b||"string"!=typeof b.pluginName||"function"!=typeof b.execute)throw Error("能力回调缺少插件名称或处理函数");if("unregister"===a.type){this.registrations.get(b.pluginName)===b&&this.registrations.delete(b.pluginName);return}if("register"!==a.type)throw Error("能力回调事件无效");if(this.registrations.has(b.pluginName))throw Error(`能力回调已注册:${b.pluginName}`);b.hostManaged=!0,this.registrations.set(b.pluginName,b),this.ready&&this.applyRegistration(b).catch(a=>{console.error("[Pi Desk][Capabilities] 新注册插件应用规则失败",{pluginName:b.pluginName,message:a instanceof Error?a.message:String(a)})})}}d()}catch(a){d(a)}})},26143:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{h:()=>n});var e=c(76760),f=c(75430),g=c(58801),h=c(42520),i=c(73589),j=a([f,g,i]);[f,g,i]=j.then?(await j)():j;let m=[{name:"codemode",create:f.createCodemodeExtension},{name:"tool-search",create:f.createToolSearchExtension},{name:"mcp",create:()=>(0,f.createMcpExtension)({openUrl:()=>void 0})}];function k(a){let b=(0,e.basename)(a.path),c="package"===a.metadata.origin?a.metadata.source.replace(/^npm:/,""):/^(index\.[^.]+|SKILL\.md)$/.test(b)?(0,e.basename)((0,e.dirname)(a.path)):(0,e.basename)(a.path,(0,e.extname)(a.path));return`插件 ${c}
7
- 来源:${a.path}`}async function l(a,b,c){b?.(a);let d=performance.now();try{return await c()}catch(c){let b=Math.round(performance.now()-d);throw console.error("[Pi Desk][PluginResources] 资源步骤失败",{stage:a,durationMs:b,message:c instanceof Error?c.stack??c.message:String(c)}),Error(`${a}
6
+ `,h=`${b}.${(0,d.randomUUID)()}.tmp`;try{(0,e.writeFileSync)(h,g,{encoding:"utf8",flag:"wx"});try{(0,e.linkSync)(h,b)}catch(a){if("EEXIST"!==a.code)throw a}}finally{(0,e.existsSync)(h)&&(0,e.unlinkSync)(h)}if(!(0,e.existsSync)(b))throw Error(`Failed to materialize Pi session: ${a.getSessionId()}`);return b}},9753:(a,b,c)=>{c.d(b,{LO:()=>d.L,Nb:()=>e.Nb,Nx:()=>e.Nx,O0:()=>e.O0,Sl:()=>e.Sl,k0:()=>e.k0}),c(47511),c(41904);var d=c(41966),e=c(85273)},12727:(a,b,c)=>{c.d(b,{B4:()=>x,Wl:()=>r,b7:()=>u,xf:()=>z,xm:()=>y,zG:()=>k,zK:()=>v,zz:()=>l});var d=c(54174);let e=new Intl.NumberFormat("en-US",{maximumFractionDigits:0});function f(a){if("string"!=typeof a)return null;let b=a.replace(/\s+/g," ").trim();return b?b.length<=500?b:`${b.slice(0,499)}…`:null}function g(a,...b){for(let c of b){let b=f(a[c]);if(b)return b}return null}function h(a,b){let c=a[b];return"number"==typeof c&&Number.isSafeInteger(c)&&c>=0?c:null}function i(a){if(0===a.length)return 0;let b=1;for(let c of a)"\n"===c&&(b+=1);return b}function j(a){let b=0;for(let c of a)b+=1;return b}function k(a,b,c){return{reasoning:f(b.reasoning),inputPreview:function(a,b){switch(a.toLowerCase().split(".").at(-1)??a.toLowerCase()){case"bash":return g(b,"command");case"read":case"write":case"edit":return g(b,"path","file_path");case"grep":{let a=g(b,"pattern","query"),c=g(b,"path");return a&&c?f(`${a} \xb7 ${c}`):a??c}case"find":return g(b,"pattern","path");case"ls":return g(b,"path");case"agent":return g(b,"description");case"agent_resume":return g(b,"description","prompt");default:return g(b,"command","path","file_path","pattern","query","description","prompt")}}(a,b),activity:function(a,b,c){switch(a.toLowerCase().split(".").at(-1)??a.toLowerCase()){case"read":let d=h(b,"offset"),f=h(b,"limit");if(null!==f){let a=d??1;return`${a}-${a+Math.max(0,f-1)}`}return null===d?null:`${d}-`;case"write":return function(a,b){let c,d,f=a.content;if("string"!=typeof f)return null;let g=b?.writeContent;if(b&&void 0!==g&&void 0!==b.writeCharacters&&void 0!==b.writeLines&&f.startsWith(g)){let a=f.slice(g.length);0===a.length?(c=b.writeCharacters,d=b.writeLines):(c=b.writeCharacters+j(a),d=b.writeLines+i(a)-(0!==g.length))}else c=j(f),d=i(f);return b&&(b.writeContent=f,b.writeCharacters=c,b.writeLines=d),`${e.format(c)} \xb7 L${e.format(d)}`}(b,c);case"edit":return function(a){let b=Array.isArray(a.edits)?a.edits.filter(a=>null!==a&&"object"==typeof a&&!Array.isArray(a)):"string"==typeof a.oldText||"string"==typeof a.newText?[a]:[];if(0===b.length)return null;let c=0,d=0,f=!1,g=!1;for(let a of b)"string"==typeof a.oldText&&(f=!0,c+=i(a.oldText)),"string"==typeof a.newText&&(g=!0,d+=i(a.newText));let h=[...f?[`-${e.format(c)}`]:[],...g?[`+${e.format(d)}`]:[]].join(" ");return h?`${e.format(b.length)} \xb7 ${h}`:e.format(b.length)}(b);default:return null}}(a,b,c)}}function l(a){if(!Array.isArray(a))return[];let b=[];for(let c of a){if(!c||"object"!=typeof c||"toolCall"!==c.type||"string"!=typeof c.id||!c.id||"string"!=typeof c.name||!c.name)continue;let a=c.arguments&&"object"==typeof c.arguments&&!Array.isArray(c.arguments)?c.arguments:{};b.push({id:c.id,name:c.name,input:a})}return b}function m(a){try{let b=JSON.stringify(a);return void 0===b?null:JSON.parse(b)}catch{return null}}function n(a){let b=m(a);return b&&"object"==typeof b&&!Array.isArray(b)?b:{}}function o(a){return"string"==typeof a?a:Array.isArray(a)?a.flatMap(a=>a&&"object"==typeof a&&"text"===a.type&&"string"==typeof a.text?[a.text]:[]).join("\n"):""}function p(a){return Array.isArray(a)?a.flatMap(a=>{if(!a||"object"!=typeof a||"image"!==a.type||"string"!=typeof a.data)return[];try{return[{data:a.data,metadata:(0,d.Z)(a.data).metadata}]}catch(a){return console.warn("[Pi Desk][PiChatProjection] 已忽略损坏的历史图片",{errorName:a instanceof Error?a.name:"UnknownError"}),[]}}):[]}function q(a){return p(a).map(a=>a.metadata)}function r(a,b){let c=p(a)[b];return c?{mimeType:c.metadata.mimeType,data:c.data}:null}function s(a,b){return Array.isArray(a)?a.flatMap(a=>{if(!a||"object"!=typeof a||a.type!==b)return[];let c="text"===b?a.text:a.thinking;return"string"==typeof c?[c]:[]}).join("\n"):""}function t(a){return a?{inputTokens:a.input,outputTokens:a.output,cacheReadTokens:a.cacheRead,costUsd:a.cost.total}:null}function u(a,b,c){switch(a.role){case"user":{let b=o(a.content),c=q(a.content);return{type:"user",text:b,images:c,declaration:{message:{kind:"user",text:b,images:c},raw:a}}}case"assistant":{b&&function(a,b,c){for(let d of l(a))b.set(d.id,k(d.name,d.input)),c?.set(d.id,{...d.input})}(a.content,b,c);let d=s(a.content,"text"),e=s(a.content,"thinking");return{type:"assistant",text:d,thinking:e,model:"pi-virtual"!==a.api&&"string"==typeof a.provider&&"string"==typeof(a.responseModel??a.model)?{provider:a.provider,modelId:a.responseModel??a.model}:null,status:function(a){switch(a){case"pending":return"running";case"stop":case"length":case"toolUse":return"completed";case"aborted":return"aborted";default:return"error"}}(a.stopReason),errorMessage:a.errorMessage??null,usage:t(a.usage),declaration:{message:{kind:"assistant",text:d,thinking:e,stopReason:a.stopReason},raw:a}}}case"toolResult":{let d=b?.get(a.toolCallId),e=c?.get(a.toolCallId);b?.delete(a.toolCallId),c?.delete(a.toolCallId);let f=o(a.content),g=q(a.content),h=a.nestedCalls?{complete:a.nestedCalls.complete,calls:a.nestedCalls.calls.map(a=>({name:a.name,...void 0===a.arguments?{}:{arguments:n(a.arguments)},...void 0===a.argumentsBytes?{}:{argumentsBytes:a.argumentsBytes},status:a.status,...void 0===a.durationMs?{}:{durationMs:a.durationMs},...void 0===a.error?{}:{error:a.error}}))}:null;return{type:"tool",name:a.toolName,reasoning:d?.reasoning??null,inputPreview:d?.inputPreview??null,activity:d?.activity??null,status:a.isError?"error":"completed",usage:t(a.usage),output:f,...g.length>0?{images:g}:{},...h?{nestedCalls:h}:{},startedAtMs:null,durationMs:function(a,b){if("bash"!==a||!b||"object"!=typeof b||Array.isArray(b))return null;let c=b.durationMs;return"number"==typeof c&&Number.isSafeInteger(c)&&c>=0?c:null}(a.toolName,a.details),declaration:{message:{kind:"tool",toolName:a.toolName,toolCallId:a.toolCallId,arguments:n(e),partialResult:null,result:m({content:a.content,details:a.details,output:f}),isError:a.isError},raw:a}}}case"bashExecution":return{type:"bash",command:a.command,status:a.cancelled?"aborted":0===a.exitCode?"completed":"error",output:a.output,declaration:{message:{kind:"bash",command:a.command,output:a.output,exitCode:a.exitCode??null,cancelled:a.cancelled,truncated:a.truncated},raw:a}};case"custom":{if(!a.display)return null;let b=o(a.content);return{type:"custom",text:b,declaration:{message:{kind:"custom",customType:a.customType,content:b,details:m(a.details)},raw:a}}}default:return null}}function v(a,b,c,d){let e=new Map,f=new Map;return c&&e.set(b,c),d&&f.set(b,d),u(a,e,f)}function w(a,b,c){let d="message"===a.type?u(a.message,b,c):"custom_message"===a.type?function(a){if(!a.display)return null;let b=o(a.content);return{type:"custom",text:b,declaration:{message:{kind:"custom",customType:a.customType,content:b,details:m(a.details)},raw:a}}}(a):"compaction"===a.type?{type:"compaction",summary:a.summary,declaration:{message:{kind:"custom",customType:"pi-desk/compaction",content:"",details:{text:a.summary}},raw:a}}:null;if(!d)return null;let e=Date.parse(a.timestamp);if(!Number.isSafeInteger(e)||e<0)throw Error(`Pi session entry has an invalid timestamp: ${a.id}`);return{entryId:a.id,timestampMs:e,message:d}}function x(a){return w(a,new Map,new Map)}function y(a,b){let c=[],d=new Map,e=new Map;for(let f of a){let a=w(f,d,e);a&&(c.push(a),void 0!==b&&c.length>b&&c.shift())}return c}function z(a){return{sessionName:a.getSessionName()?.trim()||null,entries:y(a.getBranch())}}},20369:(a,b,c)=>{c.d(b,{HE:()=>e,IS:()=>d.Dl,Wu:()=>d.j0,f$:()=>d.Qg,rY:()=>d.a4});var d=c(47511);function e(a){return Object.fromEntries(Object.entries(a).map(([a,b])=>[a,b.name]))}},23272:(a,b,c)=>{c.d(b,{H:()=>g,k:()=>h});var d=c(77598),e=c(57975),f=c(67062);class g extends Error{constructor(a,b){super(b),this.code=a,this.name="L4PiUiResponseError"}}class h{get hasPending(){return this.pending.size>0}snapshot(){return structuredClone(this.state)}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}bind(a,b){let c=()=>{b()},d=(a,b)=>(c(),this.request(a,b));return{...a,select:async(a,b,c)=>await d({method:"select",title:a,options:b},c),confirm:async(a,b,c)=>await d({method:"confirm",title:a,message:b},c)===!0,input:async(a,b="",c)=>await d({method:"input",title:a,placeholder:b},c),editor:async(a,b="")=>await d({method:"editor",title:a,prefill:b}),notify:(a,b="info")=>{c(),this.active&&this.emit({type:"notify",message:(0,e.stripVTControlCharacters)(a).slice(0,65536),level:b})},setStatus:(a,b)=>{if(c(),!this.active)return;let d={...this.state.statuses};void 0===b?delete d[a]:d[a]=(0,e.stripVTControlCharacters)(b),this.replace({...this.state,statuses:d})},setWidget:(a,b,d)=>{if(c(),!this.active)return;if("function"==typeof b)return void this.emit({type:"notify",level:"warning",message:"该插件挂件需要终端界面,当前仅支持文本挂件。"});let f={...this.state.widgets};void 0===b?delete f[a]:f[a]={lines:b.map(e.stripVTControlCharacters),placement:d?.placement??"aboveEditor"},this.replace({...this.state,widgets:f})},setEditorText:a=>{c(),this.active&&this.emit({type:"editor_text",mode:"replace",text:a.slice(0,65536)})},pasteToEditor:a=>{c(),this.active&&this.emit({type:"editor_text",mode:"paste",text:a.slice(0,65536)})},custom:async()=>{throw c(),Error("当前界面不支持自定义终端组件,请使用插件提供的网页界面。")}}}respond(a){let b=this.pending.get(a.id);if(!b)throw new g(409,"问题已结束或已失效,请查看最新状态");let{request:c}=b;if(null!==c.expiresAt&&c.expiresAt<=Date.now())throw this.finish(a.id,void 0),new g(409,"问题已超时");if(null!==a.value){if("confirm"===c.method?"boolean"!=typeof a.value:"string"!=typeof a.value)throw new g(400,"回答类型不正确");if("select"===c.method&&!c.options.includes(a.value))throw new g(400,"选择的选项已无效")}this.finish(a.id,a.value??void 0)}cancelAll(){let a=[...this.pending.values()];for(let b of(this.pending.clear(),this.state={...this.state,requests:[]},a))b.cleanup();for(let b of(a.length>0&&(this.publishSnapshot(),console.info("[Pi Desk][NativeUI] 已取消待处理交互",{count:a.length})),a))b.resolve(void 0)}reset(a=!0){this.active=a,this.cancelAll(),this.state=(0,f.l3)(),this.publishSnapshot()}dispose(){this.reset(!1),this.listeners.clear()}async waitForOperation(a,b,c){let d,e=b,f=performance.now(),g=()=>void 0,h=new Promise((a,b)=>{g=b}),i=()=>{d&&(e-=performance.now()-f,clearTimeout(d),d=void 0),this.hasPending||(f=performance.now(),d=setTimeout(()=>g(c()),Math.max(0,e)))},j=this.subscribe(a=>{"snapshot"===a.type&&i()});i();try{return await Promise.race([a,h])}finally{d&&clearTimeout(d),j()}}request(a,b){if(!this.active||b?.signal?.aborted)return Promise.resolve(void 0);let c=f.WR.parse({...a,id:(0,d.randomUUID)(),expiresAt:b?.timeout===void 0?null:Date.now()+Math.max(0,b.timeout)}),e={...this.state,requests:[...this.state.requests,c]};return this.validate(e),new Promise(a=>{let d=()=>this.finish(c.id,void 0),f=null===c.expiresAt?void 0:setTimeout(d,Math.max(0,c.expiresAt-Date.now()));b?.signal?.addEventListener("abort",d,{once:!0}),this.pending.set(c.id,{request:c,resolve:a,cleanup:()=>{f&&clearTimeout(f),b?.signal?.removeEventListener("abort",d)}}),this.state=e,this.publishSnapshot()})}finish(a,b){let c=this.pending.get(a);c&&(this.pending.delete(a),c.cleanup(),this.state={...this.state,requests:this.state.requests.filter(b=>b.id!==a)},c.resolve(b),null===this.snapshotImmediate&&(this.snapshotImmediate=setImmediate(()=>{this.snapshotImmediate=null,this.publishSnapshot()})))}validate(a){if(f.P.parse(a),Object.keys(a.statuses).length>32||Object.keys(a.widgets).length>16||Buffer.byteLength(JSON.stringify(a),"utf8")>262144)throw Error("插件交互内容过多,请先清理已有状态或缩短内容")}replace(a){this.validate(a),this.state=a,this.publishSnapshot()}publishSnapshot(){null!==this.snapshotImmediate&&(clearImmediate(this.snapshotImmediate),this.snapshotImmediate=null),this.emit({type:"snapshot",snapshot:this.snapshot()})}emit(a){for(let b of this.listeners)try{b(a)}catch(a){console.error("[Pi Desk][NativeUI] 交互推送失败",{message:a instanceof Error?a.message:String(a)})}}constructor(){this.state=(0,f.l3)(),this.pending=new Map,this.listeners=new Set,this.active=!0,this.snapshotImmediate=null}}},23404:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{O:()=>i});var e=c(28802),f=c(85273),g=c(47511),h=a([e]);e=(h.then?(await h)():h)[0];class i{constructor(a){this.readMode=a,this.registrations=new Map,this.session=null,this.requestedTools=new Set,this.setTools=null,this.originalSetTools=null,this.ready=!1,this.disposed=!1,this.rules=a()}eventBus(a){return{on:(b,c)=>a.on(b,c),emit:(b,c)=>{this.disposed||(b===f.Hj?this.register(c):a.emit(b,c))}}}createHostExtension(a,b){let c="<inline:pi-desk-input-validator>",d=new Map;return d.set("input",[async(b,c)=>a(b,c)]),d.set("tool_call",[async a=>{if(!this.isToolAllowed(a.toolName))return{block:!0,reason:`当前能力模式不允许工具:${a.toolName}`}}]),d.set("session_shutdown",[async()=>{this.ready=!1,this.registrations.clear(),b?.()}]),{path:c,resolvedPath:c,hidden:!0,sourceInfo:{path:c,source:"inline",scope:"temporary",origin:"top-level"},handlers:d,tools:new Map,commands:new Map,flags:new Map,shortcuts:new Map,messageRenderers:new Map}}resources(a){return new Proxy(a,{get:(a,b)=>{if("getSkills"===b)return()=>{let b=a.getSkills();return{...b,skills:b.skills.filter(a=>(0,g.RC)(this.rules?.skills,a.name))}};let c=Reflect.get(a,b,a);return"function"==typeof c?c.bind(a):c}})}attach(a){this.session!==a&&(this.session=a,this.requestedTools=new Set(a.getActiveToolNames()),this.originalSetTools=a.setActiveToolsByName,this.setTools=a.setActiveToolsByName.bind(a),a.setActiveToolsByName=a=>{this.rememberRequestedTools(a),this.refreshTools()},this.refreshTools())}isToolAllowed(a){return(0,g.RC)(this.rules?.tools,a)}restoreBranchSelection(){let a=this.session;!this.disposed&&a&&((0,e.getCurrentSystemMessage)(a.messages)&&(this.requestedTools=new Set(a.getActiveToolNames())),this.refreshTools())}async apply(){let a=this.session;if(this.disposed||!a)return;this.rememberRequestedTools(a.getActiveToolNames()),this.rules=this.readMode(),this.ready=!0,this.refreshTools();let b=[];for(let c of[...this.registrations.values()])try{await this.applyRegistration(c)}catch(e){let d=e instanceof Error?e.message:String(e);console.error("[Pi Desk][Capabilities] 插件应用能力规则失败",{sessionId:a.sessionId,pluginName:c.pluginName,message:d}),b.push(`${c.pluginName}:${d}`)}if(this.refreshTools(),b.length>0)throw Error(`能力规则应用失败:${b.join(";")}`)}dispose(){this.disposed=!0,this.detach()}detach(){this.ready=!1,this.registrations.clear(),this.session&&this.originalSetTools&&(this.session.setActiveToolsByName=this.originalSetTools),this.session=null,this.setTools=null,this.originalSetTools=null,this.requestedTools.clear()}rememberRequestedTools(a){let b=new Set(this.session?.getAllTools().filter(a=>"hidden"!==a.exposure).map(a=>a.name)),c=[...this.requestedTools].filter(a=>b.has(a)&&!(0,g.RC)(this.rules?.tools,a));this.requestedTools=new Set([...a,...c].filter(a=>b.has(a)))}refreshTools(){this.setTools?.([...this.requestedTools].filter(a=>(0,g.RC)(this.rules?.tools,a)))}async applyRegistration(a){let b=this.session;if(!b||this.disposed||this.registrations.get(a.pluginName)!==a)return;let c={tools:this.rules?.tools??{},skills:this.rules?.skills??{},capabilities:this.rules?.plugins?.[a.pluginName]??{}};await a.execute(structuredClone(c),b.extensionRunner.createContext())}register(a){if(!a||"object"!=typeof a)throw Error("能力回调注册无效");let b=a.registration;if(!b||"string"!=typeof b.pluginName||"function"!=typeof b.execute)throw Error("能力回调缺少插件名称或处理函数");if("unregister"===a.type){this.registrations.get(b.pluginName)===b&&this.registrations.delete(b.pluginName);return}if("register"!==a.type)throw Error("能力回调事件无效");if(this.registrations.has(b.pluginName))throw Error(`能力回调已注册:${b.pluginName}`);b.hostManaged=!0,this.registrations.set(b.pluginName,b),this.ready&&this.applyRegistration(b).catch(a=>{console.error("[Pi Desk][Capabilities] 新注册插件应用规则失败",{pluginName:b.pluginName,message:a instanceof Error?a.message:String(a)})})}}d()}catch(a){d(a)}})},26143:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{h:()=>o});var e=c(76760),f=c(75430),g=c(58801),h=c(42520),i=c(73589),j=c(47351),k=a([f,g,i,j]);[f,g,i,j]=k.then?(await k)():k;let n=[{name:"codemode",create:f.createCodemodeExtension},{name:"tool-search",create:f.createToolSearchExtension},{name:"mcp",create:()=>a=>(0,f.createMcpExtension)({openUrl:()=>void 0})({...a,registerCommand:(b,c)=>a.registerCommand(b,"mcp"===b?(0,j.V)(c):c)})}];function l(a){let b=(0,e.basename)(a.path),c="package"===a.metadata.origin?a.metadata.source.replace(/^npm:/,""):/^(index\.[^.]+|SKILL\.md)$/.test(b)?(0,e.basename)((0,e.dirname)(a.path)):(0,e.basename)(a.path,(0,e.extname)(a.path));return`插件 ${c}
7
+ 来源:${a.path}`}async function m(a,b,c){b?.(a);let d=performance.now();try{return await c()}catch(c){let b=Math.round(performance.now()-d);throw console.error("[Pi Desk][PluginResources] 资源步骤失败",{stage:a,durationMs:b,message:c instanceof Error?c.stack??c.message:String(c)}),Error(`${a}
8
8
  当前步骤耗时:${b} 毫秒
9
- 原因:${c instanceof Error?c.message:String(c)}`,{cause:c})}finally{let b=Math.round(performance.now()-d);b>=1e3&&console.info("[Pi Desk][PluginResources] 资源步骤耗时",{stage:a,durationMs:b})}}class n{current(a,b,c,d){return this.selection?d?.("等待已选择的插件资源准备完成"):this.selection=this.discover(a,b,c,d),this.selection}async discover(a,b,c,d){await l(`读取 Pi 配置
9
+ 原因:${c instanceof Error?c.message:String(c)}`,{cause:c})}finally{let b=Math.round(performance.now()-d);b>=1e3&&console.info("[Pi Desk][PluginResources] 资源步骤耗时",{stage:a,durationMs:b})}}class o{current(a,b,c,d){return this.selection?d?.("等待已选择的插件资源准备完成"):this.selection=this.discover(a,b,c,d),this.selection}async discover(a,b,c,d){await m(`读取 Pi 配置
10
10
  配置目录:${b}
11
- 工作目录:${a}`,d,()=>c.reload());let e=new f.DefaultPackageManager({cwd:a,agentDir:b,settingsManager:c,builtinExtensions:m.map(a=>a.name)}),g=await l("发现已配置的插件与资源",d,()=>e.resolve(async b=>{let c=`插件包未安装或版本不匹配,已跳过:${b}`;return(0,h.pL)(a,c),console.warn("[Pi Desk][PluginResources]",{cwd:a,message:c}),"skip"})),j=await (0,i.n)(b,e,c),k=async a=>{let b=await Promise.all(a.map(async a=>a.enabled&&!await j(a.metadata.source,a.path,"user"===a.metadata.scope&&"package"===a.metadata.origin)));return a.filter((a,c)=>b[c])};return{extensions:await k(g.extensions),skills:await k(g.skills),prompts:await k(g.prompts),themes:await k(g.themes)}}reset(){this.selection=null}async createServices(a,b,c){let d,i=(0,f.getAgentDir)(),j=f.SettingsManager.create(a,i),n=[],o=await l(`读取模型与认证配置
12
- 配置目录:${i}`,c,()=>f.ModelRuntime.create({authPath:(0,e.join)(i,"auth.json"),modelsPath:(0,e.join)(i,"models.json")})),p=async h=>{h&&((0,g.N)(),this.reset(),await l("重新读取 Pi 配置",c,()=>j.reload()));let n=await this.current(a,i,j,c),o=n.extensions.filter(a=>a.path.startsWith("builtin:")).map(a=>a.path),p=n.extensions.filter(a=>!a.path.startsWith("builtin:")).map(a=>({name:a.path,factory:async b=>{let d=k(a),e=await l(`${d}
13
- 步骤:导入插件模块`,c,()=>(0,g.G)(a.path).catch(a=>{if(a instanceof Error&&a.message.includes("不支持模块顶层 await"))throw Error("原生扩展不支持模块顶层 await,请将异步初始化放入 async 工厂函数",{cause:a});throw a}));await l(`${d}
14
- 步骤:执行插件工厂`,c,async()=>{if("function"!=typeof e.default)throw Error(`扩展必须导出工厂函数:${a.path}`);await e.default(b)})}})),q=f.SettingsManager.inMemory({},{projectTrusted:j.isProjectTrusted()});d=new f.DefaultResourceLoader({...b,cwd:a,agentDir:i,settingsManager:q,noExtensions:!0,noSkills:!0,noPromptTemplates:!0,noThemes:!0,extensionFactories:[...m.map(({name:a,create:b})=>({name:a,factory:b(),builtin:!0,replaceable:!0})),...p],additionalExtensionPaths:o,additionalSkillPaths:n.skills.map(a=>a.path),additionalPromptTemplatePaths:n.prompts.map(a=>a.path),additionalThemePaths:n.themes.map(a=>a.path)}),c?.("装配插件与会话资源"),await d.reload();let r=(a,b,c)=>{if(b)for(let d of c){let c=(0,e.relative)(d.path,b);if(!(c.startsWith("..")||(0,e.isAbsolute)(c))){a.sourceInfo={...d.metadata,path:b};break}}};for(let a of d.getSkills().skills)r(a,a.filePath,n.skills);for(let a of d.getPrompts().prompts)r(a,a.filePath,n.prompts);for(let a of d.getThemes().themes)r(a,a.sourcePath,n.themes);let s=d.getExtensions();for(let a of s.extensions){let b=n.extensions.find(b=>a.path===`<inline:${b.path}>`);if(b){for(let[d,e]of(a.path=b.path,a.resolvedPath=b.path,a.sourceInfo={...b.metadata,path:b.path},[["session_start","启动会话(session_start)"],["session_shutdown","关闭会话(session_shutdown)"],["resources_discover","补充会话资源(resources_discover)"]])){let f=a.handlers.get(d);f&&a.handlers.set(d,f.map(a=>(...d)=>l(`${k(b)}
15
- 步骤:${e}`,c,()=>a(...d))))}for(let b of a.tools.values())b.sourceInfo=a.sourceInfo;for(let b of a.commands.values())b.sourceInfo=a.sourceInfo}}for(let a of s.errors){let b=n.extensions.find(b=>a.path===`<inline:${b.path}>`);b&&(a.path=b.path)}};await p(!1);let q=new Proxy(d,{get:(a,b)=>{if("reload"===b)return()=>p(!0);let c=Reflect.get(d,b,d);return"function"==typeof c?c.bind(d):c}}),r=q.getExtensions().runtime,s=(b,c)=>{let d=`${b}: ${String(c)}`;(0,h.pL)(a,d),n.push({type:"warning",message:d})};for(let{name:a,config:b,extensionPath:c}of r.pendingProviderRegistrations)try{o.registerProvider(a,b)}catch(a){s(c,a)}for(let{provider:a,extensionPath:b}of r.pendingNativeProviderRegistrations)try{o.registerNativeProvider(a)}catch(a){s(b,a)}for(let{definition:a,extensionPath:b}of r.pendingVirtualModelRegistrations)try{o.registerVirtualModel(a)}catch(a){s(b,a)}return r.pendingProviderRegistrations=[],r.pendingNativeProviderRegistrations=[],r.pendingVirtualModelRegistrations=[],await l("刷新模型与认证配置",c,()=>o.refresh({allowNetwork:!1})),n.push(...j.drainErrors().map(({error:a})=>({type:"error",message:a.message}))),{cwd:a,agentDir:i,settingsManager:j,modelRuntime:o,resourceLoader:q,diagnostics:n}}constructor(){this.selection=null}}d()}catch(a){d(a)}})},32980:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{EG:()=>D,JX:()=>C,X9:()=>A,yT:()=>B});var e=c(77598),f=c(58500),g=c(83800),h=c(23272),i=c(26143),j=c(95220),k=c(28802),l=c(77844),m=c(12727),n=c(76452),o=c(49080),p=c(65209),q=c(82459),r=a([g,i,k,l,o,p,q]);function s(a){if(!a)return null;let b=Array.from(a);return b.length<=80?a:`${b.slice(0,79).join("")}…`}[g,i,k,l,o,p,q]=r.then?(await r)():r;class A extends Error{constructor(a){super(`Pi Extension Command was not found: ${a}`),this.name="L4PiNativeCommandNotFoundError"}}class B extends Error{constructor(){super("Pi Direct Bash is already running"),this.name="L4PiDirectBashRunningError"}}class C extends Error{constructor(){super("当前会话正在运行,暂时无法查看系统上下文"),this.name="L4PiModelContextBusyError"}}function t(a){if(!a||"object"!=typeof a)return null;let b=a.role;return"string"==typeof b?b:null}function u(a){if(!a||"object"!=typeof a)return null;let b=a.toolCallId;return"string"==typeof b?b:null}function v(a){return a.images.map(({mimeType:a,width:b,height:c})=>({mimeType:a,width:b,height:c}))}function w(a){return{tempId:a.tempId,text:a.input.text,images:v(a.input)}}function x(a){return{tempId:a.tempId,text:a.initial.text,images:v(a.initial)}}function y(a){let b=a.sourceInfo.path.replaceAll("\\","/");return"llama"!==a.name||!b.includes("/extensions/llama/")}function z(a,b){let c=Date.parse(b);if(!Number.isSafeInteger(c)||c<0)throw Error(`Pi session entry has an invalid timestamp: ${a}`);return c}class D{get pluginRuntime(){return this.initialization.plugins}get capabilityRuntime(){return this.initialization.capabilities}get messageGate(){return this.initialization.messages}constructor(a,b,c=()=>void 0,d={mode:()=>null,rules:()=>void 0},e){for(const f of(this.cwd=a,this.sessionManager=b,this.onEntryAppended=c,this.capabilities=d,this.nativeUi=new h.k,this.listeners=new Set,this.commandLifetime=new AbortController,this.reloadRequested=!1,this.initializationError=null,this.steeringQueue=[],this.followUpQueue=[],this.pendingQueueText=new Map,this.bashTempsById=new Map,this.observedRunPromises=new Set,this.committedEntryIds=new Set,this.backgroundTaskIds=new Set,this.liveUpdatesByTempId=new Map,this.acceptedInputs=[],this.presentedInputTempIds=new Set,this.session=null,this.extensionMode=(0,j.P)()?"basic":"normal",this.sessionLifecycle=null,this.treeNavigation=null,this.treeResumeImmediate=null,this.disposePromise=null,this.initializePromise=null,this.unsubscribeAgent=null,this.unsubscribeSession=null,this.toolRuntime=null,this.toolRuntimeLease=null,this.unsubscribeToolRuntime=null,this.pendingPrompt=null,this.activeMessage=null,this.activeValidation=null,this.activeCompactionTempId=null,this.acceptedInputTimer=null,this.compactionResumeTimer=null,this.startingAcceptedInput=!1,this.compactionResumeScheduled=!1,this.manualCompactionFinishPending=!1,this.publishingModel=!1,this.oversizedToolCallAbortRequested=!1,this.disposed=!1,this.resources=e??new i.h,this.ownsResources=void 0===e,this.initialization=this.createInitialization(),this.observedEntryCount=b.getEntries().length,b.getBranch()))this.committedEntryIds.add(f.id)}createInitialization(){return new g.k({cwd:this.cwd,sessionManager:this.sessionManager,mode:this.extensionMode,resources:this.resources,ui:this.nativeUi,readCapabilities:this.capabilities.rules,onInput:a=>this.validateFinalInput(a.text,a.images,a.streamingBehavior),onMessageEnd:({message:a})=>{if(!this.disposed&&this.oversizedToolCallAbortRequested&&"assistant"===a.role&&("aborted"===a.stopReason||"error"===a.stopReason))return{message:{...a,stopReason:"error",errorMessage:"工具参数流超过 262144 字符上限,本次响应中的工具均未执行。Please retry your request."}}},onTree:()=>this.resetBranchRuntime(),onCommand:(a,b)=>{let c=this.commandLifetime.signal;return(0,q.Fr)(a,{cwd:this.cwd,signal:c,reload:()=>this.requestReload(b),notify:a=>this.notifyCommandResult(b,a,c)})},pluginEvents:{onChanged:()=>this.emitRuntime(),onPush:({pluginName:a,event:b,data:c})=>this.emit({type:"plugin_push",pluginName:a,event:b,data:c}),onTasksChanged:a=>this.updateBackgroundTasks(a),onInvalidUpdate:a=>{console.warn("[Pi Desk][PiChatWorker] 已忽略非法插件运行态更新",{sessionId:this.sessionManager.getSessionId(),cwd:this.cwd,errorName:a instanceof Error?a.name:"UnknownError",message:a instanceof Error?a.message:String(a)})}}})}async notifyCommandResult(a,b,c){c.aborted||(await this.sessionLifecycle,c.aborted||this.disposed||!this.session||this.sessionManager.getBranch().some(b=>"message"===b.type&&"assistant"===b.message.role&&b.message.content.some(b=>"toolCall"===b.type&&b.id===a))&&this.session.resourceLoader.getExtensions().runtime.sendMessage({customType:"pi-desk:command-result",content:b,display:!0,details:{toolCallId:a}},{deliverAs:"steer",triggerTurn:!0}))}requestReload(a){if(this.commandLifetime.signal.throwIfAborted(),this.reloadRequested)throw Error("当前会话已有重载请求,请结束本轮并等待完成通知");return this.reloadRequested=!0,console.info("[Pi Desk][Commands] 当前会话重载请求已接纳",{sessionId:this.sessionManager.getSessionId(),toolCallId:a}),this.reloadWhenIdle(a).finally(()=>{this.reloadRequested=!1}),{mode:"async",message:"已收到当前窗口的 Pi 配置重载请求。请结束本轮对话并等待,无需查询或重复调用;会话空闲后会执行重载,完成后向本会话发送结果消息并自动唤醒。"}}async reloadWhenIdle(a){let b,c=this.commandLifetime.signal,d={sessionId:this.sessionManager.getSessionId(),toolCallId:a};try{do await (0,f.setTimeout)(250,void 0,{signal:c});while(null!==this.readPluginReloadBlockReason());if(console.info("[Pi Desk][Commands] 会话已空闲,开始重载 Pi 配置",d),await this.reload(),c.throwIfAborted(),this.initializationError)throw Error(`扩展未恢复,当前使用基础会话。
11
+ 工作目录:${a}`,d,()=>c.reload());let e=new f.DefaultPackageManager({cwd:a,agentDir:b,settingsManager:c,builtinExtensions:n.map(a=>a.name)}),g=await m("发现已配置的插件与资源",d,()=>e.resolve(async b=>{let c=`插件包未安装或版本不匹配,已跳过:${b}`;return(0,h.pL)(a,c),console.warn("[Pi Desk][PluginResources]",{cwd:a,message:c}),"skip"})),j=await (0,i.n)(b,e,c),k=async a=>{let b=await Promise.all(a.map(async a=>a.enabled&&!await j(a.metadata.source,a.path,"user"===a.metadata.scope&&"package"===a.metadata.origin)));return a.filter((a,c)=>b[c])};return{extensions:await k(g.extensions),skills:await k(g.skills),prompts:await k(g.prompts),themes:await k(g.themes)}}reset(){this.selection=null}async createServices(a,b,c){let d,i=(0,f.getAgentDir)(),j=f.SettingsManager.create(a,i),k=[],o=await m(`读取模型与认证配置
12
+ 配置目录:${i}`,c,()=>f.ModelRuntime.create({authPath:(0,e.join)(i,"auth.json"),modelsPath:(0,e.join)(i,"models.json")})),p=async h=>{h&&((0,g.N)(),this.reset(),await m("重新读取 Pi 配置",c,()=>j.reload()));let k=await this.current(a,i,j,c),o=k.extensions.filter(a=>a.path.startsWith("builtin:")).map(a=>a.path),p=k.extensions.filter(a=>!a.path.startsWith("builtin:")).map(a=>({name:a.path,factory:async b=>{let d=l(a),e=await m(`${d}
13
+ 步骤:导入插件模块`,c,()=>(0,g.G)(a.path).catch(a=>{if(a instanceof Error&&a.message.includes("不支持模块顶层 await"))throw Error("原生扩展不支持模块顶层 await,请将异步初始化放入 async 工厂函数",{cause:a});throw a}));await m(`${d}
14
+ 步骤:执行插件工厂`,c,async()=>{if("function"!=typeof e.default)throw Error(`扩展必须导出工厂函数:${a.path}`);await e.default(b)})}})),q=f.SettingsManager.inMemory({},{projectTrusted:j.isProjectTrusted()});d=new f.DefaultResourceLoader({...b,cwd:a,agentDir:i,settingsManager:q,noExtensions:!0,noSkills:!0,noPromptTemplates:!0,noThemes:!0,extensionFactories:[...n.map(({name:a,create:b})=>({name:a,factory:b(),builtin:!0,replaceable:!0})),...p],additionalExtensionPaths:o,additionalSkillPaths:k.skills.map(a=>a.path),additionalPromptTemplatePaths:k.prompts.map(a=>a.path),additionalThemePaths:k.themes.map(a=>a.path)}),c?.("装配插件与会话资源"),await d.reload();let r=(a,b,c)=>{if(b)for(let d of c){let c=(0,e.relative)(d.path,b);if(!(c.startsWith("..")||(0,e.isAbsolute)(c))){a.sourceInfo={...d.metadata,path:b};break}}};for(let a of d.getSkills().skills)r(a,a.filePath,k.skills);for(let a of d.getPrompts().prompts)r(a,a.filePath,k.prompts);for(let a of d.getThemes().themes)r(a,a.sourcePath,k.themes);let s=d.getExtensions();for(let a of s.extensions){let b=k.extensions.find(b=>a.path===`<inline:${b.path}>`);if(b){for(let[d,e]of(a.path=b.path,a.resolvedPath=b.path,a.sourceInfo={...b.metadata,path:b.path},[["session_start","启动会话(session_start)"],["session_shutdown","关闭会话(session_shutdown)"],["resources_discover","补充会话资源(resources_discover)"]])){let f=a.handlers.get(d);f&&a.handlers.set(d,f.map(a=>(...d)=>m(`${l(b)}
15
+ 步骤:${e}`,c,()=>a(...d))))}for(let b of a.tools.values())b.sourceInfo=a.sourceInfo;for(let b of a.commands.values())b.sourceInfo=a.sourceInfo}}for(let a of s.errors){let b=k.extensions.find(b=>a.path===`<inline:${b.path}>`);b&&(a.path=b.path)}};await p(!1);let q=new Proxy(d,{get:(a,b)=>{if("reload"===b)return()=>p(!0);let c=Reflect.get(d,b,d);return"function"==typeof c?c.bind(d):c}}),r=q.getExtensions().runtime,s=(b,c)=>{let d=`${b}: ${String(c)}`;(0,h.pL)(a,d),k.push({type:"warning",message:d})};for(let{name:a,config:b,extensionPath:c}of r.pendingProviderRegistrations)try{o.registerProvider(a,b)}catch(a){s(c,a)}for(let{provider:a,extensionPath:b}of r.pendingNativeProviderRegistrations)try{o.registerNativeProvider(a)}catch(a){s(b,a)}for(let{definition:a,extensionPath:b}of r.pendingVirtualModelRegistrations)try{o.registerVirtualModel(a)}catch(a){s(b,a)}return r.pendingProviderRegistrations=[],r.pendingNativeProviderRegistrations=[],r.pendingVirtualModelRegistrations=[],await m("刷新模型与认证配置",c,()=>o.refresh({allowNetwork:!1})),k.push(...j.drainErrors().map(({error:a})=>({type:"error",message:a.message}))),{cwd:a,agentDir:i,settingsManager:j,modelRuntime:o,resourceLoader:q,diagnostics:k}}constructor(){this.selection=null}}d()}catch(a){d(a)}})},32980:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{EG:()=>C,X9:()=>A,yT:()=>B});var e=c(77598),f=c(58500),g=c(83800),h=c(23272),i=c(26143),j=c(95220),k=c(28802),l=c(77844),m=c(12727),n=c(76452),o=c(49080),p=c(65209),q=c(82459),r=a([g,i,k,l,o,p,q]);function s(a){if(!a)return null;let b=Array.from(a);return b.length<=80?a:`${b.slice(0,79).join("")}…`}[g,i,k,l,o,p,q]=r.then?(await r)():r;class A extends Error{constructor(a){super(`Pi Extension Command was not found: ${a}`),this.name="L4PiNativeCommandNotFoundError"}}class B extends Error{constructor(){super("Pi Direct Bash is already running"),this.name="L4PiDirectBashRunningError"}}function t(a){if(!a||"object"!=typeof a)return null;let b=a.role;return"string"==typeof b?b:null}function u(a){if(!a||"object"!=typeof a)return null;let b=a.toolCallId;return"string"==typeof b?b:null}function v(a){return a.images.map(({mimeType:a,width:b,height:c})=>({mimeType:a,width:b,height:c}))}function w(a){return{tempId:a.tempId,text:a.input.text,images:v(a.input)}}function x(a){return{tempId:a.tempId,text:a.initial.text,images:v(a.initial)}}function y(a){let b=a.sourceInfo.path.replaceAll("\\","/");return"llama"!==a.name||!b.includes("/extensions/llama/")}function z(a,b){let c=Date.parse(b);if(!Number.isSafeInteger(c)||c<0)throw Error(`Pi session entry has an invalid timestamp: ${a}`);return c}class C{get pluginRuntime(){return this.initialization.plugins}get capabilityRuntime(){return this.initialization.capabilities}get messageGate(){return this.initialization.messages}constructor(a,b,c=()=>void 0,d={mode:()=>null,rules:()=>void 0},e){for(const f of(this.cwd=a,this.sessionManager=b,this.onEntryAppended=c,this.capabilities=d,this.nativeUi=new h.k,this.listeners=new Set,this.commandLifetime=new AbortController,this.reloadRequested=!1,this.initializationError=null,this.steeringQueue=[],this.followUpQueue=[],this.pendingQueueText=new Map,this.bashTempsById=new Map,this.observedRunPromises=new Set,this.committedEntryIds=new Set,this.backgroundTaskIds=new Set,this.liveUpdatesByTempId=new Map,this.acceptedInputs=[],this.presentedInputTempIds=new Set,this.session=null,this.extensionMode=(0,j.P)()?"basic":"normal",this.sessionLifecycle=null,this.treeNavigation=null,this.treeResumeImmediate=null,this.disposePromise=null,this.initializePromise=null,this.unsubscribeAgent=null,this.unsubscribeSession=null,this.toolRuntime=null,this.toolRuntimeLease=null,this.unsubscribeToolRuntime=null,this.pendingPrompt=null,this.activeMessage=null,this.activeValidation=null,this.activeCompactionTempId=null,this.acceptedInputTimer=null,this.compactionResumeTimer=null,this.startingAcceptedInput=!1,this.compactionResumeScheduled=!1,this.manualCompactionFinishPending=!1,this.publishingModel=!1,this.oversizedToolCallAbortRequested=!1,this.disposed=!1,this.resources=e??new i.h,this.ownsResources=void 0===e,this.initialization=this.createInitialization(),this.observedEntryCount=b.getEntries().length,b.getBranch()))this.committedEntryIds.add(f.id)}createInitialization(){return new g.k({cwd:this.cwd,sessionManager:this.sessionManager,mode:this.extensionMode,resources:this.resources,ui:this.nativeUi,readCapabilities:this.capabilities.rules,onInput:a=>this.validateFinalInput(a.text,a.images,a.streamingBehavior),onMessageEnd:({message:a})=>{if(!this.disposed&&this.oversizedToolCallAbortRequested&&"assistant"===a.role&&("aborted"===a.stopReason||"error"===a.stopReason))return{message:{...a,stopReason:"error",errorMessage:"工具参数流超过 262144 字符上限,本次响应中的工具均未执行。Please retry your request."}}},onTree:()=>this.resetBranchRuntime(),onCommand:(a,b)=>{let c=this.commandLifetime.signal;return(0,q.Fr)(a,{cwd:this.cwd,signal:c,reload:()=>this.requestReload(b),notify:a=>this.notifyCommandResult(b,a,c)})},pluginEvents:{onChanged:()=>this.emitRuntime(),onPush:({pluginName:a,event:b,data:c})=>this.emit({type:"plugin_push",pluginName:a,event:b,data:c}),onTasksChanged:a=>this.updateBackgroundTasks(a),onInvalidUpdate:a=>{console.warn("[Pi Desk][PiChatWorker] 已忽略非法插件运行态更新",{sessionId:this.sessionManager.getSessionId(),cwd:this.cwd,errorName:a instanceof Error?a.name:"UnknownError",message:a instanceof Error?a.message:String(a)})}}})}async notifyCommandResult(a,b,c){c.aborted||(await this.sessionLifecycle,c.aborted||this.disposed||!this.session||this.sessionManager.getBranch().some(b=>"message"===b.type&&"assistant"===b.message.role&&b.message.content.some(b=>"toolCall"===b.type&&b.id===a))&&this.session.resourceLoader.getExtensions().runtime.sendMessage({customType:"pi-desk:command-result",content:b,display:!0,details:{toolCallId:a}},{deliverAs:"steer",triggerTurn:!0}))}requestReload(a){if(this.commandLifetime.signal.throwIfAborted(),this.reloadRequested)throw Error("当前会话已有重载请求,请结束本轮并等待完成通知");return this.reloadRequested=!0,console.info("[Pi Desk][Commands] 当前会话重载请求已接纳",{sessionId:this.sessionManager.getSessionId(),toolCallId:a}),this.reloadWhenIdle(a).finally(()=>{this.reloadRequested=!1}),{mode:"async",message:"已收到当前窗口的 Pi 配置重载请求。请结束本轮对话并等待,无需查询或重复调用;会话空闲后会执行重载,完成后向本会话发送结果消息并自动唤醒。"}}async reloadWhenIdle(a){let b,c=this.commandLifetime.signal,d={sessionId:this.sessionManager.getSessionId(),toolCallId:a};try{do await (0,f.setTimeout)(250,void 0,{signal:c});while(null!==this.readPluginReloadBlockReason());if(console.info("[Pi Desk][Commands] 会话已空闲,开始重载 Pi 配置",d),await this.reload(),c.throwIfAborted(),this.initializationError)throw Error(`扩展未恢复,当前使用基础会话。
16
16
  ${this.initializationError}`);b="basic"===this.extensionMode?"当前窗口的 Pi 配置已重载完成。服务处于基础模式,未加载外部插件。可以继续处理重载前尚未完成的任务。":"当前窗口的 Pi 配置已重载完成,已重新加载配置及本机已安装插件的当前代码。可以继续处理重载前尚未完成的任务。",console.info("[Pi Desk][Commands] 当前会话重载完成",d)}catch(e){if(c.aborted)return;let a=e instanceof Error?e.message:String(e);console.warn("[Pi Desk][Commands] 当前会话重载失败",{...d,reason:a}),b=`当前窗口的 Pi 配置重载失败。
17
- 原因:${a}`}try{if(this.sessionLifecycle||!this.session)throw Error("会话尚未恢复,无法投递重载结果");await this.notifyCommandResult(a,b,c)}catch(a){if(c.aborted)return;console.warn("[Pi Desk][Commands] 会话重载结果投递失败",{...d,message:a instanceof Error?a.message:String(a)})}}getBackgroundTaskIds(){return this.pluginRuntime.activeTaskIds()}getTaskRecord(a){return this.pluginRuntime.taskRecord(a)}async watchTaskDetail(a,b){return await this.ensureSession(),this.pluginRuntime.watchTaskDetail(a,b)}async readTaskMessage(a,b){return await this.ensureSession(),this.pluginRuntime.readTaskMessage(a,b)}async readTaskImage(a,b,c){return await this.ensureSession(),this.pluginRuntime.readTaskImage(a,b,c)}async interruptTask(a){await this.ensureSession(),await this.pluginRuntime.interruptTask(a)}async invokePluginMethod(a,b,c,d){let e=await this.ensureSession();return this.pluginRuntime.invokeMethod(a,b,c,d,e.extensionRunner.createContext())}async listNativeCommands(){let a=await this.ensureSession(),b=a.extensionRunner.getRegisteredCommands(),c=new Set(b.map(a=>a.invocationName)),d=b.filter(y).map(a=>({name:a.invocationName,description:s(a.description),source:"extension"})),e=a.resourceLoader.getSkills().skills.map(a=>({name:`skill:${a.name}`,description:s(a.description),source:"skill"})).filter(a=>!c.has(a.name)),f=new Set(e.map(a=>a.name)),g=a.promptTemplates.filter(a=>!c.has(a.name)&&!f.has(a.name)).map(a=>({name:a.name,description:s(a.description),source:"prompt"}));return[...d,...g,...e]}async executeNativeCommand(a,b){let c=await this.ensureSession(),d=c.extensionRunner.getCommand(a);if(!d)throw new A(a);try{await d.handler(b,c.extensionRunner.createCommandContext())}catch(b){let a=b instanceof Error?b:Error(String(b));throw c.extensionRunner.emitError({extensionPath:d.sourceInfo.path,event:`command:${d.invocationName}`,error:a.message,...a.stack?{stack:a.stack}:{}}),a}}async listNativeTools(a=!1){if(a&&!this.session)return[];let b=await this.ensureSession(),c=new Set(b.getActiveToolNames()),d=new Map;for(let a of b.resourceLoader.getExtensions().extensions)for(let b of a.tools.keys())d.set(b,a.sourceInfo?.path??a.path);return b.getAllTools().map(a=>({name:a.name,description:a.description,parameters:JSON.parse(JSON.stringify(a.parameters)),active:c.has(a.name),exposure:a.exposure??"direct",source:a.namespace?.name??d.get(a.name)??null,blockedByMode:!this.capabilityRuntime.isToolAllowed(a.name)}))}async executeDirectBash(a){let b=await this.ensureSession();if(b.isBashRunning)throw new B;let c=(0,e.randomUUID)();console.info("[Pi Desk][PiChatWorker] Direct Bash 已开始",{sessionId:b.sessionId,executionId:c,excludeFromContext:a.excludeFromContext,commandLength:a.command.length}),this.startBash(c,a.command);try{let d=await b.extensionRunner.emitUserBash({type:"user_bash",command:a.command,excludeFromContext:a.excludeFromContext,cwd:this.cwd}),e=d?.result?d.result:await b.executeBash(a.command,void 0,{excludeFromContext:a.excludeFromContext,id:c,operations:d?.operations});return d?.result&&b.recordBashResult(a.command,e,{excludeFromContext:a.excludeFromContext}),this.completeBash(c,e),{output:e.output,exitCode:e.exitCode??null,cancelled:e.cancelled,truncated:e.truncated,fullOutputPath:e.fullOutputPath??null}}catch(a){throw this.discardBash(c),a}finally{console.info("[Pi Desk][PiChatWorker] Direct Bash 已结束",{sessionId:b.sessionId,executionId:c})}}async abortDirectBash(){(await this.ensureSession()).abortBash()}assertIdle(){if(this.disposed||this.initializePromise)throw Error("Pi 会话仍在初始化或关闭,不能切换分支");if(this.sessionLifecycle)throw Error("Pi 会话生命周期仍在处理,不能切换分支");if(this.startingAcceptedInput||this.acceptedInputs.length>0)throw Error("主 Agent 正在接管聊天输入,不能切换分支");if(this.activeCompactionTempId)throw Error("上下文压缩期间不能切换分支");if(this.session&&!this.session.isIdle)throw Error("主 Agent 运行时不能切换分支")}readPluginReloadBlockReason(){return this.disposed?"Pi Worker 已释放":this.sessionLifecycle?"Pi 扩展重载或关闭仍未完成":this.initializePromise?"AgentSession 正在初始化":this.startingAcceptedInput||this.acceptedInputs.length>0||this.acceptedInputTimer?"聊天输入正在接纳":this.activeValidation||this.pendingPrompt?"聊天输入正在校验":this.activeCompactionTempId?"上下文正在压缩":this.steeringQueue.length>0||this.followUpQueue.length>0?"聊天队列不为空":this.observedRunPromises.size>0?"Agent 运行仍在收尾":this.backgroundTaskIds.size>0?"插件后台任务仍在运行":this.session?.isBashRunning?"Bash 正在运行":this.session&&!this.session.isIdle?"主 Agent 正在运行":this.activeMessage||(this.toolRuntime?.size??0)>0||this.bashTempsById.size>0?"实时消息仍在处理":null}subscribe(a){if(this.disposed)throw Error("Pi chat worker has been disposed");return this.listeners.add(a),()=>this.listeners.delete(a)}async getRuntime(a=!0){if(!a){if(this.disposed)throw Error("Pi chat worker has been disposed");return this.session||this.sessionLifecycle||this.ensureSession().catch(a=>{this.disposed||this.session||(this.initializationError=(a instanceof Error?a.message:String(a)).slice(0,32e3),this.emit({type:"runtime_changed",runtime:this.runtimeSnapshot()}))}),this.runtimeSnapshot()}let b=this.ensureSession(),c=()=>void 0,d=new Promise(a=>{c=this.nativeUi.subscribe(()=>{this.nativeUi.hasPending&&a()}),this.nativeUi.hasPending&&a()});try{return await Promise.race([b,d]),this.runtimeSnapshot()}finally{c()}}async readModelContext(){if(this.startingAcceptedInput||this.acceptedInputs.length>0||this.activeValidation||this.pendingPrompt||this.activeCompactionTempId||this.observedRunPromises.size>0)throw new C;let a=await this.ensureSession();if(!a.isIdle||a.isBashRunning)throw new C;let b=new Set(a.getActiveToolNames()),c=a.getAllTools().filter(a=>b.has(a.name)).map(a=>{var b;let c;return{name:a.name,description:a.description,parameters:(b=a.parameters,(c=function(a){try{let b=JSON.stringify(a);return void 0===b?null:JSON.parse(b)}catch{return null}}(b))&&"object"==typeof c&&!Array.isArray(c)?c:{})}}),d={systemPrompt:a.systemPrompt,tools:c};return console.info("[Pi Desk][PiChatWorker] 已读取模型上下文",{sessionId:a.sessionId,toolCount:d.tools.length}),d}async listModels(){return(0,o.A)(this.sessionLifecycle?null:this.session,this.cwd)}async send(a){let b=await this.ensureSession(),c=(0,l.ni)(a);if(c.images.length>0&&!b.model?.input.includes("image"))throw Error("当前模型不支持图片输入");let d=this.messageGate.isBlocking;"follow_up"!==a.mode||d||this.resolveMode(b,a.mode),d&&(0,l.mu)([...this.steeringQueue.map(a=>a.input),...this.followUpQueue.map(a=>a.input),...this.acceptedInputs.filter(a=>a.deferredByCompaction).map(a=>a.initial),c]);let f=(0,e.randomUUID)(),g={tempId:f,input:a,initial:c,deferredByCompaction:d,allowIdleFollowUp:d};return this.acceptedInputs.push(g),d&&this.messageGate.defer("web-user-message",()=>this.startDeferredAcceptedInput(g))?this.emitRuntime():(g.deferredByCompaction=!1,this.scheduleAcceptedInputStart()),console.info("[Pi Desk][PiChatWorker] 聊天输入已由 Worker 接管",{sessionId:b.sessionId,tempId:f,requestedMode:a.mode,deferredByCompaction:d}),{tempId:f}}async interrupt(){this.nativeUi.cancelAll(),this.discardAcceptedInputs();let a=await this.ensureSession();this.oversizedToolCallAbortRequested=!1,await a.abort()}async navigateTree(a,b=!1){let c=await this.ensureSession();this.assertIdle(),this.treeResumeImmediate&&clearImmediate(this.treeResumeImmediate),this.treeResumeImmediate=null;let d=!1;try{return await this.runSessionLifecycle(async()=>{let e=this.sessionManager.getLeafId(),f={committed:!1};this.treeNavigation=f,this.messageGate.pause();try{this.initialization.setStage("切换会话树"),(d=!(b&&e===a?await this.navigateLeafUserMessage(c,a):await c.navigateTree(a,{summarize:!1})).cancelled)&&await this.capabilityRuntime.apply()}catch(a){throw f.committed||this.sessionManager.getLeafId()===e||this.resetBranchRuntime(),a}finally{try{if(f.committed)for(let a of(this.syncOwnerAppendedEntries(),this.observedEntryCount=this.sessionManager.getEntries().length,this.committedEntryIds.clear(),this.sessionManager.getBranch()))this.committedEntryIds.add(a.id)}finally{this.treeNavigation=null,f.committed||(this.reconcileAppendedEntries(),this.emitTreeState()),this.scheduleTreeMessageResume()}}}),d}catch(a){throw c.abortCompaction(),a}}async navigateLeafUserMessage(a,b){let c=this.sessionManager.getEntry(b),d=await a.extensionRunner.emit({type:"session_before_tree",preparation:{targetId:b,oldLeafId:b,commonAncestorId:b,entriesToSummarize:[],userWantsSummary:!1},signal:this.commandLifetime.signal});return d?.cancel||this.commandLifetime.signal.aborted?{cancelled:!0}:(null===c.parentId?this.sessionManager.resetLeaf():this.sessionManager.branch(c.parentId),d?.label&&this.sessionManager.appendLabelChange(b,d.label),a.refreshContext(),await a.extensionRunner.emit({type:"session_tree",oldLeafId:b,newLeafId:this.sessionManager.getLeafId()}),{cancelled:!1})}resetBranchRuntime(){this.treeNavigation&&(this.treeNavigation.committed=!0),this.commandLifetime.abort(),this.commandLifetime=new AbortController,this.acceptedInputTimer&&clearTimeout(this.acceptedInputTimer),this.compactionResumeTimer&&clearTimeout(this.compactionResumeTimer),this.acceptedInputTimer=null,this.compactionResumeTimer=null,this.messageGate.discardPending(),this.toolRuntime?.discardAll(),this.clearLiveUpdates(),this.clearMemory(),this.nativeUi.reset(),this.capabilityRuntime.restoreBranchSelection(),this.pluginRuntime.resetBranch()}scheduleTreeMessageResume(){if(this.disposed)return;let a=setImmediate(()=>{(async()=>{await this.sessionLifecycle?.catch(()=>void 0),this.treeResumeImmediate!==a||(this.treeResumeImmediate=null,this.disposed||this.treeNavigation||!this.session||(await this.messageGate.resume(),this.disposed||(this.reconcileAppendedEntries(),this.emitTreeState(),this.scheduleAcceptedInputStart())))})().catch(b=>{this.treeResumeImmediate===a&&(this.treeResumeImmediate=null),console.warn("[Pi Desk][PiChatWorker] 分支消息恢复失败",{error:b})})});this.treeResumeImmediate=a}emitTreeState(){this.emitBackgroundTasks(),this.emit({type:"session_info_changed",sessionTitle:this.sessionManager.getSessionName()?.trim()||null}),this.emitRuntime()}get isInitialized(){return null!==this.session}async reload(a){let b=a??((0,j.P)()?"basic":"normal");if((0,j.P)()&&"normal"===b)throw Error("服务处于基础模式,请正常启动 Pi Desk 后再加载外部扩展");let c=this.readPluginReloadBlockReason();if(c)throw Error(`当前会话不能重载 Pi 配置:${c}`);if(b!==this.extensionMode||!this.session)return void await this.runSessionLifecycle(async()=>{if(this.releaseSessionBindings(),this.initialization.dispose(),this.session=null,this.updateBackgroundTasks([]),this.disposed)throw Error("Pi Worker 已释放");this.extensionMode=b,this.initialization=this.createInitialization();try{await this.createSession("normal"===b)}finally{this.emit({type:"runtime_changed",runtime:this.runtimeSnapshot()})}},125e3);let d=await this.ensureSession(),e=this.readPluginReloadBlockReason();if(e)throw Error(`当前会话不能重载 Pi 配置:${e}`);await this.runSessionLifecycle(async()=>{this.unsubscribeAgent?.(),this.unsubscribeAgent=null;try{await this.initialization.reload()}catch(a){this.restoreBasicInitialization(a),await this.createSession();return}finally{this.disposed||this.session!==d||this.unsubscribeAgent||(this.unsubscribeAgent=d.agent.subscribe(a=>{this.session===d&&this.handleAgentEvent(a)}))}this.disposed||this.session!==d||(this.messageGate.installExtensionRuntime(d.resourceLoader.getExtensions().runtime),await this.capabilityRuntime.apply(),this.reconcileAppendedEntries(),this.emitRuntime())})}waitForSessionLifecycle(a,b=15e3){return this.nativeUi.waitForOperation(a,b,()=>Error(`Pi 扩展生命周期未在截止时间内完成
17
+ 原因:${a}`}try{if(this.sessionLifecycle||!this.session)throw Error("会话尚未恢复,无法投递重载结果");await this.notifyCommandResult(a,b,c)}catch(a){if(c.aborted)return;console.warn("[Pi Desk][Commands] 会话重载结果投递失败",{...d,message:a instanceof Error?a.message:String(a)})}}getBackgroundTaskIds(){return this.pluginRuntime.activeTaskIds()}getTaskRecord(a){return this.pluginRuntime.taskRecord(a)}async watchTaskDetail(a,b){return await this.ensureSession(),this.pluginRuntime.watchTaskDetail(a,b)}async readTaskMessage(a,b){return await this.ensureSession(),this.pluginRuntime.readTaskMessage(a,b)}async readTaskImage(a,b,c){return await this.ensureSession(),this.pluginRuntime.readTaskImage(a,b,c)}async interruptTask(a){await this.ensureSession(),await this.pluginRuntime.interruptTask(a)}async invokePluginMethod(a,b,c,d){let e=await this.ensureSession();return this.pluginRuntime.invokeMethod(a,b,c,d,e.extensionRunner.createContext())}async listNativeCommands(){let a=await this.ensureSession(),b=a.extensionRunner.getRegisteredCommands(),c=new Set(b.map(a=>a.invocationName)),d=b.filter(y).map(a=>({name:a.invocationName,description:s(a.description),source:"extension"})),e=a.resourceLoader.getSkills().skills.map(a=>({name:`skill:${a.name}`,description:s(a.description),source:"skill"})).filter(a=>!c.has(a.name)),f=new Set(e.map(a=>a.name)),g=a.promptTemplates.filter(a=>!c.has(a.name)&&!f.has(a.name)).map(a=>({name:a.name,description:s(a.description),source:"prompt"}));return[...d,...g,...e]}async executeNativeCommand(a,b){let c=await this.ensureSession(),d=c.extensionRunner.getCommand(a);if(!d)throw new A(a);try{await d.handler(b,c.extensionRunner.createCommandContext())}catch(b){let a=b instanceof Error?b:Error(String(b));throw c.extensionRunner.emitError({extensionPath:d.sourceInfo.path,event:`command:${d.invocationName}`,error:a.message,...a.stack?{stack:a.stack}:{}}),a}}async listNativeTools(a=!1){if(a&&!this.session)return[];let b=await this.ensureSession(),c=new Set(b.getActiveToolNames()),d=new Map;for(let a of b.resourceLoader.getExtensions().extensions)for(let b of a.tools.keys())d.set(b,a.sourceInfo?.path??a.path);return b.getAllTools().map(a=>({name:a.name,description:a.description,parameters:JSON.parse(JSON.stringify(a.parameters)),active:c.has(a.name),exposure:a.exposure??"direct",source:a.namespace?.name??d.get(a.name)??null,blockedByMode:!this.capabilityRuntime.isToolAllowed(a.name)}))}async executeDirectBash(a){let b=await this.ensureSession();if(b.isBashRunning)throw new B;let c=(0,e.randomUUID)();console.info("[Pi Desk][PiChatWorker] Direct Bash 已开始",{sessionId:b.sessionId,executionId:c,excludeFromContext:a.excludeFromContext,commandLength:a.command.length}),this.startBash(c,a.command);try{let d=await b.extensionRunner.emitUserBash({type:"user_bash",command:a.command,excludeFromContext:a.excludeFromContext,cwd:this.cwd}),e=d?.result?d.result:await b.executeBash(a.command,void 0,{excludeFromContext:a.excludeFromContext,id:c,operations:d?.operations});return d?.result&&b.recordBashResult(a.command,e,{excludeFromContext:a.excludeFromContext}),this.completeBash(c,e),{output:e.output,exitCode:e.exitCode??null,cancelled:e.cancelled,truncated:e.truncated,fullOutputPath:e.fullOutputPath??null}}catch(a){throw this.discardBash(c),a}finally{console.info("[Pi Desk][PiChatWorker] Direct Bash 已结束",{sessionId:b.sessionId,executionId:c})}}async abortDirectBash(){(await this.ensureSession()).abortBash()}assertIdle(){if(this.disposed||this.initializePromise)throw Error("Pi 会话仍在初始化或关闭,不能切换分支");if(this.sessionLifecycle)throw Error("Pi 会话生命周期仍在处理,不能切换分支");if(this.startingAcceptedInput||this.acceptedInputs.length>0)throw Error("主 Agent 正在接管聊天输入,不能切换分支");if(this.activeCompactionTempId)throw Error("上下文压缩期间不能切换分支");if(this.session&&!this.session.isIdle)throw Error("主 Agent 运行时不能切换分支")}readPluginReloadBlockReason(){return this.disposed?"Pi Worker 已释放":this.sessionLifecycle?"Pi 扩展重载或关闭仍未完成":this.initializePromise?"AgentSession 正在初始化":this.startingAcceptedInput||this.acceptedInputs.length>0||this.acceptedInputTimer?"聊天输入正在接纳":this.activeValidation||this.pendingPrompt?"聊天输入正在校验":this.activeCompactionTempId?"上下文正在压缩":this.steeringQueue.length>0||this.followUpQueue.length>0?"聊天队列不为空":this.observedRunPromises.size>0?"Agent 运行仍在收尾":this.backgroundTaskIds.size>0?"插件后台任务仍在运行":this.session?.isBashRunning?"Bash 正在运行":this.session&&!this.session.isIdle?"主 Agent 正在运行":this.activeMessage||(this.toolRuntime?.size??0)>0||this.bashTempsById.size>0?"实时消息仍在处理":null}subscribe(a){if(this.disposed)throw Error("Pi chat worker has been disposed");return this.listeners.add(a),()=>this.listeners.delete(a)}async getRuntime(a=!0){if(!a){if(this.disposed)throw Error("Pi chat worker has been disposed");return this.session||this.sessionLifecycle||this.ensureSession().catch(a=>{this.disposed||this.session||(this.initializationError=(a instanceof Error?a.message:String(a)).slice(0,32e3),this.emit({type:"runtime_changed",runtime:this.runtimeSnapshot()}))}),this.runtimeSnapshot()}let b=this.ensureSession(),c=()=>void 0,d=new Promise(a=>{c=this.nativeUi.subscribe(()=>{this.nativeUi.hasPending&&a()}),this.nativeUi.hasPending&&a()});try{return await Promise.race([b,d]),this.runtimeSnapshot()}finally{c()}}async readModelContext(){let a=await this.ensureSession(),b=new Set(a.getActiveToolNames()),c=a.getAllTools().filter(a=>b.has(a.name)).map(a=>{var b;let c;return{name:a.name,description:a.description,parameters:(b=a.parameters,(c=function(a){try{let b=JSON.stringify(a);return void 0===b?null:JSON.parse(b)}catch{return null}}(b))&&"object"==typeof c&&!Array.isArray(c)?c:{})}}),d={systemPrompt:a.systemPrompt,tools:c};return console.info("[Pi Desk][PiChatWorker] 已读取模型上下文",{sessionId:a.sessionId,toolCount:d.tools.length}),d}async listModels(){return(0,o.A)(this.sessionLifecycle?null:this.session,this.cwd)}async send(a){let b=await this.ensureSession(),c=(0,l.ni)(a);if(c.images.length>0&&!b.model?.input.includes("image"))throw Error("当前模型不支持图片输入");let d=this.messageGate.isBlocking;"follow_up"!==a.mode||d||this.resolveMode(b,a.mode),d&&(0,l.mu)([...this.steeringQueue.map(a=>a.input),...this.followUpQueue.map(a=>a.input),...this.acceptedInputs.filter(a=>a.deferredByCompaction).map(a=>a.initial),c]);let f=(0,e.randomUUID)(),g={tempId:f,input:a,initial:c,deferredByCompaction:d,allowIdleFollowUp:d};return this.acceptedInputs.push(g),d&&this.messageGate.defer("web-user-message",()=>this.startDeferredAcceptedInput(g))?this.emitRuntime():(g.deferredByCompaction=!1,this.scheduleAcceptedInputStart()),console.info("[Pi Desk][PiChatWorker] 聊天输入已由 Worker 接管",{sessionId:b.sessionId,tempId:f,requestedMode:a.mode,deferredByCompaction:d}),{tempId:f}}async interrupt(){this.nativeUi.cancelAll(),this.discardAcceptedInputs();let a=await this.ensureSession();this.oversizedToolCallAbortRequested=!1,await a.abort()}async navigateTree(a,b=!1){let c=await this.ensureSession();this.assertIdle(),this.treeResumeImmediate&&clearImmediate(this.treeResumeImmediate),this.treeResumeImmediate=null;let d=!1;try{return await this.runSessionLifecycle(async()=>{let e=this.sessionManager.getLeafId(),f={committed:!1};this.treeNavigation=f,this.messageGate.pause();try{this.initialization.setStage("切换会话树"),(d=!(b&&e===a?await this.navigateLeafUserMessage(c,a):await c.navigateTree(a,{summarize:!1})).cancelled)&&await this.capabilityRuntime.apply()}catch(a){throw f.committed||this.sessionManager.getLeafId()===e||this.resetBranchRuntime(),a}finally{try{if(f.committed)for(let a of(this.syncOwnerAppendedEntries(),this.observedEntryCount=this.sessionManager.getEntries().length,this.committedEntryIds.clear(),this.sessionManager.getBranch()))this.committedEntryIds.add(a.id)}finally{this.treeNavigation=null,f.committed||(this.reconcileAppendedEntries(),this.emitTreeState()),this.scheduleTreeMessageResume()}}}),d}catch(a){throw c.abortCompaction(),a}}async navigateLeafUserMessage(a,b){let c=this.sessionManager.getEntry(b),d=await a.extensionRunner.emit({type:"session_before_tree",preparation:{targetId:b,oldLeafId:b,commonAncestorId:b,entriesToSummarize:[],userWantsSummary:!1},signal:this.commandLifetime.signal});return d?.cancel||this.commandLifetime.signal.aborted?{cancelled:!0}:(null===c.parentId?this.sessionManager.resetLeaf():this.sessionManager.branch(c.parentId),d?.label&&this.sessionManager.appendLabelChange(b,d.label),a.refreshContext(),await a.extensionRunner.emit({type:"session_tree",oldLeafId:b,newLeafId:this.sessionManager.getLeafId()}),{cancelled:!1})}resetBranchRuntime(){this.treeNavigation&&(this.treeNavigation.committed=!0),this.commandLifetime.abort(),this.commandLifetime=new AbortController,this.acceptedInputTimer&&clearTimeout(this.acceptedInputTimer),this.compactionResumeTimer&&clearTimeout(this.compactionResumeTimer),this.acceptedInputTimer=null,this.compactionResumeTimer=null,this.messageGate.discardPending(),this.toolRuntime?.discardAll(),this.clearLiveUpdates(),this.clearMemory(),this.nativeUi.reset(),this.capabilityRuntime.restoreBranchSelection(),this.pluginRuntime.resetBranch()}scheduleTreeMessageResume(){if(this.disposed)return;let a=setImmediate(()=>{(async()=>{await this.sessionLifecycle?.catch(()=>void 0),this.treeResumeImmediate!==a||(this.treeResumeImmediate=null,this.disposed||this.treeNavigation||!this.session||(await this.messageGate.resume(),this.disposed||(this.reconcileAppendedEntries(),this.emitTreeState(),this.scheduleAcceptedInputStart())))})().catch(b=>{this.treeResumeImmediate===a&&(this.treeResumeImmediate=null),console.warn("[Pi Desk][PiChatWorker] 分支消息恢复失败",{error:b})})});this.treeResumeImmediate=a}emitTreeState(){this.emitBackgroundTasks(),this.emit({type:"session_info_changed",sessionTitle:this.sessionManager.getSessionName()?.trim()||null}),this.emitRuntime()}get isInitialized(){return null!==this.session}async reload(a){let b=a??((0,j.P)()?"basic":"normal");if((0,j.P)()&&"normal"===b)throw Error("服务处于基础模式,请正常启动 Pi Desk 后再加载外部扩展");let c=this.readPluginReloadBlockReason();if(c)throw Error(`当前会话不能重载 Pi 配置:${c}`);if(b!==this.extensionMode||!this.session)return void await this.runSessionLifecycle(async()=>{if(this.releaseSessionBindings(),this.initialization.dispose(),this.session=null,this.updateBackgroundTasks([]),this.disposed)throw Error("Pi Worker 已释放");this.extensionMode=b,this.initialization=this.createInitialization();try{await this.createSession("normal"===b)}finally{this.emit({type:"runtime_changed",runtime:this.runtimeSnapshot()})}},125e3);let d=await this.ensureSession(),e=this.readPluginReloadBlockReason();if(e)throw Error(`当前会话不能重载 Pi 配置:${e}`);await this.runSessionLifecycle(async()=>{this.unsubscribeAgent?.(),this.unsubscribeAgent=null;try{await this.initialization.reload()}catch(a){this.restoreBasicInitialization(a),await this.createSession();return}finally{this.disposed||this.session!==d||this.unsubscribeAgent||(this.unsubscribeAgent=d.agent.subscribe(a=>{this.session===d&&this.handleAgentEvent(a)}))}this.disposed||this.session!==d||(this.messageGate.installExtensionRuntime(d.resourceLoader.getExtensions().runtime),await this.capabilityRuntime.apply(),this.reconcileAppendedEntries(),this.emitRuntime())})}waitForSessionLifecycle(a,b=15e3){return this.nativeUi.waitForOperation(a,b,()=>Error(`Pi 扩展生命周期未在截止时间内完成
18
18
  ${this.initialization.describeStage()}`))}async runSessionLifecycle(a,b=15e3){if(this.sessionLifecycle)throw Error("Pi 扩展生命周期尚未完成");let c=Promise.resolve().then(()=>{if(this.disposed)throw Error("Pi Worker 已释放");return a()});this.sessionLifecycle=c;let d=()=>{this.sessionLifecycle===c&&(this.sessionLifecycle=null)};c.then(d,d),await this.waitForSessionLifecycle(c,b)}releaseSessionBindings(){this.unsubscribeAgent?.(),this.unsubscribeSession?.(),this.unsubscribeToolRuntime?.(),this.toolRuntimeLease?.release(),this.unsubscribeAgent=null,this.unsubscribeSession=null,this.unsubscribeToolRuntime=null,this.toolRuntimeLease=null,this.toolRuntime=null}async compact(){if(this.startingAcceptedInput||this.acceptedInputs.length>0)throw Error("主 Agent 正在接管聊天输入,不能压缩上下文");if(this.activeCompactionTempId)throw Error("上下文正在压缩");this.messageGate.pause();let a=null;try{if(!(a=await this.ensureSession()).isIdle)throw Error("主 Agent 运行时不能压缩上下文");if(a.isBashRunning)throw Error("Bash 运行时不能压缩上下文");let b=this.unsubscribeAgent;this.unsubscribeAgent=null,b?.();try{await a.compact()}finally{this.disposed||this.session!==a||this.unsubscribeAgent||(this.unsubscribeAgent=a.agent.subscribe(a=>this.handleAgentEvent(a)))}}finally{this.scheduleCompactionMessageResume()}}async restoreQueuedMessages(){let a=await this.ensureSession(),b=this.acceptedInputs.splice(0),c=b.filter(a=>"auto"===a.input.mode).map(a=>a.initial),d=b.filter(a=>"follow_up"===a.input.mode).map(a=>a.initial),e=this.steeringQueue.splice(0),f=this.followUpQueue.splice(0),g=e.map(a=>a.input),h=f.map(a=>a.input),i=[...g,...c,...h,...d];for(let c of(this.pendingQueueText.clear(),a.clearQueue(),b))this.discardPresentedInput(c.tempId);for(let a of[...e,...f])this.discardPresentedInput(a.tempId);return this.emitRuntime(),{text:i.map(a=>a.text).filter(a=>a.trim()).join("\n\n"),images:i.flatMap(a=>a.images.map(a=>({...a})))}}async applyCapabilityMode(){let a=null!==this.session;await this.ensureSession();try{a&&await this.capabilityRuntime.apply()}finally{this.emitRuntime()}}async setTitle(a){let b=await this.ensureSession(),c=a.replace(/[\r\n]+/g," ").trim();this.sessionManager.getSessionName()!==c&&b.setSessionName(c)}async setModel(a){if(this.startingAcceptedInput||this.acceptedInputs.length>0)throw Error("主 Agent 正在接管聊天输入,不能切换模型");if(this.activeCompactionTempId)throw Error("上下文压缩期间不能切换模型");let b=await this.ensureSession();if(!b.isIdle)throw Error("主 Agent 运行时不能切换模型");let c=b.modelRuntime.getModel(a.provider,a.modelId);if(!c)throw Error("模型不存在或当前不可用");if(!(0,k.getSupportedThinkingLevels)(c).includes(a.thinkingLevel))throw Error("模型不支持该思考等级");this.publishingModel=!0;try{await b.setModel(c),b.setThinkingLevel(a.thinkingLevel)}finally{this.publishingModel=!1,this.emitRuntime()}}dispose(){return this.disposePromise??=this.disposeSession().finally(()=>{this.ownsResources&&this.resources.reset()}),this.disposePromise}async disposeSession(){this.disposed=!0,this.nativeUi.dispose(),this.commandLifetime.abort(),this.treeResumeImmediate&&clearImmediate(this.treeResumeImmediate),this.treeResumeImmediate=null,this.acceptedInputTimer&&clearTimeout(this.acceptedInputTimer),this.compactionResumeTimer&&clearTimeout(this.compactionResumeTimer),this.acceptedInputTimer=null,this.compactionResumeTimer=null,this.messageGate.dispose(),this.clearLiveUpdates(),this.listeners.clear();let a=this.session;a||this.initialization.dispose(),a?.clearQueue(),a?.abortCompaction();let b=a?.abort().catch(()=>void 0);await Promise.allSettled([this.initializePromise,this.sessionLifecycle,b]);let c=this.session;if(!c){this.capabilityRuntime.dispose(),this.pluginRuntime.dispose(),this.clearMemory();return}c!==a&&(c.clearQueue(),c.abortCompaction(),await c.abort().catch(()=>void 0));try{await c.extensionRunner.emit({type:"session_shutdown",reason:"quit"})}catch(a){console.warn("[Pi Desk][PiChatWorker] 扩展关闭失败",{sessionId:c.sessionId,message:a instanceof Error?a.message:String(a)})}this.releaseSessionBindings(),this.initialization.dispose(!1),this.session=null,this.initializationError=null,await Promise.allSettled([...this.observedRunPromises]),this.clearMemory()}resolveMode(a,b,c=!1){if("follow_up"===b){if(a.isStreaming)return"followUp";if(c)return"prompt";throw Error("主 Agent 已空闲,不能添加 Follow-up")}return a.isStreaming?"steer":"prompt"}scheduleCompactionMessageResume(){this.disposed||this.compactionResumeScheduled||this.compactionResumeTimer||(this.compactionResumeScheduled=!0,queueMicrotask(()=>{if(this.compactionResumeScheduled=!1,!this.disposed){if(this.session?.isCompacting){this.compactionResumeTimer=setTimeout(()=>{this.compactionResumeTimer=null,this.scheduleCompactionMessageResume()},0);return}this.activeValidation?.compactionStarted||this.messageGate.resume().then(()=>{this.disposed||(this.scheduleAcceptedInputStart(),this.manualCompactionFinishPending&&(this.manualCompactionFinishPending=!1,this.session?.isStreaming||this.emit({type:"main_operation_finished"})),this.emitRuntime())})}}))}scheduleAcceptedInputStart(){this.disposed||this.startingAcceptedInput||0===this.acceptedInputs.length||this.acceptedInputTimer||this.messageGate.isBlocking||(this.acceptedInputTimer=setTimeout(()=>{this.acceptedInputTimer=null,this.startAcceptedInput()},0))}startAcceptedInput(){if(this.disposed||this.startingAcceptedInput||this.messageGate.isBlocking)return;let a=this.acceptedInputs.shift();a&&(this.startingAcceptedInput=!0,this.runAcceptedInput(a).finally(()=>{this.startingAcceptedInput=!1,this.scheduleAcceptedInputStart()}))}async startDeferredAcceptedInput(a){if(this.disposed)return;let b=this.acceptedInputs.indexOf(a);if(!(b<0)){this.acceptedInputs.splice(b,1),a.deferredByCompaction=!1,this.emitRuntime(),this.startingAcceptedInput=!0;try{await this.runAcceptedInput(a)}finally{this.startingAcceptedInput=!1}}}async runAcceptedInput(a){let b=null;try{let c,d=await this.ensureSession(),e=this.resolveMode(d,a.input.mode,a.allowIdleFollowUp);b={tempId:a.tempId,requestedMode:a.input.mode,mode:e,prepared:null,error:null,compactionStarted:!1,allowIdleFollowUp:a.allowIdleFollowUp},this.activeValidation=b,"prompt"===e&&(this.presentedInputTempIds.add(a.tempId),this.emit({type:"message_start",tempId:a.tempId,message:{type:"user",text:a.initial.text,images:v(a.initial)}}));let f=new Promise(a=>{c=a}),g=null,h=d.prompt(a.input.text,{images:(0,l.ti)(a.initial.images),source:"rpc",streamingBehavior:"follow_up"===a.input.mode?"followUp":"steer",preflightResult:()=>c(!0)}).then(()=>{c(!1),this.finishObservedSend(b)},a=>{g=a,c(!1),this.finishObservedSend(b)});this.observeRun(h);let i=await f;if(this.activeValidation===b&&(this.activeValidation=null),b.compactionStarted&&this.scheduleCompactionMessageResume(),b.error)throw b.error;if(!i)throw await h,g instanceof Error?g:Error("Pi 拒绝接纳聊天输入");if(!b.prepared){this.discardPresentedInput(a.tempId),console.info("[Pi Desk][PiChatWorker] 聊天输入已由扩展直接处理",{sessionId:d.sessionId,tempId:a.tempId});return}console.info("[Pi Desk][PiChatWorker] Pi 已开始处理已接管聊天输入",{sessionId:d.sessionId,tempId:a.tempId,mode:b.mode})}catch(c){this.activeValidation===b&&(this.activeValidation=null),b&&(this.cancelPreflightOperation(b),b.compactionStarted&&this.scheduleCompactionMessageResume()),this.discardPresentedInput(a.tempId),console.warn("[Pi Desk][PiChatWorker] 已撤回未被 Pi 接纳的聊天输入",{sessionId:this.session?.sessionId??this.sessionManager.getSessionId(),tempId:a.tempId,errorName:c instanceof Error?c.name:"UnknownError"})}}discardAcceptedInputs(){let a=this.acceptedInputs.splice(0);for(let b of a)this.discardPresentedInput(b.tempId);a.some(a=>a.deferredByCompaction)&&this.emitRuntime()}discardPresentedInput(a){this.presentedInputTempIds.delete(a)&&this.emit({type:"message_discard",tempId:a})}async ensureSession(){if(this.disposed)throw Error("Pi chat worker has been disposed");if(this.sessionLifecycle)throw Error("Pi 扩展生命周期尚未完成,请等待或在新会话使用基础聊天");return this.session?this.session:(this.initializePromise||(this.initializePromise=this.createSession().finally(()=>{this.initializePromise=null})),this.initializePromise)}restoreBasicInitialization(a){if(this.releaseSessionBindings(),this.initialization.dispose(),this.session=null,this.disposed||"basic"===this.extensionMode)throw a;let b=a instanceof Error?a.message:String(a);this.initializationError=b.length>32e3?`${b.slice(0,31970)}
19
19
  …诊断过长,已截断`:b,this.extensionMode="basic",this.updateBackgroundTasks([]),this.initialization=this.createInitialization(),console.warn("[Pi Desk][PiChatWorker] 扩展加载失败,切换基础聊天",{sessionId:this.sessionManager.getSessionId(),cwd:this.cwd,message:this.initializationError})}async createSession(a=!1){let b;try{b=await this.initialization.start(a)}catch(a){this.restoreBasicInitialization(a),b=await this.initialization.start()}if(this.disposed)throw this.initialization.dispose(),Error("Pi Worker 已释放");try{this.syncOwnerAppendedEntries()}catch(a){throw this.initialization.dispose(),a}return this.session=b,"normal"===this.extensionMode&&(this.initializationError=null),this.unsubscribeAgent=b.agent.subscribe(a=>{this.session===b&&this.handleAgentEvent(a)}),this.toolRuntimeLease=(0,n.s)(b),this.toolRuntime=this.toolRuntimeLease.runtime,this.unsubscribeToolRuntime=this.toolRuntime.subscribe(a=>{this.session===b&&(this.emit(a),"message_update"===a.type&&"tool"===a.message.type&&"running"!==a.message.status&&this.flushLiveUpdates())}),this.unsubscribeSession=b.subscribe(a=>{this.session===b&&this.handleSessionEvent(a)}),this.backgroundTaskIds.size>0&&this.emitBackgroundTasks(),this.emitRuntime(),b}syncOwnerAppendedEntries(){for(let a of this.sessionManager.getEntries().slice(this.observedEntryCount))this.onEntryAppended(a)}validateFinalInput(a,b,c){let d=this.activeValidation;if(!d)return{action:"continue"};try{let e=c??"prompt";if("follow_up"===d.requestedMode&&"followUp"!==e&&!(d.allowIdleFollowUp&&"prompt"===e))throw Error("主 Agent 已空闲,不能添加 Follow-up");d.mode=e;let f=this.session;if(!f)throw Error("Pi AgentSession 尚未就绪");let g=(0,l.qc)(a,b,f.resourceLoader.getSkills().skills,f.promptTemplates);if(g.images.length>0&&!f.model?.input.includes("image"))throw Error("当前模型不支持图片输入");if(d.prepared=g,"prompt"===d.mode)this.pendingPrompt={tempId:d.tempId,input:g};else{let a="steer"===d.mode?this.steeringQueue:this.followUpQueue,b={tempId:d.tempId,input:g,confirmed:!1};(0,l.mu)([...this.steeringQueue.map(a=>a.input),...this.followUpQueue.map(a=>a.input),g]),a.push(b)}return{action:"continue"}}catch(a){return d.error=a instanceof Error?a:Error("聊天输入校验失败"),{action:"handled"}}}cancelPreflightOperation(a){a.compactionStarted&&(a.compactionStarted=!1,this.emit({type:"main_operation_cancelled"}))}finishObservedSend(a){this.reconcileAppendedEntries(),this.activeValidation===a&&(this.activeValidation=null),this.pendingPrompt?.tempId===a.tempId&&(this.pendingPrompt=null,this.discardPresentedInput(a.tempId)),this.removeUnconfirmedQueueItem(a.tempId)&&(this.discardPresentedInput(a.tempId),this.emitRuntime())}removeUnconfirmedQueueItem(a){for(let b of[this.steeringQueue,this.followUpQueue]){let c=b.findIndex(b=>b.tempId===a&&!b.confirmed);if(c>=0)return b.splice(c,1),!0}return!1}observeRun(a){this.observedRunPromises.add(a),a.finally(()=>this.observedRunPromises.delete(a))}handleAgentEvent(a){if(!this.disposed&&!this.treeNavigation)switch(a.type){case"agent_start":this.oversizedToolCallAbortRequested=!1,this.emit({type:"agent_started"});return;case"agent_end":this.oversizedToolCallAbortRequested=!1,this.reconcileAppendedEntries();return;case"message_start":if(this.abortOversizedStreamingToolCall(a.message))return;this.startMessage(a.message);return;case"message_update":if(this.abortOversizedStreamingToolCall(a.message))return;this.updateMessage(a.message),this.toolRuntime?.syncStreamingTools(a.message);return;case"message_end":this.toolRuntime?.syncStreamingTools(a.message),this.endMessage(a.message);return;default:return}}abortOversizedStreamingToolCall(a){let b=function(a){if("assistant"!==t(a))return null;let b=a.content;if(!Array.isArray(b))return null;for(let a of b)if(!(!a||"object"!=typeof a||Array.isArray(a))&&"toolCall"===a.type&&"string"==typeof a.partialJson&&!(a.partialJson.length<=262144))return{toolCallId:"string"==typeof a.id?a.id:null,toolName:"string"==typeof a.name?a.name:null,argumentChars:a.partialJson.length};return null}(a);return!!b&&(this.oversizedToolCallAbortRequested||this.session?.agent.signal?.aborted||(this.oversizedToolCallAbortRequested=!0,console.warn("[Pi Desk][PiChatWorker] 工具参数流过大,已中止当前运行,交由 Pi 重试策略处理",{sessionId:this.sessionManager.getSessionId(),toolCallId:b.toolCallId,toolName:b.toolName,argumentChars:b.argumentChars,maxArgumentChars:262144}),this.session?.agent.abort()),!0)}handleSessionEvent(a){if(!this.disposed)switch(a.type){case"queue_update":this.handleQueueUpdate(a.steering,a.followUp);return;case"agent_end":a.willRetry&&(this.toolRuntime?.size??0)>0&&(console.warn("[Pi Desk][PiChatWorker] 自动重试前丢弃未闭合 ToolCall",{sessionId:this.sessionManager.getSessionId(),toolCount:this.toolRuntime?.size??0}),this.toolRuntime?.discardAll());return;case"agent_settled":this.oversizedToolCallAbortRequested=!1,this.reconcileAppendedEntries(),this.toolRuntime?.discardAll(),this.emitRuntime(),this.emit({type:"agent_settled"});return;case"compaction_start":if(this.messageGate.pause(),console.info("[Pi Desk][PiChatWorker] 上下文压缩开始",{sessionId:this.session?.sessionId,reason:a.reason}),this.activeCompactionTempId)console.warn("[Pi Desk][PiChatWorker] 已忽略重复的上下文压缩开始事件",{sessionId:this.session?.sessionId,reason:a.reason});else{let a=(0,e.randomUUID)();this.activeCompactionTempId=a,this.emit({type:"message_start",tempId:a,message:function(a=""){return{type:"compaction",summary:a}}()})}this.activeValidation&&(this.activeValidation.compactionStarted=!0),this.emit({type:"agent_started"});return;case"compaction_end":if(a.errorMessage?console.error("[Pi Desk][PiChatWorker] 上下文压缩失败",{sessionId:this.session?.sessionId,reason:a.reason,errorMessage:a.errorMessage}):console.info("[Pi Desk][PiChatWorker] 上下文压缩结束",{sessionId:this.session?.sessionId,reason:a.reason,aborted:a.aborted,compacted:void 0!==a.result,willRetry:a.willRetry}),a.result){let b=this.activeCompactionTempId;this.reconcileAppendedEntries(),b&&this.activeCompactionTempId===b&&(console.error("[Pi Desk][PiChatWorker] 压缩成功但未找到对应 CompactionEntry",{sessionId:this.session?.sessionId,reason:a.reason}),this.discardActiveCompaction())}else this.discardActiveCompaction();this.emitRuntime(),"manual"===a.reason&&(this.manualCompactionFinishPending=!0),this.scheduleCompactionMessageResume();return;case"thinking_level_changed":this.publishingModel||this.emitRuntime();return;case"entry_appended":this.treeNavigation||this.onEntryAppended(a.entry);return;case"session_info_changed":{let b=this.sessionManager.getLeafEntry();this.treeNavigation||b?.type!=="session_info"||this.onEntryAppended(b),this.emit({type:"session_info_changed",sessionTitle:a.name?.trim()||null});return}case"bash_execution_update":a.id&&this.updateBash(a.id,a.delta);return;default:return}}startMessage(a){let b,c=t(a),d=!0,f=!1,g=null;if("user"===c){let a=this.takeUserInput();b=a?.tempId??(0,e.randomUUID)(),f=this.presentedInputTempIds.delete(b)}else if("toolResult"===c){let c=(g=u(a))?this.toolRuntime?.tempId(g):null;b=c??(0,e.randomUUID)(),d=null===c}else b=(0,e.randomUUID)();let h=this.projectLiveMessage(a,g);h&&(this.activeMessage={tempId:b,started:d||f,toolCallId:g},this.emit({type:d&&!f?"message_start":"message_update",tempId:b,message:h}))}updateMessage(a){let b=this.activeMessage;if(!b)return;let c=this.projectLiveMessage(a,b.toolCallId);c&&this.emit({type:"message_update",tempId:b.tempId,message:c})}endMessage(a){let b=this.activeMessage,c=t(a),d="toolResult"===c?u(a):null;if(!b){let c=this.projectLiveMessage(a,d);if(!c)return;b={tempId:(0,e.randomUUID)(),started:!0,toolCallId:d},this.emit({type:"message_start",tempId:b.tempId,message:c})}let f=this.projectLiveMessage(a,b.toolCallId);f&&this.emit({type:"message_update",tempId:b.tempId,message:f});let g=this.sessionManager.getLeafEntry(),h=g?(0,m.B4)(g):null;g&&h?(this.onEntryAppended(g),this.committedEntryIds.add(g.id),this.observedEntryCount=this.sessionManager.getEntries().length,this.emit({type:"message_commit",tempId:b.tempId,entryId:h.entryId,timestampMs:h.timestampMs,message:f??h.message}),this.emitRuntime()):b.started&&this.emit({type:"message_discard",tempId:b.tempId}),b.toolCallId&&this.toolRuntime?.remove(b.toolCallId),this.activeMessage=null}projectLiveMessage(a,b){return"toolResult"===t(a)&&b?this.toolRuntime?.projectLiveResult(a,b)??null:(0,m.b7)(a)}takeUserInput(){if(this.pendingPrompt){let a=this.pendingPrompt;return this.pendingPrompt=null,a}let a=this.steeringQueue.shift()??this.followUpQueue.shift();return a?(this.applyPendingQueueText(),this.emitRuntime(),{tempId:a.tempId,input:a.input}):null}startBash(a,b){let c={tempId:(0,e.randomUUID)(),executionId:a,command:b,output:"",status:"running"};this.bashTempsById.set(a,c),this.emit({type:"message_start",tempId:c.tempId,message:this.bashMessage(c)})}updateBash(a,b){let c=this.bashTempsById.get(a);c&&"running"===c.status&&(c.output+=b,this.emit({type:"message_update",tempId:c.tempId,message:this.bashMessage(c)}))}completeBash(a,b){let c=this.bashTempsById.get(a);if(!c)return;c.output=b.output,c.status=b.cancelled?"aborted":0===b.exitCode?"completed":"error",this.emit({type:"message_update",tempId:c.tempId,message:this.bashMessage(c)}),this.flushLiveUpdates();let d=this.sessionManager.getLeafEntry(),e=d?(0,m.B4)(d):null;d&&e?.message.type==="bash"&&e.message.command===c.command&&(this.onEntryAppended(d),this.commitBash(c,e))}commitBash(a,b){this.flushLiveUpdates(),this.committedEntryIds.add(b.entryId),this.observedEntryCount=this.sessionManager.getEntries().length,this.emit({type:"message_commit",tempId:a.tempId,entryId:b.entryId,timestampMs:b.timestampMs,message:b.message}),this.bashTempsById.delete(a.executionId)}discardBash(a){let b=this.bashTempsById.get(a);b&&(this.bashTempsById.delete(a),this.emit({type:"message_discard",tempId:b.tempId}))}bashMessage(a){return{type:"bash",command:a.command,status:a.status,output:a.output,declaration:{message:{kind:"bash",command:a.command,output:a.output,exitCode:"completed"===a.status?0:null,cancelled:"aborted"===a.status,truncated:!1},raw:{executionId:a.executionId,command:a.command,output:a.output,status:a.status}}}}handleQueueUpdate(a,b){this.confirmAndSyncQueue("steering",a),this.confirmAndSyncQueue("followUp",b),this.emitRuntime()}confirmAndSyncQueue(a,b){let c="steering"===a?this.steeringQueue:this.followUpQueue;for(let a of c)a.confirmed=!0;c.length!==b.length?this.pendingQueueText.set(a,b):(c.forEach((a,c)=>{a.input.text=b[c]??a.input.text}),this.pendingQueueText.delete(a))}applyPendingQueueText(){for(let a of["steering","followUp"]){let b=this.pendingQueueText.get(a);b&&this.confirmAndSyncQueue(a,b)}}reconcileAppendedEntries(){if(this.treeNavigation)return;let a=this.sessionManager.getEntries(),b=a.slice(this.observedEntryCount);for(let c of(this.observedEntryCount=a.length,b)){if(this.onEntryAppended(c),this.committedEntryIds.has(c.id))continue;let a=(0,m.B4)(c);if(!a)continue;if("compaction"===c.type&&this.activeCompactionTempId){let b=this.activeCompactionTempId;this.activeCompactionTempId=null,this.committedEntryIds.add(c.id),this.emit({type:"message_commit",tempId:b,entryId:a.entryId,timestampMs:z(c.id,c.timestamp),message:a.message});continue}if("bash"===a.message.type){let b=a.message.command,c=[...this.bashTempsById.values()].reverse().find(a=>a.command===b);if(c){this.commitBash(c,a);continue}}let b=(0,e.randomUUID)();this.committedEntryIds.add(c.id),this.emit({type:"message_start",tempId:b,message:a.message}),this.emit({type:"message_commit",tempId:b,entryId:a.entryId,timestampMs:z(c.id,c.timestamp),message:a.message})}}discardActiveCompaction(){let a=this.activeCompactionTempId;a&&(this.activeCompactionTempId=null,this.emit({type:"message_discard",tempId:a}))}updateBackgroundTasks(a){let b=new Set(a);if(!(b.size===this.backgroundTaskIds.size&&[...b].every(a=>this.backgroundTaskIds.has(a)))){for(let a of(this.backgroundTaskIds.clear(),b))this.backgroundTaskIds.add(a);this.emitBackgroundTasks()}}emitBackgroundTasks(){this.emit({type:"background_tasks_changed",taskIds:[...this.backgroundTaskIds]})}runtimeSnapshot(){let a=this.session,b=a?.model,c=a?.getContextUsage(),d=this.acceptedInputs.filter(a=>a.deferredByCompaction&&"auto"===a.input.mode).map(x),e=this.acceptedInputs.filter(a=>a.deferredByCompaction&&"follow_up"===a.input.mode).map(x);return{extensionMode:this.extensionMode,initializationError:this.initializationError,queues:{steering:[...this.steeringQueue.map(w),...d],followUp:[...this.followUpQueue.map(w),...e]},model:b?{provider:b.provider,modelId:b.id,thinkingLevel:a.thinkingLevel}:null,contextUsage:c&&c.contextWindow>0?{tokens:c.tokens,contextWindow:c.contextWindow}:null,plugins:this.pluginRuntime.snapshot(),capabilityMode:this.capabilities.mode()}}emitRuntime(){this.session&&this.emit({type:"runtime_changed",runtime:this.runtimeSnapshot()})}emit(a){if(!this.disposed&&!this.treeNavigation){if("message_update"===a.type)return void this.scheduleLiveUpdate(a);this.flushLiveUpdates(),"message_start"===a.type?(this.clearLiveUpdate(a.tempId),this.liveUpdatesByTempId.set(a.tempId,{lastPublishedAt:Date.now(),pending:null,timer:null,receivedCount:0,publishedCount:0})):("message_commit"===a.type||"message_discard"===a.type)&&this.finishLiveUpdate(a.tempId),("message_commit"===a.type||"session_info_changed"===a.type)&&(0,p.xt)(this.cwd),this.publish(a)}}scheduleLiveUpdate(a){let b=this.liveUpdatesByTempId.get(a.tempId)??{lastPublishedAt:0,pending:null,timer:null,receivedCount:0,publishedCount:0};if(b.pending=a,b.receivedCount+=1,this.liveUpdatesByTempId.set(a.tempId,b),b.timer)return;let c=Date.now()-b.lastPublishedAt,d=Math.max(0,500-c);0===d?this.publishPendingLiveUpdate(b):b.timer=setTimeout(()=>{this.liveUpdatesByTempId.get(a.tempId)===b&&(b.timer=null,this.publishPendingLiveUpdate(b))},d)}publishPendingLiveUpdate(a){let b=a.pending;b&&!this.disposed&&(a.pending=null,a.lastPublishedAt=Date.now(),a.publishedCount+=1,this.publish(b))}flushLiveUpdates(){for(let a of this.liveUpdatesByTempId.values())a.timer&&clearTimeout(a.timer),a.timer=null,this.publishPendingLiveUpdate(a)}finishLiveUpdate(a){let b=this.liveUpdatesByTempId.get(a);this.clearLiveUpdate(a),b&&b.receivedCount!==b.publishedCount&&console.debug("[Pi Desk][PiChatWorker] 流式消息更新已合并",{sessionId:this.sessionManager.getSessionId(),tempId:a,receivedCount:b.receivedCount,publishedCount:b.publishedCount})}clearLiveUpdate(a){let b=this.liveUpdatesByTempId.get(a);b?.timer&&clearTimeout(b.timer),this.liveUpdatesByTempId.delete(a)}clearLiveUpdates(){for(let a of this.liveUpdatesByTempId.values())a.timer&&clearTimeout(a.timer);this.liveUpdatesByTempId.clear()}publish(a){for(let b of[...this.listeners])try{b(a)}catch(b){console.error("[Pi Desk][PiChatWorker] 事件监听器执行失败",{sessionId:this.sessionManager.getSessionId(),eventType:a.type,errorName:b instanceof Error?b.name:"UnknownError"})}}clearMemory(){this.steeringQueue.length=0,this.followUpQueue.length=0,this.pendingQueueText.clear(),this.bashTempsById.clear(),this.pendingPrompt=null,this.activeMessage=null,this.activeValidation=null,this.activeCompactionTempId=null,this.oversizedToolCallAbortRequested=!1,this.acceptedInputs.length=0,this.presentedInputTempIds.clear(),this.committedEntryIds.clear(),this.backgroundTaskIds.clear()}}d()}catch(a){d(a)}})},40333:(a,b,c)=>{c.d(b,{$m:()=>d.$m,FX:()=>d.FX,Pu:()=>d.Pu,QK:()=>d.QK,Tk:()=>d.Tk,nJ:()=>d.nJ,qs:()=>d.qs});var d=c(43969)},41904:(a,b,c)=>{c.d(b,{J:()=>f,a:()=>e});var d=c(59473);let e=d.Ik({locale:d.k5(["zh-CN","en"]),timeZone:d.Yj().trim().min(1).max(100).refine(a=>{try{return new Intl.DateTimeFormat("en",{timeZone:a}),!0}catch{return!1}},"无效的 IANA 时区")}).strict().readonly(),f=d.Ik({region:e}).strict().readonly()},41966:(a,b,c)=>{c.d(b,{L:()=>d});function d(a){if(!(a instanceof Error)||"PiDeskPluginMethodError"!==a.name)return!1;let b=a.code;return 400===b||404===b||409===b}},42520:(a,b,c)=>{c.d(b,{pL:()=>d});function d(a,b){let c=(globalThis.__piDeskNativePluginDiagnostics||(globalThis.__piDeskNativePluginDiagnostics=[]),globalThis.__piDeskNativePluginDiagnostics);!c.some(c=>c.cwd===a&&c.message===b)&&(c.push({cwd:a,message:b}),c.length>100&&c.splice(0,c.length-100))}},42633:(a,b,c)=>{c.d(b,{J8:()=>f,qf:()=>e});var d=c(59473);let e=d.KC([d.Yj(),d.Ik({default:d.Yj(),translations:d.g1(d.Yj().min(1).max(35),d.Yj()).refine(a=>Object.keys(a).length<=16,"too many translations")}).strict()]);function f(a,b){return{default:a,translations:{en:b}}}},43969:(a,b,c)=>{c.d(b,{$m:()=>g,FX:()=>h,Pu:()=>m,QK:()=>i,Tk:()=>k,nJ:()=>j,qs:()=>l});var d=c(59473);let e=d.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=d.g1(d.Yj(),d.Pq());function g(a,b){return`${a}\u0000${b}`}function h(a){return e.parse(a)}function i(a){return e.parse(a)}function j(a,b){let c=f.parse(a);if(Buffer.byteLength(JSON.stringify(c),"utf8")>2097152)throw new m(b);return c}class k extends Error{constructor(a,b){super(`Plugin method was not found: ${a}/${b}`),this.name="L4PiPluginMethodNotFoundError"}}class l extends Error{constructor(a,b){super(`Plugin method is already registered: ${a}/${b}`),this.name="L4PiPluginMethodConflictError"}}class m extends Error{constructor(a){super(`Plugin method ${a} exceeds 2MB`),this.direction=a,this.name="L4PiPluginMethodPayloadTooLargeError"}}},44095:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{K:()=>z,y:()=>w});var e=c(77598),f=c(58500),g=c(51455),h=c(76760),i=c(59473),j=c(47511),k=c(58801),l=c(88502),m=c(43969),n=a([k]);k=(n.then?(await n)():n)[0];let r=i.g1(i.Yj(),i.Pq()),s=i.Ik({workId:i.Yj().trim().min(1),sessionId:i.Yj().trim().min(1),branchId:i.Yj().trim().min(1)}).strict(),t=i.Ik({source:s,cwd:i.Yj().trim().min(1),status:i.k5(["main_running","background_running","completed","idle"])}).strict(),u=i.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),v=i.ai().int().safe();class w extends Error{constructor(){super("插件运行时仍有调用正在执行"),this.name="L4PiPluginRuntimeBusyError"}}class x extends Error{constructor(a,b){super(b instanceof Error?b.message:String(b),{cause:b}),this.phase=a,this.name="L4PiPluginPhaseError"}}class y extends x{constructor(a,b){super(a,Error("插件加载超时,已停止本次加载")),this.execution=b,this.name="L4PiPluginLoadTimeoutError"}}function o(a,b,c){if("string"!=typeof b||!b.trim())throw Error(`package.json.${c} must be a non-empty string`);let d=(0,h.resolve)(a,b),e=(0,h.relative)(a,d);if(e.startsWith("..")||(0,h.isAbsolute)(e))throw Error(`package.json.${c} must stay inside the package root`);return d}function p(a){return a instanceof Error&&a.message?a.message:String(a)}async function q(a){let b=null,c=Promise.resolve().then(a.execute);a.owner.pendingCleanup.add(c);let d=()=>{a.owner.pendingCleanup.delete(c)};c.then(d,d);try{if(await Promise.race([c.then(()=>!0),new Promise(a=>{b=setTimeout(()=>a(!1),1500)})]))return;throw a.onTimeout?.(),Error(`插件 ${a.phase} 超时,关闭结果未确认`)}catch(b){console.warn("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 生命周期执行失败",{source:a.owner.source,packageName:a.owner.packageName,phase:a.phase,timeoutMs:1500,message:p(b)})}finally{b&&clearTimeout(b)}}class z{constructor(a,b){this.packageProvider=a,this.hostSettings=b,this.methods=new Map,this.pluginOwners=new Map,this.browserEntries=new Map,this.declarations=new Map,this.capabilityLoaders=new Map,this.owners=[],this.loadingOwners=new Set,this.changeListeners=new Set,this.changingSources=new Set,this.maintainingSources=new Set,this.lifetime=new AbortController,this.packageDiagnostics=new Map,this.recoveries=new Map,this.initializePromise=null,this.initialized=!1,this.disposed=!1,this.acceptingCalls=!0,this.loadError=null,this.workSessionProvider=null,this.pushSender=null,this.appRuntimeSink=null}initialize(){return this.disposed?Promise.reject(Error("Global plugin runtime has been disposed")):this.initialized?Promise.resolve():(this.initializePromise||(this.initializePromise=this.loadConfiguredPackages().catch(a=>{this.loadError=p(a),console.error("[Pi Desk][GlobalPluginRuntime] 读取插件配置失败,核心应用继续启动",{errorName:a instanceof Error?a.name:"UnknownError",message:this.loadError})}).finally(()=>{this.initializePromise=null,this.initialized=!0,this.publishChanges()})),this.initializePromise)}subscribeChanges(a){return this.changeListeners.add(a),()=>this.changeListeners.delete(a)}publishChanges(){if(!this.disposed)for(let a of this.changeListeners)try{a()}catch(a){console.warn("[Pi Desk][GlobalPluginRuntime] 状态监听失败",{message:p(a)})}}async withSourceIdle(a,b,c,d){let e,g=AbortSignal.any([c,this.lifetime.signal]);g.throwIfAborted();let h=new Promise((a,b)=>{e=()=>b(g.reason),g.addEventListener("abort",e,{once:!0})});try{await Promise.race([this.initialize(),h])}finally{g.removeEventListener("abort",e)}if(g.throwIfAborted(),!this.acceptingCalls||this.changingSources.has(a)||this.maintainingSources.has(a))throw new w;this.cancelRecovery(a),this.maintainingSources.add(a);let i=performance.now()+15e3;try{for(;this.owners.some(b=>b.source===a&&b.activeCalls.size>0);){if(performance.now()>=i)throw Error(`插件 ${a} 的在途调用未在15秒内结束,本次维护失败,可稍后手动重试`);d(`插件 ${a} 仍有调用正在执行`),await (0,f.setTimeout)(250,void 0,{signal:g})}return g.throwIfAborted(),await b()}finally{this.maintainingSources.delete(a)}}async replaceSource(a,b){if(await this.initialize(),this.disposed||!this.acceptingCalls||this.changingSources.has(a))throw new w;this.cancelRecovery(a);let c=this.owners.find(b=>b.source===a);this.changingSources.add(a);try{if(c&&this.releaseOwner(c),this.disposed)throw Error("Global plugin runtime has been disposed");if((0,k.N)(),this.packageDiagnostics.delete(a),null!==b){if(await this.loadPackage(a,b),this.disposed)throw Error("Global plugin runtime has been disposed");let c=this.packageDiagnostics.get(a);if(c?.status==="failed")throw Error(c.error?.message??"插件加载失败")}}finally{this.changingSources.delete(a),this.publishChanges()}}ownerPublished(a){return a.active&&!a.draining&&!this.changingSources.has(a.source)&&this.owners.includes(a)}readDiagnostics(){return{packages:[...this.packageDiagnostics.values()].sort((a,b)=>a.source.localeCompare(b.source)).map(a=>structuredClone(a)),loadError:this.loadError}}readCapabilityRegistrations(){return[...this.owners].filter(a=>this.ownerPublished(a)).sort((a,b)=>a.source.localeCompare(b.source)).map(a=>({source:a.source,methods:[...this.methods.values()].filter(b=>b.owner===a).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.method.localeCompare(b.method):c}).map(({pluginName:a,method:b})=>({pluginName:a,method:b})),browserEntries:[...this.browserEntries.values()].filter(b=>b.owner===a).sort((a,b)=>a.pluginName.localeCompare(b.pluginName)).map(({pluginName:a})=>({pluginName:a})),messageDeclarations:[...this.declarations.values()].filter(b=>b.owner===a).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.declarationName.localeCompare(b.declarationName):c}).map(({pluginName:a,declarationName:b,declaration:c})=>({pluginName:a,declarationName:b,priority:c.priority}))}))}async prepareReload(){if(await this.initialize(),this.disposed)throw Error("Global plugin runtime has been disposed");if(!this.acceptingCalls||this.changingSources.size>0||this.maintainingSources.size>0||this.owners.some(a=>a.activeCalls.size>0))throw new w;for(let a of(this.acceptingCalls=!1,this.recoveries.keys()))this.cancelRecovery(a);for(let a of this.owners)a.draining=!0;await Promise.all([...this.owners].reverse().map(async a=>{let b=a.beforeReload;if(!b)return;a.beforeReload=null;let c=new AbortController;await q({owner:a,phase:"beforeReload",execute:()=>b({signal:c.signal}),onTimeout:()=>c.abort()})}))}bindWorkSessionProvider(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.workSessionProvider=a,()=>{this.workSessionProvider===a&&(this.workSessionProvider=null)}}bindPushSender(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.pushSender=a,()=>{this.pushSender===a&&(this.pushSender=null)}}bindAppRuntimeSink(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.appRuntimeSink=a,()=>{this.appRuntimeSink===a&&(this.appRuntimeSink=null)}}async runOwnedCall(a,b){let c;if(this.ensureOwnerActive(a),this.maintainingSources.has(a.source))throw new w;let d=new AbortController,e=new Promise((a,b)=>{c=b}),f=()=>{c(Error("Pi Desk Plugin owner is no longer active"))};d.signal.addEventListener("abort",f,{once:!0}),a.activeCalls.add(d);try{let c=await Promise.race([Promise.resolve().then(()=>(this.ensureOwnerActive(a),b(d.signal))),e]);return this.ensureOwnerActive(a),c}finally{a.activeCalls.delete(d),d.signal.removeEventListener("abort",f)}}async invoke(a,b,c){if(await this.initialize(),this.disposed)throw Error("Global plugin runtime has been disposed");if(!this.acceptingCalls)throw new w;let d=(0,m.FX)(a),e=(0,m.QK)(b),f=this.methods.get((0,m.$m)(d,e));if(!f)throw new m.Tk(d,e);if(!this.ownerPublished(f.owner)||this.changingSources.has(f.owner.source))throw new w;let g=(0,m.nJ)(c,"input");return this.runOwnedCall(f.owner,async a=>{let b=await f.execute(g,{signal:a});return(0,m.nJ)(b,"output")})}async listCapabilityDeclarations(){if(await this.initialize(),this.disposed||!this.acceptingCalls)throw new w;let a=await Promise.all([...this.capabilityLoaders].filter(([,a])=>this.ownerPublished(a.owner)&&!this.changingSources.has(a.owner.source)).map(async([a,b])=>{try{return await this.runOwnedCall(b.owner,async c=>{let d=await b.load({signal:c});if(this.capabilityLoaders.get(a)!==b)throw Error(`能力声明已被替换:${a}`);return[a,j.dO.parse(d)]})}catch(b){throw Error(`读取 ${a} 能力选项失败:${p(b)}`,{cause:b})}}));return Object.fromEntries(a)}async listBrowserEntries(){return await this.initialize(),[...this.browserEntries.values()].filter(a=>this.ownerPublished(a.owner)).sort((a,b)=>a.pluginName.localeCompare(b.pluginName)).flatMap(({pluginName:a,entryPath:b,resourceKey:c,snapshot:d})=>d?[{pluginName:a,entryPath:b,resourceKey:c,snapshot:d}]:[])}async listMessageDeclarations(){return await this.initialize(),this.readMessageDeclarations()}readMessageDeclarations(){return[...this.declarations.values()].filter(a=>this.ownerPublished(a.owner)).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.declarationName.localeCompare(b.declarationName):c}).map(({pluginName:a,declarationName:b,declaration:c})=>({pluginName:a,declarationName:b,declaration:c}))}async dispose(){if(this.disposed)return;for(let a of(this.disposed=!0,this.lifetime.abort(),this.recoveries.keys()))this.cancelRecovery(a);this.acceptingCalls=!1,this.changeListeners.clear(),this.workSessionProvider=null,this.pushSender=null;let a=[...new Set([...this.owners,...this.loadingOwners])].reverse();this.owners.length=0,this.loadingOwners.clear(),await Promise.all(a.map(a=>this.releaseOwner(a))),this.methods.clear(),this.pluginOwners.clear(),this.browserEntries.clear(),this.declarations.clear(),this.capabilityLoaders.clear(),this.appRuntimeSink=null}async loadConfiguredPackages(){for(let a of(this.loadError=null,this.packageDiagnostics.clear(),await this.packageProvider())){if(this.disposed)return;let b=await this.loadPackage(a.source,a.installedPath);b&&!this.disposed&&this.recoveries.set(a.source,{installedPath:a.installedPath,settled:b.execution,controller:new AbortController})}for(let[a,b]of this.recoveries)this.recoverSource(a,b)}cancelRecovery(a){let b=this.recoveries.get(a);this.recoveries.delete(a),b?.controller.abort()}async recoverSource(a,b){let c,d=b.controller.signal,e=new Promise((a,b)=>{c=()=>b(d.reason),d.addEventListener("abort",c,{once:!0})});try{await Promise.race([b.settled,e]),d.throwIfAborted(),console.info("[Pi Desk][GlobalPluginRuntime] 插件加载超时,稍后自动重试一次",{source:a,delayMs:1e4}),await (0,f.setTimeout)(1e4,void 0,{signal:d}),d.throwIfAborted(),this.recoveries.delete(a),await this.replaceSource(a,b.installedPath),console.info("[Pi Desk][GlobalPluginRuntime] 插件自动重试成功",{source:a})}catch(b){d.aborted||console.warn("[Pi Desk][GlobalPluginRuntime] 插件自动重试失败,不再自动加载",{source:a,message:p(b)})}finally{d.removeEventListener("abort",c),this.recoveries.get(a)===b&&this.recoveries.delete(a)}}async loadOwnerWithinDeadline(a,b,c){let d,e="entry",f=performance.now(),g=()=>{let b=Math.round(performance.now()-f);b<1e3||console.info("[Pi Desk][GlobalPluginRuntime] 插件加载阶段耗时",{source:a.source,packageName:a.packageName,phase:e,durationMs:b})},h=a=>{g(),e=a,f=performance.now()},i=(async()=>{let d=()=>h("setup");void 0!==b?await this.loadEntryOwner(a,b,d):await this.loadLegacyOwner(a,c,d),h("resources");try{await this.validateOwnerResources(a)}catch(a){throw new x("resources",a)}this.ensureOwnerActive(a)})();try{await Promise.race([i,new Promise((a,b)=>{d=setTimeout(()=>{b(new y(e,i))},15e3)})])}finally{d&&clearTimeout(d),g()}}async loadPackage(a,b){let c,d=performance.now(),e=(0,h.resolve)(b);try{let a=(0,h.join)(e,"package.json");c=JSON.parse(await (0,g.readFile)(a,"utf8"))}catch(b){return this.packageDiagnostics.set(a,{source:a,packageName:null,version:null,pluginName:null,status:"failed",error:{phase:"package",message:p(b)}}),null}let f=c.piDesk?.entry,i=c.piDesk?.global;if(void 0===f&&void 0===i||this.disposed)return null;let j={source:a,packageName:"string"==typeof c.name?c.name:null,version:"string"==typeof c.version?c.version:null,packageRoot:e,active:!0,draining:!1,pluginNames:new Set,activeCalls:new Set,subscriptions:new Set,pendingCleanup:new Set,beforeReload:null,disposer:null};console.info("[Pi Desk][GlobalPluginRuntime] 开始加载 Pi Desk Plugin",{source:a,packageName:j.packageName}),this.loadingOwners.add(j);try{await this.loadOwnerWithinDeadline(j,f,i),this.owners.push(j),this.recordOwnerDiagnostic(j),console.info("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 已加载",{source:a,packageName:j.packageName,pluginNames:[...j.pluginNames],methodCount:[...this.methods.values()].filter(a=>a.owner===j).length,browserEntryCount:[...this.browserEntries.values()].filter(a=>a.owner===j).length,declarationCount:[...this.declarations.values()].filter(a=>a.owner===j).length,durationMs:Math.round(performance.now()-d)})}catch(f){let b=f instanceof x?f.phase:"entry",c=[...j.pluginNames][0]??null;await this.releaseOwner(j);let e=p(f);if(this.packageDiagnostics.set(a,{source:a,packageName:j.packageName,version:j.version,pluginName:c,status:"failed",error:{phase:b,message:e}}),console.warn("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 加载失败",{source:a,packageName:j.packageName,phase:b,errorName:f instanceof Error?f.name:"UnknownError",message:e,durationMs:Math.round(performance.now()-d)}),f instanceof y)return{execution:f.execution.catch(()=>{}).then(async()=>{await Promise.allSettled([...j.pendingCleanup])})}}finally{this.loadingOwners.delete(j)}return null}async loadEntryOwner(a,b,c){let d=o(a.packageRoot,b,"piDesk.entry");if(!(await (0,g.stat)(d)).isFile())throw Error("Pi Desk Plugin entry is not a file");let e=(await (0,k.G)(d,a.packageRoot)).default;if(!e||"object"!=typeof e||"string"!=typeof e.name||"function"!=typeof e.setup)throw Error("Pi Desk Plugin entry must default-export definePiDeskPlugin(...)");let f=(0,m.FX)(e.name);this.claimPluginName(a,f),c();try{let b=function(a){if(void 0===a)return{beforeReload:null,disposer:null};if("function"==typeof a)return{beforeReload:null,disposer:a};if(!a||"object"!=typeof a)throw Error("Pi Desk Plugin setup must return void, a disposer, or a lifecycle object");if(void 0!==a.beforeReload&&"function"!=typeof a.beforeReload)throw Error("Pi Desk Plugin lifecycle.beforeReload must be a function");if(void 0!==a.dispose&&"function"!=typeof a.dispose)throw Error("Pi Desk Plugin lifecycle.dispose must be a function");return{beforeReload:a.beforeReload??null,disposer:a.dispose??null}}(await e.setup(this.createPiDeskFacade(a,f,a.packageRoot)));if(a.beforeReload=b.beforeReload,a.disposer=b.disposer,!a.active||this.disposed)throw await this.releaseOwner(a),Error("插件初始化完成时 Owner 已失效")}catch(a){throw new x("setup",a)}}async loadLegacyOwner(a,b,c){let d=o(a.packageRoot,b,"piDesk.global");if(!(await (0,g.stat)(d)).isFile())throw Error("Global Plugin entry is not a file");let e=await (0,k.G)(d,a.packageRoot);if("function"!=typeof e.default)throw Error("Global Plugin entry must default-export a factory function");let f=e.default;c();try{let b=await f(this.createLegacyApi(a));if(void 0!==b&&"function"!=typeof b)throw Error("Global Plugin factory must return void or a disposer function");if(a.disposer=b??null,!a.active||this.disposed)throw await this.releaseOwner(a),Error("插件初始化完成时 Owner 已失效")}catch(a){throw new x("setup",a)}}claimPluginName(a,b){this.ensureOwnerActive(a);let c=this.pluginOwners.get(b);if(c&&c!==a)throw Error(`Pi Desk pluginName is already registered: ${b}`);this.pluginOwners.set(b,a),a.pluginNames.add(b)}createLegacyApi(a){return{bindPlugin:b=>{let c=(0,m.FX)(b);return this.claimPluginName(a,c),{name:c,registerMethod:(b,d)=>this.registerMethod(a,c,b,d)}}}}createPiDeskFacade(a,b,c){return{name:b,host:{settings:{getSnapshot:()=>{if(this.ensureOwnerActive(a),!this.hostSettings)throw Error("宿主共享设置尚未就绪");return this.hostSettings.getSnapshot()},subscribe:b=>{if(this.ensureOwnerActive(a),!this.hostSettings)throw Error("宿主共享设置尚未就绪");let c=this.hostSettings.subscribe(()=>{a.active&&!a.draining&&b()});return a.subscriptions.add(c),()=>{if(a.subscriptions.delete(c))return c()}}},workSessions:{listWorkSessions:async()=>{this.ensureOwnerActive(a);let b=await this.readWorkSessions();return this.ensureOwnerActive(a),b}}},notifications:{publish:c=>(this.ensureOwnerActive(a),this.requireAppRuntimeSink().publishNotification(b,c)),update:(c,d)=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().updateNotification(b,c,d)},delete:c=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().deleteNotification(b,c)}},setState:c=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().setState(b,c)},registerMethod:(c,d)=>this.registerMethod(a,b,c,d),registerBrowserEntry:d=>{if(this.ensureOwnerActive(a),this.browserEntries.has(b))throw Error(`Browser Entry is already registered: ${b}`);let f=o(c,d,"browserEntry"),g={pluginName:b,entryPath:f,resourceKey:(0,e.randomUUID)(),snapshot:null,owner:a};return this.browserEntries.set(b,g),this.registrationDisposer(a,()=>{this.browserEntries.get(b)===g&&this.browserEntries.delete(b)})},declareCapabilities:c=>{if(this.ensureOwnerActive(a),"function"!=typeof c)throw Error("能力声明必须是按需查询函数");if(this.capabilityLoaders.has(b))throw Error(`能力声明已注册:${b}`);let d={load:c,owner:a};return this.capabilityLoaders.set(b,d),this.registrationDisposer(a,()=>{this.capabilityLoaders.get(b)===d&&this.capabilityLoaders.delete(b)})},declareMessage:(c,d)=>this.registerDeclaration(a,b,c,d),pushGlobal:(c,d)=>{a.active&&!a.draining&&this.sendPush(b,{scope:"global"},c,d)},pushSession:(c,d,e)=>{a.active&&!a.draining&&this.sendPush(b,{scope:"session",source:s.parse(c)},d,e)}}}registerMethod(a,b,c,d){this.ensureOwnerActive(a);let e=(0,m.QK)(c),f=(0,m.$m)(b,e);if(this.methods.has(f))throw new m.qs(b,e);let g={pluginName:b,method:e,execute:d,owner:a};return this.methods.set(f,g),this.registrationDisposer(a,()=>{this.methods.get(f)===g&&this.methods.delete(f)})}registerDeclaration(a,b,c,d){var e;this.ensureOwnerActive(a);let f=u.parse(c);if(!d||"object"!=typeof d||"function"!=typeof d.match||"function"!=typeof d.project)throw Error("Message Declaration must provide match and project functions");let g={priority:(e=d.priority,v.parse(e)),match:d.match,project:d.project},h=`${b}\u0000${f}`;if(this.declarations.has(h))throw Error(`Message Declaration is already registered: ${b}/${f}`);let i={pluginName:b,declarationName:f,declaration:g,owner:a};return this.declarations.set(h,i),this.registrationDisposer(a,()=>{this.declarations.get(h)===i&&this.declarations.delete(h)})}registrationDisposer(a,b){let c=!0;return()=>{c&&(c=!1,a.active&&b())}}requireAppRuntimeSink(){if(!this.appRuntimeSink)throw Error("App Runtime sink has not been bound");return this.appRuntimeSink}sendPush(a,b,c,d){if(this.disposed)return;let e=(0,m.QK)(c),f=function(a){let b=r.parse(a);if(Buffer.byteLength(JSON.stringify(b),"utf8")>65536)throw Error("Plugin Push data exceeds 64KB");return b}(d);this.pushSender?.({pluginName:a,target:b,event:e,data:structuredClone(f)})}async readWorkSessions(){if(!this.workSessionProvider||this.disposed)return[];let a=await this.workSessionProvider();return i.YO(t).parse(a).map(a=>structuredClone(a))}async validateOwnerResources(a){for(let b of[...this.browserEntries.values()].filter(b=>b.owner===a)){if(!(await (0,g.stat)(b.entryPath)).isFile())throw Error("Browser Entry resource is not a file");if("entry.js"!==(0,h.basename)(b.entryPath))throw Error("Browser Entry resource file must be named entry.js");let c=await (0,l.f)(b.entryPath);if(this.ensureOwnerActive(a),[...this.browserEntries.values()].reduce((a,b)=>a+(b.snapshot?.size??0),0)+c.size>0x8000000)throw Error("Browser 模块快照总量超过128MB,拒绝加载此插件");b.snapshot=c}}recordOwnerDiagnostic(a){this.packageDiagnostics.set(a.source,{source:a.source,packageName:a.packageName,version:a.version,pluginName:[...a.pluginNames][0]??null,status:"ready",error:null})}ensureOwnerActive(a){if(!a.active||a.draining||this.disposed)throw Error("Pi Desk Plugin owner is no longer active")}async releaseOwner(a){let b=[...a.subscriptions];if(a.subscriptions.clear(),a.active){for(let b of(a.active=!1,a.activeCalls))b.abort();a.activeCalls.clear();let b=this.owners.indexOf(a);for(let[c,d]of(b>=0&&this.owners.splice(b,1),this.methods))d.owner===a&&this.methods.delete(c);for(let[b,c]of this.browserEntries)c.owner===a&&this.browserEntries.delete(b);for(let[b,c]of this.declarations)c.owner===a&&this.declarations.delete(b);for(let[b,c]of this.capabilityLoaders)c.owner===a&&this.capabilityLoaders.delete(b);for(let b of a.pluginNames)if(this.pluginOwners.get(b)===a){this.pluginOwners.delete(b);try{this.appRuntimeSink?.releasePlugin(b)}catch(a){console.warn("[Pi Desk][GlobalPluginRuntime] 清理插件 App Runtime 失败",{pluginName:b,errorName:a instanceof Error?a.name:"UnknownError",message:p(a)})}}a.pluginNames.clear()}let c=a.beforeReload,d=a.disposer;a.beforeReload=null,a.disposer=null;let e=new AbortController;await Promise.all([...b.map(b=>q({owner:a,phase:"dispose",execute:b})),c?q({owner:a,phase:"beforeReload",execute:()=>c({signal:e.signal}),onTimeout:()=>e.abort()}):Promise.resolve(),d?q({owner:a,phase:"dispose",execute:d}):Promise.resolve()])}}d()}catch(a){d(a)}})},46107:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Nx:()=>n,cY:()=>m,sv:()=>o,to:()=>l});var e=c(73024),f=c(76760),g=c(77598),h=c(75430),i=c(59473),j=c(58417),k=a([h]);h=(k.then?(await k)():k)[0];let n="https://registry.npmjs.org",o="https://mirrors.cloud.tencent.com/npm",p=i.Ik({downloadSource:j.w3.default({mode:"auto"}),disabled:i.YO(i.Yj()).max(2e3).default([]),registries:i.g1(i.Yj(),j.SZ).default({}),updateTags:i.g1(i.Yj(),j.mR).default({})}).strict();function l(a=(0,h.getAgentDir)()){let b=(0,f.join)(a,"pi-desk-plugins.json");return(0,e.existsSync)(b)?p.parse(JSON.parse((0,e.readFileSync)(b,"utf8"))):p.parse({})}function m(a,b=(0,h.getAgentDir)()){!function(a,b){let c=(0,f.join)(a,"pi-desk-plugins.json"),d=p.parse(b(l(a)));(0,e.mkdirSync)((0,f.dirname)(c),{recursive:!0});let h=`${c}.${(0,g.randomUUID)()}.tmp`;try{(0,e.writeFileSync)(h,`${JSON.stringify(d,null,2)}
20
20
  `,"utf8"),(0,e.renameSync)(h,c)}finally{(0,e.rmSync)(h,{force:!0})}}(b,b=>({...b,downloadSource:a}))}d()}catch(a){d(a)}})},46524:(a,b,c)=>{c.d(b,{Ns:()=>f,cg:()=>n,dX:()=>g,eD:()=>q,j0:()=>o,u3:()=>p});var d=c(12727);let e=new WeakMap;class f extends Error{constructor(a){super(`Pi session entry was not found: ${a}`),this.name="L4PiSessionEntryNotFoundError"}}class g extends Error{constructor(a){super(`Pi session fork target is not a user message: ${a}`),this.name="L4PiSessionForkTargetError"}}function h(a){return"string"==typeof a?a:Array.isArray(a)?a.flatMap(a=>a&&"object"==typeof a&&"text"===a.type&&"string"==typeof a.text?[a.text]:[]).join("\n"):""}function i(a){return Array.isArray(a)?a.filter(a=>null!==a&&"object"==typeof a&&"image"===a.type).length:0}function j(a){let b=a.replace(/\s+/g," ").trim();return b.length<=240?b:`${b.slice(0,239)}…`}function k(a){try{return JSON.stringify(a,null,2)??""}catch{return""}}function l(a){let b=a.getEntries(),c=e.get(a);if(c?.entryCount===b.length)return c.callsById;let f=new Map;for(let a of b)if("message"===a.type&&"assistant"===a.message.role)for(let b of(0,d.zz)(a.message.content))f.set(b.id,{name:b.name,input:b.input,display:(0,d.zG)(b.name,b.input)});return e.set(a,{entryCount:b.length,callsById:f}),f}function m(a){switch(a.type){case"message":switch(a.message.role){case"user":return"user";case"assistant":return"assistant";case"toolResult":return"tool";case"bashExecution":return"bash";case"custom":return"custom_message";default:return"custom"}case"custom_message":return"custom_message";case"compaction":return"compaction";case"branch_summary":return"branch_summary";case"custom":case"context_edit":case"usage":return"custom";case"model_change":return"model_change";case"thinking_level_change":return"thinking_level_change";case"session_info":return"session_info";case"label":return"label"}}function n(a,b){let c=l(a);return{sessionId:a.getSessionId(),leafEntryId:a.getLeafId(),nodes:a.getEntries().map(d=>({entryId:d.id,parentEntryId:d.parentId,timestampMs:function(a){let b=Date.parse(a.timestamp);if(!Number.isSafeInteger(b)||b<0)throw Error(`Pi session entry has an invalid timestamp: ${a.id}`);return b}(d),kind:m(d),preview:function(a,b,c){switch(a.type){case"message":let d=a.message;switch(d.role){case"user":{let a=h(d.content),b=i(d.content);return j(a||(b>0?`${b} 张图片`:""))}case"assistant":{let a=h(d.content);if(a)return j(a);if(d.errorMessage)return j(d.errorMessage);return"aborted"===d.stopReason?"已中断":""}case"toolResult":return function(a,b){if(!b)return j(a);let c=b.display.inputPreview??function(a){try{let b=JSON.stringify(a);return"{}"===b?"":j(b)}catch{return""}}(b.input),d=c?`${b.name}: ${c}`:b.name;return j(b.display.activity?`${d} \xb7 ${b.display.activity}`:d)}(d.toolName,b.get(d.toolCallId));case"bashExecution":return j(d.command);case"custom":return j(h(d.content));default:return""}case"custom_message":return j(h(a.content));case"compaction":case"branch_summary":return j(a.summary);case"custom":return j(a.customType);case"context_edit":return j(`${null===a.replacement?"从上下文移除":"替换上下文内容"}:${a.targetId}`);case"usage":return j(`用量记录:${a.kind}`);case"model_change":return j(`${a.provider}/${c?.getModel(a.provider,a.modelId)?.name||a.modelId}`);case"thinking_level_change":return j(a.thinkingLevel);case"session_info":return j(a.name??"");case"label":return j(a.label??"已清除标签")}}(d,c,b),label:a.getLabel(d.id)?.trim()||null}))}}function o(a,b,c){let d=a.getEntry(b);if(!d)throw new f(b);let e=function(a,b,c){switch(a.type){case"message":let d=a.message;switch(d.role){case"user":{let a=h(d.content),b=i(d.content);return[a,b>0?`[图片 ${b} 张]`:""].filter(Boolean).join("\n\n")}case"assistant":return h(d.content)||d.errorMessage||("aborted"===d.stopReason?"已中断":"");case"toolResult":return function(a,b){if(!b)return`工具:${a}
@@ -23,7 +23,7 @@ ${this.initialization.describeStage()}`))}async runSessionLifecycle(a,b=15e3){if
23
23
  目标节点:${a.targetId}`;case"usage":return`用量记录:${a.kind}
24
24
  模型:${a.provider}/${a.model}
25
25
 
26
- ${k(a.usage)}`;case"model_change":return`${a.provider}/${c?.getModel(a.provider,a.modelId)?.name||a.modelId}`;case"thinking_level_change":return a.thinkingLevel;case"session_info":return a.name??"";case"label":return a.label??"已清除标签"}}(d,l(a),c);return{entryId:b,kind:m(d),content:e.length<=65536?e:e.slice(0,65536),truncated:e.length>65536}}function p(a,b){let c=a.getEntry(b);if(!c)throw new f(b);if("message"!==c.type||"user"!==c.message.role)throw new g(b);return{selectedEntryId:b,targetLeafEntryId:c.parentId,editorText:h(c.message.content)}}function q(a,b){let c=a.getEntry(b);if(!c)throw new f(b);return a.getLeafId()===b?{selectedEntryId:b,targetLeafEntryId:b,editorText:null,changed:!1}:"message"===c.type&&"user"===c.message.role?{selectedEntryId:b,targetLeafEntryId:c.parentId,editorText:h(c.message.content),changed:a.getLeafId()!==c.parentId}:"custom_message"===c.type?{selectedEntryId:b,targetLeafEntryId:c.parentId,editorText:h(c.content),changed:a.getLeafId()!==c.parentId}:{selectedEntryId:b,targetLeafEntryId:b,editorText:null,changed:!0}}},47511:(a,b,c)=>{c.d(b,{Dl:()=>o,Qg:()=>m,RC:()=>q,a4:()=>k,dO:()=>j,j0:()=>n});var d=c(59473);let e=d.Yj().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=d.Yj().trim().min(1).max(256),g=d.Ik({allow:d.YO(f).max(5e3).optional(),deny:d.YO(f).max(5e3).optional()}).strict(),h=d.Ik({value:d.Yj().trim().min(1).max(256),label:d.Yj().trim().min(1).max(120).optional(),description:d.Yj().trim().max(1e3).optional()}).strict(),i=d.Ik({label:d.Yj().trim().min(1).max(120),options:d.YO(h).max(5e3)}).strict(),j=d.g1(e,i),k=d.Yj().min(1).max(64),l=d.Ik({name:d.Yj().trim().min(1).max(64),tools:g.optional(),skills:g.optional(),plugins:d.g1(e,d.g1(e,g)).optional()}).strict(),m=d.g1(k,l).refine(a=>Object.keys(a).length<=100,"最多保存 100 个能力模式").refine(a=>new Set(Object.values(a).map(a=>a.name)).size===Object.keys(a).length,"模式名称不能重复"),n=d.g1(k,l.shape.name),o=d.Ik({tools:d.YO(h),skills:d.YO(h),plugins:d.g1(e,j)}).strict();function p(a,b){let c=0,d=0,e=-1,f=0;for(;d<b.length;)if("*"===a[c])e=c++,f=d;else if(a[c]===b[d])c+=1,d+=1;else{if(!(e>=0))return!1;c=e+1,d=++f}for(;"*"===a[c];)c+=1;return c===a.length}function q(a,b){return(a?.allow===void 0||a.allow.some(a=>p(a,b)))&&!a?.deny?.some(a=>p(a,b))}d.Ik({tools:g,skills:g,capabilities:d.g1(e,g)}).strict()},49080:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{A:()=>l});var e=c(73024),f=c(76760),g=c(75430),h=c(78262),i=c(28802),j=a([g,h,i]);[g,h,i]=j.then?(await j)():j;let m=new Set(["off","minimal","low","medium","high","xhigh","max"]);function k(a,b){return`${a}\u0000${b}`}async function l(a,b=process.cwd()){let c=(0,g.getAgentDir)(),d=a?.modelRuntime??await g.ModelRuntime.create({authPath:(0,f.join)(c,"auth.json"),modelsPath:(0,f.join)(c,"models.json")}),j=a?.settingsManager??g.SettingsManager.create(b,c);await d.refresh({allowNetwork:!1});let n=j.getEnabledModels(),o=n?.length?(await (0,g.resolveModelScopeWithDiagnostics)(n,d)).scopedModels.map(a=>a.model):[...await d.getAvailable()],p=new Map;for(let a of(0,h.oj)(o,d))p.set(k(a.provider,a.id),a);let q=[...p.values()].map(a=>({provider:a.provider,modelId:a.id,name:a.name,input:[...a.input],kind:d.getPhysicalModel(a.provider,a.id)?"physical":"virtual",contextWindow:a.contextWindow>0?a.contextWindow:null,thinkingLevels:[...(0,i.getSupportedThinkingLevels)(a)]})),r=new Map(q.map(a=>[k(a.provider,a.modelId),a])),s=[],t=0;for(let a of function(){let a=(0,f.join)((0,g.getAgentDir)(),"models.json");if(!(0,e.existsSync)(a))return[];try{let b=JSON.parse((0,e.readFileSync)(a,"utf8"));return Array.isArray(b.modelPresets)?b.modelPresets:[]}catch(b){return console.warn("[Pi Desk][PiModelCatalog] models.json 读取失败",{path:a,errorName:b instanceof Error?b.name:"UnknownError"}),[]}}()){if("string"!=typeof a.provider||!a.provider.trim()||"string"!=typeof a.modelId||!a.modelId.trim()||"string"!=typeof a.thinkingLevel||!m.has(a.thinkingLevel)||void 0!==a.color&&null!==a.color&&"string"!=typeof a.color){t+=1;continue}let b=a.thinkingLevel,c=r.get(k(a.provider,a.modelId));if(!c||!c.thinkingLevels.includes(b)){t+=1;continue}s.push({provider:a.provider,modelId:a.modelId,thinkingLevel:b,color:"string"==typeof a.color&&a.color.trim()?a.color:null})}return t>0&&console.warn("[Pi Desk][PiModelCatalog] 已忽略无效或不可用的模型预设",{cwd:a?.sessionManager.getCwd()??b,count:t}),{models:q,presets:s}}d()}catch(a){d(a)}})},54174:(a,b,c)=>{c.d(b,{Z:()=>i,f1:()=>j});let d=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;class e extends Error{constructor(a){super(a),this.name="L4PiImageValidationError"}}function f(a,b){if(!Number.isSafeInteger(a)||a<=0)throw new e(`图片 ${b} 无效`);return a}let g=new Set([192,193,194,195,197,198,199,201,202,203,205,206,207]);function h(a,b){return a[b]|a[b+1]<<8|a[b+2]<<16}function i(a){if(!a||a.startsWith("data:")||!d.test(a))throw new e("图片 Base64 无效");let b=Buffer.from(a,"base64");if(0===b.length)throw new e("图片内容为空");let c=function(a){if(a.length>=8&&137===a[0]&&80===a[1]&&78===a[2]&&71===a[3]&&13===a[4]&&10===a[5]&&26===a[6]&&10===a[7])return"image/png";if(a.length>=3&&255===a[0]&&216===a[1]&&255===a[2])return"image/jpeg";if(a.length>=10&&["GIF87a","GIF89a"].includes(a.toString("ascii",0,6)))return"image/gif";if(a.length>=16&&"RIFF"===a.toString("ascii",0,4)&&"WEBP"===a.toString("ascii",8,12))return"image/webp";throw new e("图片格式不受支持")}(b);return{bytes:b,metadata:{mimeType:c,...function(a,b){switch(b){case"image/png":if(a.length<24||"IHDR"!==a.toString("ascii",12,16))throw new e("PNG 图片头无效");return{width:f(a.readUInt32BE(16),"宽度"),height:f(a.readUInt32BE(20),"高度")};case"image/jpeg":let c=2;for(;c+3<a.length;){for(;c<a.length&&255!==a[c];)c+=1;for(;c<a.length&&255===a[c];)c+=1;if(c>=a.length)break;let b=a[c];if(c+=1,216===b||1===b||b>=208&&b<=215)continue;if(217===b||218===b||c+1>=a.length)break;let d=a.readUInt16BE(c);if(d<2||c+d>a.length)break;if(g.has(b)){if(d<7)break;return{width:f(a.readUInt16BE(c+5),"宽度"),height:f(a.readUInt16BE(c+3),"高度")}}c+=d}throw new e("JPEG 图片尺寸无效");case"image/gif":if(a.length<10)throw new e("GIF 图片头无效");return{width:f(a.readUInt16LE(6),"宽度"),height:f(a.readUInt16LE(8),"高度")};case"image/webp":return function(a){let b=a.toString("ascii",12,16);if("VP8X"===b){if(a.length<30)throw new e("WebP VP8X 图片头无效");return{width:f(h(a,24)+1,"宽度"),height:f(h(a,27)+1,"高度")}}if("VP8L"===b){if(a.length<25||47!==a[20])throw new e("WebP VP8L 图片头无效");let b=a[21],c=a[22],d=a[23],g=a[24];return{width:f(1+((63&c)<<8|b),"宽度"),height:f(1+((15&g)<<10|d<<2|(192&c)>>6),"高度")}}if("VP8 "===b){if(a.length<30||157!==a[23]||1!==a[24]||42!==a[25])throw new e("WebP VP8 图片头无效");return{width:f(16383&a.readUInt16LE(26),"宽度"),height:f(16383&a.readUInt16LE(28),"高度")}}throw new e("WebP 图片编码无效")}(a)}}(b,c)}}}function j(a){let b=i(a.data);if(b.metadata.mimeType!==a.mimeType)throw new e("图片 MIME 与实际内容不一致");if(b.metadata.width!==a.width||b.metadata.height!==a.height)throw new e("图片尺寸与实际内容不一致");return b}},56752:(a,b,c)=>{c.d(b,{C:()=>f,b:()=>e});var d=c(76760);function e(a){return"win32"===process.platform?a.toLocaleLowerCase():a}function f(a,b){let c=(0,d.relative)(a,b);return""===c||!c.startsWith(`..${d.sep}`)&&".."!==c&&!(0,d.isAbsolute)(c)}},56971:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{o:()=>o});var e=c(51455),f=c(48161),g=c(76760),h=c(58417),i=c(73589),j=a([i]);function k(a,b){let c=(0,g.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,g.isAbsolute)(c)}async function l(a){try{return await (0,e.realpath)(a)}catch{return(0,g.resolve)(a)}}function m(a){return"win32"===process.platform?a.toLowerCase():a}async function n(a){try{if((await (0,e.stat)(a)).isFile())return{version:null,description:null,hasNodeEntry:!1,error:null};let b=JSON.parse(await (0,e.readFile)((0,g.join)(a,"package.json"),"utf8"));if(!b||"object"!=typeof b||Array.isArray(b))throw Error("package.json 必须是对象");return{version:"string"==typeof b.version?b.version:null,description:(0,h._C)(b),hasNodeEntry:b.piDesk?.entry!==void 0||b.piDesk?.global!==void 0,hasNativeEntries:Array.isArray(b.pi?.extensions)&&b.pi.extensions.length>0,error:null}}catch(a){if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return{version:null,description:null,hasNodeEntry:!1,error:null};return{version:null,description:null,hasNodeEntry:!1,error:a instanceof Error?a.message:String(a)}}}async function o(a,b,c){let d=c.SettingsManager.create(a,b,{projectTrusted:!1}),h=new c.DefaultPackageManager({cwd:a,agentDir:b,settingsManager:d}),j=d.drainErrors().map(({error:a})=>a.message),o=new Map,p=new Map;for(let a of h.listConfiguredPackages()){if("user"!==a.scope)continue;let b=a.installedPath?await l(a.installedPath):null,c=b?await n(b):null,d=b?p.get(m(b)):void 0;b&&!d&&p.set(m(b),a.source),o.set(a.source,{source:a.source,kind:"package",path:b,nativePaths:[],hasPiResources:!0,piDeskRoot:b&&c?.hasNodeEntry&&!d?b:null,version:c?.version??null,description:c?.description??null,enabled:!0,error:d?`此目录已由 ${d} 声明,不能重复加载`:b?c?.error??null:"插件包未安装或安装目录不存在"})}let q=(0,g.join)(b,"extensions"),r=new Set;try{for(let a of(await (0,e.readdir)(q,{withFileTypes:!0})))if(!a.name.startsWith(".")&&"node_modules"!==a.name&&(a.isDirectory()||a.isSymbolicLink()))try{let b=await l((0,g.join)(q,a.name));(await (0,e.stat)(b)).isDirectory()&&r.add(b)}catch(b){j.push(`${a.name}: ${b instanceof Error?b.message:String(b)}`)}}catch(a){a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code||j.push(a instanceof Error?a.message:String(a))}for(let a of d.getGlobalSettings().extensions??[]){if(/^[!+-]|[?*{}]/.test(a))continue;let c=await l(a.startsWith("~/")?(0,g.join)((0,f.homedir)(),a.slice(2)):(0,g.resolve)(b,a));try{(await (0,e.stat)(c)).isDirectory()&&r.add(c)}catch{}}let s=[...r].sort((a,b)=>b.length-a.length);try{let a=await h.resolve(async a=>{let b=o.get(a);return b&&(b.error??="插件包未安装或版本不匹配"),"skip"});for(let a of o.values())a.hasPiResources=!1;for(let b of[...a.extensions,...a.skills,...a.prompts,...a.themes])if(b.enabled&&"user"===b.metadata.scope&&"package"===b.metadata.origin){let a=o.get(b.metadata.source);a&&(a.hasPiResources=!0)}for(let b of a.extensions){if("user"!==b.metadata.scope)continue;let a=await l(b.path);if("package"===b.metadata.origin){let c=o.get(b.metadata.source);c&&b.enabled&&!c.nativePaths.includes(a)&&c.nativePaths.push(a);continue}let c=s.find(b=>k(b,a))??a,d=[...p].find(([b])=>k(b,m(a)));if(d){let c=o.get(d[1]);b.enabled&&c&&!c.nativePaths.includes(a)&&c.nativePaths.push(a),j.push(`扩展入口 ${a} 与已配置包 ${d[1]} 重复,保留包来源`);continue}let e=o.get(c);e||(e={source:c,kind:"extension",path:c,nativePaths:[],piDeskRoot:null,version:null,description:null,enabled:!1,error:null},o.set(c,e)),b.enabled&&(e.enabled=!0,e.nativePaths.includes(a)||e.nativePaths.push(a))}}catch(a){j.push(a instanceof Error?a.message:String(a))}for(let a of s){if([...p.keys()].some(b=>k(b,m(a))))continue;let b=await n(a),c=o.get(a);if(!c&&!b.hasNodeEntry&&!b.error)continue;let d=(await Promise.all(["index.ts","index.js"].map(b=>(0,e.stat)((0,g.join)(a,b)).then(a=>a.isFile(),()=>!1)))).some(Boolean),f=c??{source:a,kind:"extension",path:a,nativePaths:[],piDeskRoot:null,version:null,description:null,enabled:!b.hasNativeEntries&&!d,error:null};f.version=b.version,f.description=b.description,f.error=b.error,b.hasNodeEntry&&f.enabled&&(f.piDeskRoot=a),o.set(a,f)}let t=await (0,i.n)(b,h,d);for(let a of o.values())await t(a.source,a.path,"package"===a.kind)&&(a.enabled=!1);return{sources:[...o.values()].sort((a,b)=>a.source.localeCompare(b.source)),errors:j}}i=(j.then?(await j)():j)[0],d()}catch(a){d(a)}})},58417:(a,b,c)=>{c.d(b,{LD:()=>k,SZ:()=>f,_C:()=>j,mR:()=>e,w3:()=>g});var d=c(59473);let e=d.Yj().trim().min(1).max(128).regex(/^[a-zA-Z][a-zA-Z0-9._-]*$/),f=d.Yj().trim().url().max(2048).refine(a=>{let b=new URL(a);return["https:","http:"].includes(b.protocol)&&!b.username&&!b.password&&!b.search&&!b.hash},"插件源必须是 HTTP 或 HTTPS 仓库地址"),g=d.gM("mode",[d.Ik({mode:d.eu("auto")}).strict(),d.Ik({mode:d.eu("local")}).strict(),d.Ik({mode:d.eu("official")}).strict(),d.Ik({mode:d.eu("domestic")}).strict(),d.Ik({mode:d.eu("custom"),registry:f}).strict()]),h=d.Ik({description:d.Yj().trim().min(1).max(4e3).optional(),readme:d.Yj().trim().min(1).max(1024).optional()}),i=d.Ik({description:d.Yj().optional(),piDesk:d.Ik({i18n:d.g1(d.Yj().min(1).max(35),h).optional()}).passthrough().optional()}).passthrough();function j(a){let b=i.safeParse(a);if(!b.success)return null;let c=b.data.description?.trim();if(!c)return null;let d=Object.fromEntries(Object.entries(b.data.piDesk?.i18n??{}).slice(0,16).flatMap(([a,b])=>b.description?[[a,b.description]]:[]));return Object.keys(d).length?{default:c,translations:d}:c}function k(a){let b=/^npm:((?:@[^/]+\/)?[^@]+)(?:@.+)?$/.exec(a);return b?`npm:${b[1]}`:a.replaceAll("\\","/")}},58801:(a,b,c)=>{c.a(a,async(a,d)=>{try{let n;c.d(b,{G:()=>m,N:()=>k});var e=c(93736),f=c(73024),g=c(76760),h=a([e]);e=(h.then?(await h)():h)[0];let o=(0,g.join)(process.cwd(),"package.json"),{createRequire:p}=process.getBuiltinModule("module"),q=(0,e.createJiti)((0,g.join)(process.env.PI_DESK_PI_PACKAGE_DIR??process.cwd(),"package.json")),r=new Map,s=0;function i(a){let b=r.get(a);return b&&(r.delete(a),r.set(a,b)),b}function j(a,b){let c=r.get(a);if(c&&(r.delete(a),s-=c.bytes),!(b.bytes>0x2000000)){for(;r.size>=512||s+b.bytes>0x2000000;){let a=r.entries().next().value;r.delete(a[0]),s-=a[1].bytes}r.set(a,b),s+=b.bytes}}function k(){r.size>0&&console.info("[Pi Desk][PluginResources] 已清除插件代码缓存",{fileCount:r.size,bytes:s}),r.clear(),s=0}async function l(){let[a,b,c,d,f,h,k,l,m]=await Promise.all([q.import("@earendil-works/pi-coding-agent"),q.import("@earendil-works/pi-agent-core"),q.import("@earendil-works/pi-tui"),q.import("@earendil-works/pi-ai/compat"),q.import("@earendil-works/pi-ai/oauth"),q.import("@earendil-works/pi-ai/providers/all"),q.import("typebox"),q.import("typebox/compile"),q.import("typebox/value")]),n=(0,e.createJiti)(o,{moduleCache:!1,fsCache:!1,tryNative:!1,virtualModules:{"@earendil-works/pi-coding-agent":a,"@earendil-works/pi-agent-core":b,"@earendil-works/pi-tui":c,"@earendil-works/pi-ai/providers/all":h,"@earendil-works/pi-ai/compat":d,"@earendil-works/pi-ai/oauth":f,"@earendil-works/pi-ai":d,"@mariozechner/pi-coding-agent":a,"@mariozechner/pi-agent-core":b,"@mariozechner/pi-tui":c,"@mariozechner/pi-ai/providers/all":h,"@mariozechner/pi-ai/compat":d,"@mariozechner/pi-ai/oauth":f,"@mariozechner/pi-ai":d,typebox:k,"typebox/compile":l,"typebox/value":m,"@sinclair/typebox":k,"@sinclair/typebox/compile":l,"@sinclair/typebox/value":m}}),p=n.options.transform;return n.options.transform=a=>(function(a,b){if(!a.filename)return b(a);let c=(0,g.resolve)(a.filename),d=i(c),e=d?.source===a.source?d:void 0,f=!0===a.async,h=e?.transforms.get(f);if(h)return h;let k=a.source,l=b(a);return l.error||l.code.includes("__JITI_ERROR__")||j(c,{source:k,transforms:new Map(e?.transforms).set(f,l),bytes:(e?.bytes??Buffer.byteLength(k))+Buffer.byteLength(l.code)}),l})(a,p),n}async function m(a,b=(0,g.dirname)(a)){let c=await (n??=l()),d=p(o).cache,e=(0,g.resolve)(b);for(let a of Object.keys(d)){let b=(0,g.relative)(e,a);b.startsWith("..")||(0,g.isAbsolute)(b)||b.split(/[\\/]/).includes("node_modules")||delete d[a]}try{let b,d=(0,g.resolve)(a),e=c.evalModule((b=(0,f.readFileSync)(d,"utf8"),i(d)?.source!==b&&j(d,{source:b,transforms:new Map,bytes:Buffer.byteLength(b)}),b),{filename:d,async:!1});return{default:e?.default??e}}catch(a){if(k(),a instanceof Error&&/await is only valid|top.level await|ERR_REQUIRE_ASYNC_MODULE/i.test(a.message))throw Error("Pi Desk Node Entry 不支持模块顶层 await,请将异步初始化放入 async setup()",{cause:a});throw a}}d()}catch(a){d(a)}})},61035:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{J:()=>l});var e=c(77598),f=c(73024),g=c(76760),h=c(75430),i=c(41904),j=a([h]);function k(){let a=Intl.DateTimeFormat().resolvedOptions();return i.J.parse({region:{locale:a.locale.toLowerCase().startsWith("zh")?"zh-CN":"en",timeZone:a.timeZone||"UTC"}})}h=(j.then?(await j)():j)[0];class m{constructor(a=(0,g.join)((0,h.getAgentDir)(),"pi-desk-settings.json"),b=k){this.path=a,this.defaults=b,this.snapshot=null,this.listeners=new Set,this.tail=Promise.resolve()}getSnapshot(){if(!this.snapshot)if((0,f.existsSync)(this.path))this.snapshot=i.J.parse(JSON.parse((0,f.readFileSync)(this.path,"utf8")));else{let a=i.J.parse(this.defaults());this.save(a),this.snapshot=a}return this.snapshot}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}update(a){let b=this.tail.then(()=>{let b=this.getSnapshot(),c=i.J.parse({region:{...b.region,...a}});if(JSON.stringify(b)!==JSON.stringify(c))for(let a of(this.save(c),this.snapshot=c,console.info("[Pi Desk][Settings] 共享地区设置已保存",c.region),this.listeners))try{a()}catch(a){console.error("[Pi Desk][Settings] 设置订阅回调失败",{message:a instanceof Error?a.message:String(a)})}});return this.tail=b.catch(()=>void 0),b}save(a){(0,f.mkdirSync)((0,g.dirname)(this.path),{recursive:!0});let b=`${this.path}.${process.pid}.${(0,e.randomUUID)()}.tmp`;try{(0,f.writeFileSync)(b,`${JSON.stringify(a,null,2)}
26
+ ${k(a.usage)}`;case"model_change":return`${a.provider}/${c?.getModel(a.provider,a.modelId)?.name||a.modelId}`;case"thinking_level_change":return a.thinkingLevel;case"session_info":return a.name??"";case"label":return a.label??"已清除标签"}}(d,l(a),c);return{entryId:b,kind:m(d),content:e.length<=65536?e:e.slice(0,65536),truncated:e.length>65536}}function p(a,b){let c=a.getEntry(b);if(!c)throw new f(b);if("message"!==c.type||"user"!==c.message.role)throw new g(b);return{selectedEntryId:b,targetLeafEntryId:c.parentId,editorText:h(c.message.content)}}function q(a,b){let c=a.getEntry(b);if(!c)throw new f(b);return a.getLeafId()===b?{selectedEntryId:b,targetLeafEntryId:b,editorText:null,changed:!1}:"message"===c.type&&"user"===c.message.role?{selectedEntryId:b,targetLeafEntryId:c.parentId,editorText:h(c.message.content),changed:a.getLeafId()!==c.parentId}:"custom_message"===c.type?{selectedEntryId:b,targetLeafEntryId:c.parentId,editorText:h(c.content),changed:a.getLeafId()!==c.parentId}:{selectedEntryId:b,targetLeafEntryId:b,editorText:null,changed:!0}}},47351:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{V:()=>g});var e=c(61035),f=a([e]);function g(a){return{...a,async handler(b,c){let[d,f,...g]=b.trim().split(/\s+/);if("logout"!==d||g.length>0)return void await a.handler(b,c);let h="zh-CN"===(0,e.J)().getSnapshot().region.locale,i=f;if(!i){let b=(await a.getArgumentCompletions?.("logout ")??[]).map(a=>a.value.slice(7));if(0===b.length)return void c.ui.notify(h?"当前没有可退出登录的 MCP 服务。":"No MCP server is available to sign out.","info");i=1===b.length?b[0]:await c.ui.select(h?"选择 MCP 服务":"Select MCP server",b)}!i||await c.ui.confirm(h?`退出登录:${i}`:`Sign out: ${i}`,h?"将删除此服务的共享登录凭据,其他会话下次访问也可能需要重新登录。":"This deletes the server’s shared credentials. Other sessions may need to sign in again.")&&(console.info("[Pi Desk][MCP] 用户确认退出登录",{server:i}),await a.handler(`logout ${i}`,c))}}}e=(f.then?(await f)():f)[0],d()}catch(a){d(a)}})},47511:(a,b,c)=>{c.d(b,{Dl:()=>o,Qg:()=>m,RC:()=>q,a4:()=>k,dO:()=>j,j0:()=>n});var d=c(59473);let e=d.Yj().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=d.Yj().trim().min(1).max(256),g=d.Ik({allow:d.YO(f).max(5e3).optional(),deny:d.YO(f).max(5e3).optional()}).strict(),h=d.Ik({value:d.Yj().trim().min(1).max(256),label:d.Yj().trim().min(1).max(120).optional(),description:d.Yj().trim().max(1e3).optional()}).strict(),i=d.Ik({label:d.Yj().trim().min(1).max(120),options:d.YO(h).max(5e3)}).strict(),j=d.g1(e,i),k=d.Yj().min(1).max(64),l=d.Ik({name:d.Yj().trim().min(1).max(64),tools:g.optional(),skills:g.optional(),plugins:d.g1(e,d.g1(e,g)).optional()}).strict(),m=d.g1(k,l).refine(a=>Object.keys(a).length<=100,"最多保存 100 个能力模式").refine(a=>new Set(Object.values(a).map(a=>a.name)).size===Object.keys(a).length,"模式名称不能重复"),n=d.g1(k,l.shape.name),o=d.Ik({tools:d.YO(h),skills:d.YO(h),plugins:d.g1(e,j)}).strict();function p(a,b){let c=0,d=0,e=-1,f=0;for(;d<b.length;)if("*"===a[c])e=c++,f=d;else if(a[c]===b[d])c+=1,d+=1;else{if(!(e>=0))return!1;c=e+1,d=++f}for(;"*"===a[c];)c+=1;return c===a.length}function q(a,b){return(a?.allow===void 0||a.allow.some(a=>p(a,b)))&&!a?.deny?.some(a=>p(a,b))}d.Ik({tools:g,skills:g,capabilities:d.g1(e,g)}).strict()},49080:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{A:()=>l});var e=c(73024),f=c(76760),g=c(75430),h=c(78262),i=c(28802),j=a([g,h,i]);[g,h,i]=j.then?(await j)():j;let m=new Set(["off","minimal","low","medium","high","xhigh","max"]);function k(a,b){return`${a}\u0000${b}`}async function l(a,b=process.cwd()){let c=(0,g.getAgentDir)(),d=a?.modelRuntime??await g.ModelRuntime.create({authPath:(0,f.join)(c,"auth.json"),modelsPath:(0,f.join)(c,"models.json")}),j=a?.settingsManager??g.SettingsManager.create(b,c);await d.refresh({allowNetwork:!1});let n=j.getEnabledModels(),o=n?.length?(await (0,g.resolveModelScopeWithDiagnostics)(n,d)).scopedModels.map(a=>a.model):[...await d.getAvailable()],p=new Map;for(let a of(0,h.oj)(o,d))p.set(k(a.provider,a.id),a);let q=[...p.values()].map(a=>({provider:a.provider,modelId:a.id,name:a.name,input:[...a.input],kind:d.getPhysicalModel(a.provider,a.id)?"physical":"virtual",contextWindow:a.contextWindow>0?a.contextWindow:null,thinkingLevels:[...(0,i.getSupportedThinkingLevels)(a)]})),r=new Map(q.map(a=>[k(a.provider,a.modelId),a])),s=[],t=0;for(let a of function(){let a=(0,f.join)((0,g.getAgentDir)(),"models.json");if(!(0,e.existsSync)(a))return[];try{let b=JSON.parse((0,e.readFileSync)(a,"utf8"));return Array.isArray(b.modelPresets)?b.modelPresets:[]}catch(b){return console.warn("[Pi Desk][PiModelCatalog] models.json 读取失败",{path:a,errorName:b instanceof Error?b.name:"UnknownError"}),[]}}()){if("string"!=typeof a.provider||!a.provider.trim()||"string"!=typeof a.modelId||!a.modelId.trim()||"string"!=typeof a.thinkingLevel||!m.has(a.thinkingLevel)||void 0!==a.color&&null!==a.color&&"string"!=typeof a.color){t+=1;continue}let b=a.thinkingLevel,c=r.get(k(a.provider,a.modelId));if(!c||!c.thinkingLevels.includes(b)){t+=1;continue}s.push({provider:a.provider,modelId:a.modelId,thinkingLevel:b,color:"string"==typeof a.color&&a.color.trim()?a.color:null})}return t>0&&console.warn("[Pi Desk][PiModelCatalog] 已忽略无效或不可用的模型预设",{cwd:a?.sessionManager.getCwd()??b,count:t}),{models:q,presets:s}}d()}catch(a){d(a)}})},54174:(a,b,c)=>{c.d(b,{Z:()=>i,f1:()=>j});let d=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;class e extends Error{constructor(a){super(a),this.name="L4PiImageValidationError"}}function f(a,b){if(!Number.isSafeInteger(a)||a<=0)throw new e(`图片 ${b} 无效`);return a}let g=new Set([192,193,194,195,197,198,199,201,202,203,205,206,207]);function h(a,b){return a[b]|a[b+1]<<8|a[b+2]<<16}function i(a){if(!a||a.startsWith("data:")||!d.test(a))throw new e("图片 Base64 无效");let b=Buffer.from(a,"base64");if(0===b.length)throw new e("图片内容为空");let c=function(a){if(a.length>=8&&137===a[0]&&80===a[1]&&78===a[2]&&71===a[3]&&13===a[4]&&10===a[5]&&26===a[6]&&10===a[7])return"image/png";if(a.length>=3&&255===a[0]&&216===a[1]&&255===a[2])return"image/jpeg";if(a.length>=10&&["GIF87a","GIF89a"].includes(a.toString("ascii",0,6)))return"image/gif";if(a.length>=16&&"RIFF"===a.toString("ascii",0,4)&&"WEBP"===a.toString("ascii",8,12))return"image/webp";throw new e("图片格式不受支持")}(b);return{bytes:b,metadata:{mimeType:c,...function(a,b){switch(b){case"image/png":if(a.length<24||"IHDR"!==a.toString("ascii",12,16))throw new e("PNG 图片头无效");return{width:f(a.readUInt32BE(16),"宽度"),height:f(a.readUInt32BE(20),"高度")};case"image/jpeg":let c=2;for(;c+3<a.length;){for(;c<a.length&&255!==a[c];)c+=1;for(;c<a.length&&255===a[c];)c+=1;if(c>=a.length)break;let b=a[c];if(c+=1,216===b||1===b||b>=208&&b<=215)continue;if(217===b||218===b||c+1>=a.length)break;let d=a.readUInt16BE(c);if(d<2||c+d>a.length)break;if(g.has(b)){if(d<7)break;return{width:f(a.readUInt16BE(c+5),"宽度"),height:f(a.readUInt16BE(c+3),"高度")}}c+=d}throw new e("JPEG 图片尺寸无效");case"image/gif":if(a.length<10)throw new e("GIF 图片头无效");return{width:f(a.readUInt16LE(6),"宽度"),height:f(a.readUInt16LE(8),"高度")};case"image/webp":return function(a){let b=a.toString("ascii",12,16);if("VP8X"===b){if(a.length<30)throw new e("WebP VP8X 图片头无效");return{width:f(h(a,24)+1,"宽度"),height:f(h(a,27)+1,"高度")}}if("VP8L"===b){if(a.length<25||47!==a[20])throw new e("WebP VP8L 图片头无效");let b=a[21],c=a[22],d=a[23],g=a[24];return{width:f(1+((63&c)<<8|b),"宽度"),height:f(1+((15&g)<<10|d<<2|(192&c)>>6),"高度")}}if("VP8 "===b){if(a.length<30||157!==a[23]||1!==a[24]||42!==a[25])throw new e("WebP VP8 图片头无效");return{width:f(16383&a.readUInt16LE(26),"宽度"),height:f(16383&a.readUInt16LE(28),"高度")}}throw new e("WebP 图片编码无效")}(a)}}(b,c)}}}function j(a){let b=i(a.data);if(b.metadata.mimeType!==a.mimeType)throw new e("图片 MIME 与实际内容不一致");if(b.metadata.width!==a.width||b.metadata.height!==a.height)throw new e("图片尺寸与实际内容不一致");return b}},56752:(a,b,c)=>{c.d(b,{C:()=>f,b:()=>e});var d=c(76760);function e(a){return"win32"===process.platform?a.toLocaleLowerCase():a}function f(a,b){let c=(0,d.relative)(a,b);return""===c||!c.startsWith(`..${d.sep}`)&&".."!==c&&!(0,d.isAbsolute)(c)}},56971:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{o:()=>o});var e=c(51455),f=c(48161),g=c(76760),h=c(58417),i=c(73589),j=a([i]);function k(a,b){let c=(0,g.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,g.isAbsolute)(c)}async function l(a){try{return await (0,e.realpath)(a)}catch{return(0,g.resolve)(a)}}function m(a){return"win32"===process.platform?a.toLowerCase():a}async function n(a){try{if((await (0,e.stat)(a)).isFile())return{version:null,description:null,hasNodeEntry:!1,error:null};let b=JSON.parse(await (0,e.readFile)((0,g.join)(a,"package.json"),"utf8"));if(!b||"object"!=typeof b||Array.isArray(b))throw Error("package.json 必须是对象");return{version:"string"==typeof b.version?b.version:null,description:(0,h._C)(b),hasNodeEntry:b.piDesk?.entry!==void 0||b.piDesk?.global!==void 0,hasNativeEntries:Array.isArray(b.pi?.extensions)&&b.pi.extensions.length>0,error:null}}catch(a){if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return{version:null,description:null,hasNodeEntry:!1,error:null};return{version:null,description:null,hasNodeEntry:!1,error:a instanceof Error?a.message:String(a)}}}async function o(a,b,c){let d=c.SettingsManager.create(a,b,{projectTrusted:!1}),h=new c.DefaultPackageManager({cwd:a,agentDir:b,settingsManager:d}),j=d.drainErrors().map(({error:a})=>a.message),o=new Map,p=new Map;for(let a of h.listConfiguredPackages()){if("user"!==a.scope)continue;let b=a.installedPath?await l(a.installedPath):null,c=b?await n(b):null,d=b?p.get(m(b)):void 0;b&&!d&&p.set(m(b),a.source),o.set(a.source,{source:a.source,kind:"package",path:b,nativePaths:[],hasPiResources:!0,piDeskRoot:b&&c?.hasNodeEntry&&!d?b:null,version:c?.version??null,description:c?.description??null,enabled:!0,error:d?`此目录已由 ${d} 声明,不能重复加载`:b?c?.error??null:"插件包未安装或安装目录不存在"})}let q=(0,g.join)(b,"extensions"),r=new Set;try{for(let a of(await (0,e.readdir)(q,{withFileTypes:!0})))if(!a.name.startsWith(".")&&"node_modules"!==a.name&&(a.isDirectory()||a.isSymbolicLink()))try{let b=await l((0,g.join)(q,a.name));(await (0,e.stat)(b)).isDirectory()&&r.add(b)}catch(b){j.push(`${a.name}: ${b instanceof Error?b.message:String(b)}`)}}catch(a){a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code||j.push(a instanceof Error?a.message:String(a))}for(let a of d.getGlobalSettings().extensions??[]){if(/^[!+-]|[?*{}]/.test(a))continue;let c=await l(a.startsWith("~/")?(0,g.join)((0,f.homedir)(),a.slice(2)):(0,g.resolve)(b,a));try{(await (0,e.stat)(c)).isDirectory()&&r.add(c)}catch{}}let s=[...r].sort((a,b)=>b.length-a.length);try{let a=await h.resolve(async a=>{let b=o.get(a);return b&&(b.error??="插件包未安装或版本不匹配"),"skip"});for(let a of o.values())a.hasPiResources=!1;for(let b of[...a.extensions,...a.skills,...a.prompts,...a.themes])if(b.enabled&&"user"===b.metadata.scope&&"package"===b.metadata.origin){let a=o.get(b.metadata.source);a&&(a.hasPiResources=!0)}for(let b of a.extensions){if("user"!==b.metadata.scope)continue;let a=await l(b.path);if("package"===b.metadata.origin){let c=o.get(b.metadata.source);c&&b.enabled&&!c.nativePaths.includes(a)&&c.nativePaths.push(a);continue}let c=s.find(b=>k(b,a))??a,d=[...p].find(([b])=>k(b,m(a)));if(d){let c=o.get(d[1]);b.enabled&&c&&!c.nativePaths.includes(a)&&c.nativePaths.push(a),j.push(`扩展入口 ${a} 与已配置包 ${d[1]} 重复,保留包来源`);continue}let e=o.get(c);e||(e={source:c,kind:"extension",path:c,nativePaths:[],piDeskRoot:null,version:null,description:null,enabled:!1,error:null},o.set(c,e)),b.enabled&&(e.enabled=!0,e.nativePaths.includes(a)||e.nativePaths.push(a))}}catch(a){j.push(a instanceof Error?a.message:String(a))}for(let a of s){if([...p.keys()].some(b=>k(b,m(a))))continue;let b=await n(a),c=o.get(a);if(!c&&!b.hasNodeEntry&&!b.error)continue;let d=(await Promise.all(["index.ts","index.js"].map(b=>(0,e.stat)((0,g.join)(a,b)).then(a=>a.isFile(),()=>!1)))).some(Boolean),f=c??{source:a,kind:"extension",path:a,nativePaths:[],piDeskRoot:null,version:null,description:null,enabled:!b.hasNativeEntries&&!d,error:null};f.version=b.version,f.description=b.description,f.error=b.error,b.hasNodeEntry&&f.enabled&&(f.piDeskRoot=a),o.set(a,f)}let t=await (0,i.n)(b,h,d);for(let a of o.values())await t(a.source,a.path,"package"===a.kind)&&(a.enabled=!1);return{sources:[...o.values()].sort((a,b)=>a.source.localeCompare(b.source)),errors:j}}i=(j.then?(await j)():j)[0],d()}catch(a){d(a)}})},58417:(a,b,c)=>{c.d(b,{LD:()=>k,SZ:()=>f,_C:()=>j,mR:()=>e,w3:()=>g});var d=c(59473);let e=d.Yj().trim().min(1).max(128).regex(/^[a-zA-Z][a-zA-Z0-9._-]*$/),f=d.Yj().trim().url().max(2048).refine(a=>{let b=new URL(a);return["https:","http:"].includes(b.protocol)&&!b.username&&!b.password&&!b.search&&!b.hash},"插件源必须是 HTTP 或 HTTPS 仓库地址"),g=d.gM("mode",[d.Ik({mode:d.eu("auto")}).strict(),d.Ik({mode:d.eu("local")}).strict(),d.Ik({mode:d.eu("official")}).strict(),d.Ik({mode:d.eu("domestic")}).strict(),d.Ik({mode:d.eu("custom"),registry:f}).strict()]),h=d.Ik({description:d.Yj().trim().min(1).max(4e3).optional(),readme:d.Yj().trim().min(1).max(1024).optional()}),i=d.Ik({description:d.Yj().optional(),piDesk:d.Ik({i18n:d.g1(d.Yj().min(1).max(35),h).optional()}).passthrough().optional()}).passthrough();function j(a){let b=i.safeParse(a);if(!b.success)return null;let c=b.data.description?.trim();if(!c)return null;let d=Object.fromEntries(Object.entries(b.data.piDesk?.i18n??{}).slice(0,16).flatMap(([a,b])=>b.description?[[a,b.description]]:[]));return Object.keys(d).length?{default:c,translations:d}:c}function k(a){let b=/^npm:((?:@[^/]+\/)?[^@]+)(?:@.+)?$/.exec(a);return b?`npm:${b[1]}`:a.replaceAll("\\","/")}},58801:(a,b,c)=>{c.a(a,async(a,d)=>{try{let n;c.d(b,{G:()=>m,N:()=>k});var e=c(93736),f=c(73024),g=c(76760),h=a([e]);e=(h.then?(await h)():h)[0];let o=(0,g.join)(process.cwd(),"package.json"),{createRequire:p}=process.getBuiltinModule("module"),q=(0,e.createJiti)((0,g.join)(process.env.PI_DESK_PI_PACKAGE_DIR??process.cwd(),"package.json")),r=new Map,s=0;function i(a){let b=r.get(a);return b&&(r.delete(a),r.set(a,b)),b}function j(a,b){let c=r.get(a);if(c&&(r.delete(a),s-=c.bytes),!(b.bytes>0x2000000)){for(;r.size>=512||s+b.bytes>0x2000000;){let a=r.entries().next().value;r.delete(a[0]),s-=a[1].bytes}r.set(a,b),s+=b.bytes}}function k(){r.size>0&&console.info("[Pi Desk][PluginResources] 已清除插件代码缓存",{fileCount:r.size,bytes:s}),r.clear(),s=0}async function l(){let[a,b,c,d,f,h,k,l,m]=await Promise.all([q.import("@earendil-works/pi-coding-agent"),q.import("@earendil-works/pi-agent-core"),q.import("@earendil-works/pi-tui"),q.import("@earendil-works/pi-ai/compat"),q.import("@earendil-works/pi-ai/oauth"),q.import("@earendil-works/pi-ai/providers/all"),q.import("typebox"),q.import("typebox/compile"),q.import("typebox/value")]),n=(0,e.createJiti)(o,{moduleCache:!1,fsCache:!1,tryNative:!1,virtualModules:{"@earendil-works/pi-coding-agent":a,"@earendil-works/pi-agent-core":b,"@earendil-works/pi-tui":c,"@earendil-works/pi-ai/providers/all":h,"@earendil-works/pi-ai/compat":d,"@earendil-works/pi-ai/oauth":f,"@earendil-works/pi-ai":d,"@mariozechner/pi-coding-agent":a,"@mariozechner/pi-agent-core":b,"@mariozechner/pi-tui":c,"@mariozechner/pi-ai/providers/all":h,"@mariozechner/pi-ai/compat":d,"@mariozechner/pi-ai/oauth":f,"@mariozechner/pi-ai":d,typebox:k,"typebox/compile":l,"typebox/value":m,"@sinclair/typebox":k,"@sinclair/typebox/compile":l,"@sinclair/typebox/value":m}}),p=n.options.transform;return n.options.transform=a=>(function(a,b){if(!a.filename)return b(a);let c=(0,g.resolve)(a.filename),d=i(c),e=d?.source===a.source?d:void 0,f=!0===a.async,h=e?.transforms.get(f);if(h)return h;let k=a.source,l=b(a);return l.error||l.code.includes("__JITI_ERROR__")||j(c,{source:k,transforms:new Map(e?.transforms).set(f,l),bytes:(e?.bytes??Buffer.byteLength(k))+Buffer.byteLength(l.code)}),l})(a,p),n}async function m(a,b=(0,g.dirname)(a)){let c=await (n??=l()),d=p(o).cache,e=(0,g.resolve)(b);for(let a of Object.keys(d)){let b=(0,g.relative)(e,a);b.startsWith("..")||(0,g.isAbsolute)(b)||b.split(/[\\/]/).includes("node_modules")||delete d[a]}try{let b,d=(0,g.resolve)(a),e=c.evalModule((b=(0,f.readFileSync)(d,"utf8"),i(d)?.source!==b&&j(d,{source:b,transforms:new Map,bytes:Buffer.byteLength(b)}),b),{filename:d,async:!1});return{default:e?.default??e}}catch(a){if(k(),a instanceof Error&&/await is only valid|top.level await|ERR_REQUIRE_ASYNC_MODULE/i.test(a.message))throw Error("Pi Desk Node Entry 不支持模块顶层 await,请将异步初始化放入 async setup()",{cause:a});throw a}}d()}catch(a){d(a)}})},61035:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{J:()=>l});var e=c(77598),f=c(73024),g=c(76760),h=c(75430),i=c(41904),j=a([h]);function k(){let a=Intl.DateTimeFormat().resolvedOptions();return i.J.parse({region:{locale:a.locale.toLowerCase().startsWith("zh")?"zh-CN":"en",timeZone:a.timeZone||"UTC"}})}h=(j.then?(await j)():j)[0];class m{constructor(a=(0,g.join)((0,h.getAgentDir)(),"pi-desk-settings.json"),b=k){this.path=a,this.defaults=b,this.snapshot=null,this.listeners=new Set,this.tail=Promise.resolve()}getSnapshot(){if(!this.snapshot)if((0,f.existsSync)(this.path))this.snapshot=i.J.parse(JSON.parse((0,f.readFileSync)(this.path,"utf8")));else{let a=i.J.parse(this.defaults());this.save(a),this.snapshot=a}return this.snapshot}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}update(a){let b=this.tail.then(()=>{let b=this.getSnapshot(),c=i.J.parse({region:{...b.region,...a}});if(JSON.stringify(b)!==JSON.stringify(c))for(let a of(this.save(c),this.snapshot=c,console.info("[Pi Desk][Settings] 共享地区设置已保存",c.region),this.listeners))try{a()}catch(a){console.error("[Pi Desk][Settings] 设置订阅回调失败",{message:a instanceof Error?a.message:String(a)})}});return this.tail=b.catch(()=>void 0),b}save(a){(0,f.mkdirSync)((0,g.dirname)(this.path),{recursive:!0});let b=`${this.path}.${process.pid}.${(0,e.randomUUID)()}.tmp`;try{(0,f.writeFileSync)(b,`${JSON.stringify(a,null,2)}
27
27
  `,"utf8"),(0,f.renameSync)(b,this.path)}finally{(0,f.existsSync)(b)&&(0,f.unlinkSync)(b)}}}function l(){return globalThis.__piDeskHostSettingsStore??=new m}d()}catch(a){d(a)}})},61518:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{O:()=>k});var e=c(77598),f=c(73024),g=c(76760),h=c(75430),i=c(47511),j=a([h]);h=(j.then?(await j)():j)[0];class l{constructor(a=function(){let a=(0,h.getAgentDir)(),b=(0,g.join)(a,"pi-desk-capability-modes.json"),c=(0,g.join)(a,"pi-super-capability-modes.json");return!(0,f.existsSync)(b)&&(0,f.existsSync)(c)&&(0,f.copyFileSync)(c,b),b}()){this.path=a,this.modes=null,this.listeners=new Set,this.tail=Promise.resolve()}read(){if(null===this.modes){let a=(0,f.existsSync)(this.path)?JSON.parse((0,f.readFileSync)(this.path,"utf8")):{modes:{}};if(!a||"object"!=typeof a||!("modes"in a))throw Error("能力模式配置缺少 modes");this.modes=i.Qg.parse(a.modes)}return structuredClone(this.modes)}subscribe(a){return this.listeners.add(a),()=>{this.listeners.delete(a)}}replace(a){let b=i.Qg.parse(a),c=this.tail.then(()=>{(0,f.mkdirSync)((0,g.dirname)(this.path),{recursive:!0});let a=`${this.path}.${process.pid}.${(0,e.randomUUID)()}.tmp`;try{(0,f.writeFileSync)(a,`${JSON.stringify({modes:b},null,2)}
28
28
  `,"utf8"),(0,f.renameSync)(a,this.path)}finally{(0,f.existsSync)(a)&&(0,f.unlinkSync)(a)}for(let a of(this.modes=structuredClone(b),this.listeners))try{a()}catch(a){console.error("[Pi Desk][Capabilities] 模式配置监听器失败",{message:a instanceof Error?a.message:String(a)})}});return this.tail=c.catch(()=>void 0),c}}function k(){return globalThis.__piDeskCapabilityModesStore??=new l}d()}catch(a){d(a)}})},63719:(a,b,c)=>{c.d(b,{CT:()=>r,Db:()=>k,JH:()=>t,NL:()=>j,Nu:()=>u,O_:()=>l,Ys:()=>h,_g:()=>o,eC:()=>p,ih:()=>z,jI:()=>y,lt:()=>g,p$:()=>q,rh:()=>n,uV:()=>e,w9:()=>i,xm:()=>f});var d=c(59473);let e=4096,f=5e3,g=100,h=200,i=1e3,j=5242880,k=0xa00000,l=5e7;function m(a,b){return""===a?b:!(a.length>e||a.startsWith("/")||a.includes("\\")||a.includes("\0")||/^[a-zA-Z]:/.test(a))&&a.split("/").every(a=>a.length>0&&"."!==a&&".."!==a)}let n=d.Yj().max(e).refine(a=>m(a,!0),"目录路径必须是规范相对路径"),o=d.Yj().min(1).max(e).refine(a=>m(a,!1),"文件路径必须是规范相对路径"),p=d.Yj().min(1).max(e).refine(a=>m(a,!1)||a.length>0&&a.length<=e&&!a.includes("\0")&&(a.startsWith("/")||a.startsWith("\\\\")||/^[a-zA-Z]:[\\/]/.test(a)),"预览路径必须是规范相对路径或绝对路径"),q=d.k5(["compressed","original"]),r=d.k5(["image/jpeg","image/png","image/webp","image/gif"]),s=d.Ik({name:d.Yj().min(1),type:d.k5(["directory","file"])}).strict(),t=d.Ik({entries:d.YO(s).max(f),truncated:d.zM()}).strict(),u=d.Ik({query:d.Yj().min(1).max(200).refine(a=>a.trim().length>0&&!/[\0\r\n]/.test(a),"搜索词必须是非空单行文本"),scope:d.k5(["all","files","content"]).default("all"),caseSensitive:d.zM().default(!1),wholeWord:d.zM().default(!1),regex:d.zM().default(!1)}).strict(),v=d.Ik({start:d.ai().int().nonnegative(),end:d.ai().int().nonnegative()}).strict().refine(a=>a.start<=a.end,"搜索命中区间无效"),w=d.Ik({path:o,ranges:d.YO(v)}).strict().refine(a=>a.ranges.every(b=>b.end<=a.path.length),"文件名命中区间越界"),x=d.Ik({path:o,line:d.ai().int().positive(),text:d.Yj().max(i),ranges:d.YO(v)}).strict().refine(a=>a.ranges.every(b=>b.end<=a.text.length),"正文命中区间越界"),y=d.Ik({fileMatches:d.YO(w).max(g),contentMatches:d.YO(x).max(h),truncated:d.zM()}).strict(),z=d.gM("kind",[d.Ik({kind:d.eu("text"),content:d.Yj(),size:d.ai().int().nonnegative().max(j)}).strict(),d.Ik({kind:d.eu("image"),mimeType:r,data:d.Yj().min(1),size:d.ai().int().positive().max(k)}).strict()])},67062:(a,b,c)=>{c.d(b,{P:()=>h,WR:()=>g,YB:()=>i,Z$:()=>j,l3:()=>k});var d=c(59473);let e=d.Yj().max(65536),f=d.Ik({id:d.Yj().uuid(),title:e,expiresAt:d.ai().int().nonnegative().nullable()}),g=d.gM("method",[f.extend({method:d.eu("confirm"),message:e}).strict(),f.extend({method:d.eu("select"),options:d.YO(e).max(200)}).strict(),f.extend({method:d.eu("input"),placeholder:e}).strict(),f.extend({method:d.eu("editor"),prefill:e}).strict()]),h=d.Ik({requests:d.YO(g).max(32),statuses:d.g1(d.Yj().max(128),e),widgets:d.g1(d.Yj().max(128),d.Ik({lines:d.YO(e).max(200),placement:d.k5(["aboveEditor","belowEditor"])}).strict())}).strict(),i=d.Ik({id:d.Yj().uuid(),value:d.KC([d.zM(),e,d.ch()])}).strict(),j=d.gM("type",[d.Ik({type:d.eu("snapshot"),snapshot:h}).strict(),d.Ik({type:d.eu("notify"),message:e,level:d.k5(["info","warning","error"])}).strict(),d.Ik({type:d.eu("editor_text"),text:e,mode:d.k5(["replace","paste"])}).strict()]);function k(){return{requests:[],statuses:{},widgets:{}}}},69503:(a,b,c)=>{c.d(b,{D:()=>h,Yj:()=>i,s6:()=>e,xI:()=>f});var d=c(59473);let e="project-preview",f=32,g=d.Ik({directories:d.YO(d.Yj().min(1).max(4096)).max(f),defaultDirectory:d.Yj().min(1).max(4096).nullable()}).strict();function h(a){let b=g.safeParse(a);return b.success?b.data:{directories:[],defaultDirectory:null}}function i(a){let b=a.replaceAll("\\","/").replace(/\/+$/,"")||"/";return/^[a-z]:/i.test(b)||b.startsWith("//")?b.toLowerCase():b}},69765:(a,b,c)=>{c.d(b,{U:()=>d});class d{constructor(a=()=>void 0){this.onDispatchError=a,this.deferred=[],this.restoreExtensionRuntime=null,this.draining=null,this.paused=!1,this.disposed=!1}get isBlocking(){return this.paused||null!==this.draining||this.deferred.length>0}pause(){this.disposed||(this.paused=!0)}defer(a,b){return!!this.isBlocking&&!this.disposed&&(this.deferred.push({source:a,dispatch:b}),!0)}resume(){if(this.disposed)return Promise.resolve();if(this.paused=!1,this.draining)return this.draining;let a=this.drain().finally(()=>{this.draining===a&&(this.draining=null),!this.paused&&this.deferred.length>0&&this.resume()});return this.draining=a,a}installExtensionRuntime(a){if(this.disposed)return;this.restoreExtensionRuntime?.();let b=a.sendMessage,c=a.sendUserMessage,d=(a,c)=>{this.defer("extension-message",()=>b(a,c))||b(a,c)},e=(a,b)=>{this.defer("extension-user-message",()=>c(a,b))||c(a,b)};a.sendMessage=d,a.sendUserMessage=e,this.restoreExtensionRuntime=()=>{a.sendMessage===d&&(a.sendMessage=b),a.sendUserMessage===e&&(a.sendUserMessage=c)}}discardPending(){this.deferred.length=0}dispose(){this.disposed||(this.disposed=!0,this.paused=!0,this.deferred.length=0,this.restoreExtensionRuntime?.(),this.restoreExtensionRuntime=null)}async drain(){for(;!this.paused&&!this.disposed;){let a=this.deferred.shift();if(!a)return;try{await a.dispatch()}catch(b){this.onDispatchError(a.source,b)}}}}},72498:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{M2:()=>y,Wo:()=>x,Zd:()=>u,er:()=>z,gb:()=>v,ls:()=>t,vC:()=>A,wz:()=>w});var e=c(73024),f=c(76760),g=c(75430),h=c(14616),i=c(61518),j=c(32980),k=c(54174),l=c(87468),m=c(12727),n=c(65209),o=c(5782),p=c(46524),q=c(26143),r=a([g,i,j,n,q]);[g,i,j,n,q]=r.then?(await r)():r;class x extends Error{constructor(a){super(a),this.name="L4PiSessionBranchBlockedError"}}class y extends Error{constructor(a){super(`Pi session resend target is not a user message: ${a}`),this.name="L4PiSessionResendTargetError"}}class z extends Error{constructor(){super("Pi session has no durable entry to clone"),this.name="L4PiSessionCloneEmptyError"}}function s(){return globalThis.__piDeskPiWorkSessionRuntimes||(globalThis.__piDeskPiWorkSessionRuntimes=new Map),globalThis.__piDeskPiWorkSessionRuntimes}class A{constructor(a,b){this.sessionManager=a,this.branchIndex=b,this.resources=new q.h,this.pendingBranchAppend=null,this.capabilityModeValue=null,this.capabilityTail=Promise.resolve(),this.disposed=!1,this.closePromise=null,this.indexedEntryCount=a.getEntries().length,this.branchIdValue=b.branchIdForHead(a.getLeafId()),this.chatWorker=this.createChatWorker(),this.unsubscribeCapabilities=(0,i.O)().subscribe(()=>{if(null===this.capabilityModeValue||this.disposed)return;let a=(0,i.O)().read(),b=Object.hasOwn(a,this.capabilityModeValue)?this.capabilityModeValue:null;this.setCapabilityMode(b).catch(a=>{console.error("[Pi Desk][Capabilities] 会话同步模式配置失败",{sessionId:this.sessionId,message:a instanceof Error?a.message:String(a)})})})}static create(a){let b=g.SessionManager.create(a),c=(0,o.l)(b);return(0,n.Ko)(a),A.fromManager(g.SessionManager.open(c,b.getSessionDir()))}static async open(a,b){let c=s().get(b);if(c){if(c.assertActive(),(0,f.resolve)(c.cwd)!==(0,f.resolve)(a))throw Error(`Pi session ${b} cwd does not match requested cwd`);return c}let d=await (0,n.vg)(a,b);if(!d)throw Error(`Pi session ${b} was not found in ${a}`);let e=A.fromManager(g.SessionManager.open(d));if((0,f.resolve)(e.cwd)!==(0,f.resolve)(a))throw Error(`Pi session ${b} cwd does not match persisted cwd`);return e}get cwd(){return this.sessionManager.getCwd()}get sessionId(){return this.sessionManager.getSessionId()}get branchId(){return this.branchIdValue}get isWorkerInitialized(){return this.assertActive(),this.chatWorker.isInitialized}readChatBackgroundTaskIds(){return this.assertActive(),this.chatWorker.getBackgroundTaskIds()}readPluginReloadBlockReason(){return this.assertActive(),this.chatWorker.readPluginReloadBlockReason()}readChatSnapshot(){return this.assertActive(),(0,m.xf)(this.sessionManager)}search(a){return this.assertActive(),(0,h.we)(this.sessionManager,a)}async readSessionTree(){this.assertActive();let a=this.sessionManager.getEntries().some(a=>"model_change"===a.type)?await g.ModelRuntime.create():void 0;return(0,p.cg)(this.sessionManager,a)}async readSessionTreeEntryDetail(a){this.assertActive();let b=this.sessionManager.getEntry(a)?.type==="model_change"?await g.ModelRuntime.create():void 0;return(0,p.j0)(this.sessionManager,a,b)}readChatImage(a,b){if(this.assertActive(),!Number.isSafeInteger(b)||b<0)throw Error("图片位置无效");if(!this.sessionManager.getBranch().some(b=>b.id===a))throw Error(`Pi session entry is not on the current branch: ${a}`);let c=this.sessionManager.getEntry(a);if(c?.type!=="message"||"user"!==c.message.role&&"toolResult"!==c.message.role)throw Error(`Pi session entry has no message images: ${a}`);let d=(0,m.Wl)(c.message.content,b);if(!d)throw Error(`Pi message image was not found: ${a}/${b}`);return d}subscribeChat(a){return this.assertActive(),this.chatWorker.subscribe(a)}get nativeUi(){return this.assertActive(),this.chatWorker.nativeUi}async readChatRuntime(){return this.assertActive(),this.chatWorker.getRuntime(!1)}async readModelContext(){return this.assertActive(),this.chatWorker.readModelContext()}watchTaskDetail(a,b){return this.assertActive(),this.chatWorker.watchTaskDetail(a,b)}readTaskMessage(a,b){return this.assertActive(),this.chatWorker.readTaskMessage(a,b)}readTaskImage(a,b,c){return this.assertActive(),this.chatWorker.readTaskImage(a,b,c)}async interruptTask(a){this.assertActive(),await this.chatWorker.interruptTask(a)}async invokePluginMethod(a,b,c,d){if(this.assertActive(),a.sessionId!==this.sessionId||a.branchId!==this.branchId)throw Error("Pi session plugin source does not match the current runtime");return this.chatWorker.invokePluginMethod(b,c,d,a)}async listModels(){return this.assertActive(),this.chatWorker.listModels()}async listNativeCommands(){return this.assertActive(),this.chatWorker.listNativeCommands()}async executeNativeCommand(a,b){this.assertActive(),await this.chatWorker.executeNativeCommand(a,b)}async listNativeTools(a=!1){return a&&this.disposed?[]:(this.assertActive(),this.chatWorker.listNativeTools(a))}async executeDirectBash(a){return this.assertActive(),this.chatWorker.executeDirectBash(a)}async abortDirectBash(){this.assertActive(),await this.chatWorker.abortDirectBash()}async send(a){if(this.assertActive(),"resend"!==a.mode)return this.chatWorker.send(a);let b=this.sessionManager.getEntry(a.entryId);if(!b)throw new p.Ns(a.entryId);if("message"!==b.type||"user"!==b.message.role)throw new y(a.entryId);let c=b.message.content,d="string"==typeof c?c:c.flatMap(a=>"text"===a.type?[a.text]:[]).join(""),e="string"==typeof c?[]:c.flatMap(a=>"image"===a.type?[{...(0,k.Z)(a.data).metadata,data:a.data}]:[]),f=this.chatWorker.readPluginReloadBlockReason();if(f)throw new x(f);if(!(await this.navigateBranch(a.entryId,!0,a.onBranchChanged)).changed)throw new x("分支切换已取消,未重发消息");return this.chatWorker.send({mode:"auto",text:d,images:e})}async interrupt(){this.assertActive(),await this.chatWorker.interrupt()}async compact(){this.assertActive(),await this.chatWorker.compact()}async reload(a){this.assertActive(),await this.chatWorker.reload(a)}async restoreQueuedMessages(){return this.assertActive(),this.chatWorker.restoreQueuedMessages()}async setTitle(a){this.assertActive(),await this.chatWorker.setTitle(a)}async setModel(a){this.assertActive(),await this.chatWorker.setModel(a)}setCapabilityMode(a){let b=this.capabilityTail.then(async()=>{if(this.assertActive(),null!==a&&!Object.hasOwn((0,i.O)().read(),a))throw Error("能力模式已不存在,请重新选择");this.capabilityModeValue=a,await this.chatWorker.applyCapabilityMode()});return this.capabilityTail=b.catch(()=>void 0),b}async dispose(){this.closePromise||(this.disposed=!0,this.unsubscribeCapabilities(),this.closePromise=this.chatWorker.dispose().finally(()=>this.resources.reset()),this.closePromise.then(()=>{s().get(this.sessionId)===this&&s().delete(this.sessionId)},a=>{console.warn("[Pi Desk][WorkSessionRuntime] 会话关闭未确认,保留实例占用直到重启",{sessionId:this.sessionId,message:a instanceof Error?a.message:String(a)})})),await this.waitForWorkerClose(this.closePromise,1500).catch(()=>void 0)}async waitForWorkerClose(a,b){let c;try{await Promise.race([a.then(()=>!0),new Promise(a=>{c=setTimeout(()=>a(!1),b)})])}finally{c&&clearTimeout(c)}}async branch(a){return this.navigateBranch(a)}async navigateBranch(a,b=!1,c){this.assertActive(),this.assertBranchable(),this.syncBranchIndex();let d=b?{...(0,p.u3)(this.sessionManager,a),changed:!0}:(0,p.eD)(this.sessionManager,a);if(!d.changed)return d;let e=this.sessionManager.getLeafId(),f=this.pendingBranchAppend;this.pendingBranchAppend=null;let g=!1;try{return(g=await this.chatWorker.navigateTree(d.selectedEntryId,b))?d:{...d,changed:!1,targetLeafEntryId:this.sessionManager.getLeafId(),editorText:null}}finally{this.syncBranchIndex();let a=this.sessionManager.getLeafId();g||a!==e?(this.pendingBranchAppend=this.branchIndex.predictAppend(a),this.branchIdValue=this.pendingBranchAppend.branchId,await c?.()):this.pendingBranchAppend=f}}createBranchedSession(a){let b,c,d,f,h;this.assertActive(),"at"===a.position&&this.assertBranchable(),this.syncBranchIndex();let i=this.sessionManager.getSessionFile();if(!i||!(0,e.existsSync)(i))throw Error(`Pi session ${this.sessionId} has no authoritative JSONL file`);if("before"===a.position){if(!a.entryId)throw new p.Ns("");let e=(0,p.u3)(this.sessionManager,a.entryId);b=e.selectedEntryId,c=e.targetLeafEntryId,d=e.editorText}else{if(!(b=a.entryId??this.sessionManager.getLeafId()??""))throw new z;if(!this.sessionManager.getEntry(b))throw new p.Ns(b);c=b,d=null}if(!(h=null===c?(f=g.SessionManager.create(this.cwd,this.sessionManager.getSessionDir())).newSession({parentSession:i}):(f=g.SessionManager.open(i,this.sessionManager.getSessionDir())).createBranchedSession(c)))throw Error(`Failed to create Pi session from entry: ${b}`);(0,o.l)(f),(0,n.Ko)(this.cwd);let j=A.fromManager(g.SessionManager.open(h,this.sessionManager.getSessionDir()));return console.info("[Pi Desk][PiWorkSessionRuntime] 已创建路径分支 Pi 会话",{sourceSessionId:this.sessionId,sourceBranchId:this.branchIndex.branchIdForEntry(b),selectedEntryId:b,targetLeafEntryId:c,position:a.position,sessionId:j.sessionId,branchId:j.branchId}),{runtime:j,editorText:d}}assertBranchable(){try{this.chatWorker.assertIdle()}catch(a){throw new x(a instanceof Error?a.message:"当前 Pi 会话不能切换分支")}}createChatWorker(){return new j.EG(this.cwd,this.sessionManager,a=>this.confirmAppendedEntry(a),{mode:()=>this.capabilityModeValue,rules:()=>null===this.capabilityModeValue?void 0:(0,i.O)().read()[this.capabilityModeValue]},this.resources)}confirmAppendedEntry(a){try{this.syncBranchIndex(),this.branchIndex.branchIdForEntry(a.id)}catch(b){throw console.error("[Pi Desk][PiWorkSessionRuntime] 增量同步 Pi 分支索引失败",{sessionId:this.sessionId,entryId:a.id,parentId:a.parentId,errorName:b instanceof Error?b.name:"UnknownError",errorMessage:b instanceof Error?b.message:String(b)}),b}}syncBranchIndex(){let a=this.sessionManager.getEntries();for(;this.indexedEntryCount<a.length;){let b,c=a[this.indexedEntryCount];this.pendingBranchAppend?(b=this.branchIndex.confirmAppend(this.pendingBranchAppend,c),this.pendingBranchAppend=null):b=this.branchIndex.appendEntry(c).branchId,this.indexedEntryCount+=1,this.sessionManager.getLeafId()===c.id&&(this.branchIdValue=b)}}static fromManager(a){let b=s().get(a.getSessionId());if(b)return b.assertActive(),b;let c=new A(a,new l.u(a.getEntries()));return s().set(c.sessionId,c),c}assertActive(){if(this.disposed)throw Error(`Pi session runtime has been disposed: ${this.sessionId}`)}}function t(a){let b=s().get(a);if(!b)throw Error(`Pi session runtime is not initialized: ${a}`);return b}async function u(){let a=await Promise.all([...s().values()].map(a=>a.listNativeTools(!0)));return[...new Map(a.flat().map(a=>[a.name,a])).values()]}async function v(a){await s().get(a)?.dispose()}async function w(){await Promise.all([...s().values()].map(a=>a.dispose()))}d()}catch(a){d(a)}})},73383:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{JF:()=>s,cI:()=>r,jd:()=>q});var e=c(76760),f=c(9753),g=c(99327),h=c(76452),i=a([g]);function j(a,b,c){if("string"!=typeof a)throw Error(`${b} must be a string`);let d=a.trim();if(!d||d.length>c)throw Error(`${b} must contain 1-${c} characters`);return d}function k(a,b,c){return null==a?null:j(a,b,c)}function l(a){if(void 0===a)return[];if(!Array.isArray(a)||a.length>12)throw Error("Task info must be an array with at most 12 items");return a.map((a,b)=>{if(!a||"object"!=typeof a||Array.isArray(a))throw Error(`Task info ${b} must be an object`);return{label:j(a.label,`Task info ${b} label`,64),value:j(a.value,`Task info ${b} value`,500)}})}function m(a,b){if("number"!=typeof a||!Number.isSafeInteger(a)||a<0)throw Error(`${b} must be a non-negative Unix millisecond timestamp`);return a}function n(a){if(!a||"object"!=typeof a)throw Error("Task snapshot is invalid");let b=function(a){switch(a){case"running":case"completed":case"failed":case"stopped":case"interrupted":return a;default:throw Error("Task status is invalid")}}(a.status),c=null===a.endedAt?null:m(a.endedAt,"Task endedAt");if("running"===b&&null!==c)throw Error("Running task requires endedAt=null");if("running"!==b&&null===c)throw Error("Terminal task requires endedAt");let d=function(a){if(null===a)return null;if(!a||"object"!=typeof a)throw Error("Task detailSource is invalid");if("text-file"===a.kind){let b=j(a.path,"Task text-file path",32768);if(!(0,e.isAbsolute)(b))throw Error("Task text-file path must be absolute");return{kind:"text-file",path:b}}if("pi-conversation"!==a.kind)throw Error("Task detailSource kind is invalid");if(void 0!==a.session){var b;if(!((b=a.session)&&"object"==typeof b&&"string"==typeof b.sessionId&&"function"==typeof b.sessionManager?.getBranch&&"function"==typeof b.agent?.subscribe))throw Error("Task AgentSession is invalid");return{kind:"pi-conversation",session:a.session}}let c=j(a.sessionFile,"Task sessionFile",32768);if(!(0,e.isAbsolute)(c))throw Error("Task sessionFile must be absolute");return{kind:"pi-conversation",sessionFile:c}}(a.detailSource);if("running"!==b&&d?.kind==="pi-conversation"&&d.session){let a=d.session.sessionFile;d=a?{kind:"pi-conversation",sessionFile:a}:null}return{record:{taskId:j(a.taskId,"Task id",200),taskKind:k(a.taskKind,"Task kind",100),taskType:k(a.taskType,"Task type",100),title:j(a.title,"Task title",200),info:l(a.info),status:b,activity:function(a){if(null==a)return null;if("string"!=typeof a)throw Error("Task activity must be a string");let b=a.trim();return b?b.length<=300?b:`${b.slice(0,299)}…`:null}(a.activity),startedAt:m(a.startedAt,"Task startedAt"),endedAt:c,detailSource:d,interrupt:"running"===b&&"function"==typeof a.interrupt?a.interrupt:null},infoLoader:function(a){if(null==a)return null;if("function"!=typeof a)throw Error("Task infoLoader must be a function");return a}(a.infoLoader)}}function o(a){let{detailSource:b,interrupt:c,...d}=a;return{...d,info:d.info.map(a=>({...a}))}}function p(a){let b=[],c=[];for(let d of a)"running"===d.status?b.push(d):c.push(d);return c.sort((a,b)=>(b.endedAt??0)-(a.endedAt??0)||b.startedAt-a.startedAt),[...b,...c.slice(0,100)].sort((a,b)=>b.startedAt-a.startedAt)}g=(i.then?(await i)():i)[0];class q{constructor(a,b){this.options=b,this.records=new Map,this.infoRuntimes=new Map,this.toolRuntimeOwners=new Map,this.disposed=!1,this.detailPool=new g.Il(a=>{let b=this.records.get(a);return b?{taskId:b.taskId,status:b.status,detailSource:b.detailSource,canInterrupt:"running"===b.status&&null!==b.interrupt}:null}),this.unsubscribe=a.on(f.O0,a=>{if(!this.disposed)try{this.apply(a)}catch(a){this.options.onInvalidReport(a)}})}summaries(){return p(this.records.values()).map(o)}activeTaskIds(){return[...this.records.values()].filter(a=>"running"===a.status).map(a=>a.taskId).sort()}record(a){return this.records.get(a)??null}async watchDetail(a,b){return await this.loadInfo(a),this.detailPool.watch(a,b)}readMessage(a,b){return this.detailPool.readMessage(a,b)}readImage(a,b,c){return this.detailPool.readImage(a,b,c)}async interrupt(a){let b=this.records.get(a);if(!b)throw new r(a);if("running"!==b.status||!b.interrupt)throw new s(a);await b.interrupt()}dispose(){if(!this.disposed){for(let a of(this.disposed=!0,this.unsubscribe(),this.detailPool.dispose(),this.toolRuntimeOwners.values()))a.lease.release();this.toolRuntimeOwners.clear(),this.records.clear(),this.infoRuntimes.clear()}}setToolRuntime(a,b){let c=b?.kind==="pi-conversation"?b.session:void 0,d=this.toolRuntimeOwners.get(a);if(d?.session!==c){if(d?.lease.release(),!c)return void this.toolRuntimeOwners.delete(a);this.toolRuntimeOwners.set(a,{session:c,lease:(0,h.s)(c)})}}releaseToolRuntime(a){this.toolRuntimeOwners.get(a)?.lease.release(),this.toolRuntimeOwners.delete(a)}setInfoLoader(a,b){let c=this.infoRuntimes.get(a);if(!b||c?.loader!==b){if(!b)return void this.infoRuntimes.delete(a);this.infoRuntimes.set(a,{loader:b,promise:null})}}async loadInfo(a){let b=this.infoRuntimes.get(a);if(!b)return;if(b.promise)return b.promise;let c=(async()=>{try{var c;if(!this.records.has(a))return;let d=l(await b.loader());if(this.infoRuntimes.get(a)!==b)return;this.infoRuntimes.delete(a);let e=this.records.get(a);if(!e||(c=e.info,c.length===d.length&&c.every((a,b)=>{let c=d[b];return a.label===c?.label&&a.value===c.value})))return;e.info=d,this.options.onChanged(this.summaries(),this.activeTaskIds())}catch(b){console.warn("[Pi Desk][TaskRuntime] 按需加载任务 info 失败",{taskId:a,errorName:b instanceof Error?b.name:"UnknownError"})}finally{this.infoRuntimes.get(a)===b&&(b.promise=null)}})();b.promise=c,await c}apply(a){if(!a||"object"!=typeof a)throw Error("Task report is invalid");let b=!1,c=new Set;if("upsert"===a.type){if(!Array.isArray(a.tasks))throw Error("Task upsert requires tasks");let d=a.tasks.map(n),e=new Set;for(let a of d){if(e.has(a.record.taskId))throw Error(`Task report contains duplicate id: ${a.record.taskId}`);e.add(a.record.taskId)}for(let a of d)this.records.set(a.record.taskId,a.record),this.setToolRuntime(a.record.taskId,a.record.detailSource),this.setInfoLoader(a.record.taskId,a.infoLoader),c.add(a.record.taskId),b=!0}else if("remove"===a.type){if(!Array.isArray(a.taskIds))throw Error("Task remove requires taskIds");for(let d of a.taskIds){let a=j(d,"Task id",200),e=this.records.delete(a);this.infoRuntimes.delete(a),this.releaseToolRuntime(a),e&&c.add(a),b=e||b}}else throw Error("Task report type is invalid");if(b){for(let a of this.trimTerminalHistory())c.add(a);for(let a of c)this.detailPool.taskChanged(a);this.options.onChanged(this.summaries(),this.activeTaskIds())}}trimTerminalHistory(){let a=[],b=new Set(p(this.records.values()).map(a=>a.taskId));for(let[c,d]of this.records)"running"===d.status||b.has(c)||(this.records.delete(c),this.infoRuntimes.delete(c),this.releaseToolRuntime(c),a.push(c));return a}}class r extends Error{constructor(a){super(`Task was not found: ${a}`),this.name="L4PiTaskNotFoundError"}}class s extends Error{constructor(a){super(`Task is not interruptible: ${a}`),this.name="L4PiTaskNotInterruptibleError"}}d()}catch(a){d(a)}})},73589:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{n:()=>n});var e=c(51455),f=c(48161),g=c(76760),h=c(58417),i=c(46107),j=a([i]);async function k(a){let b=await (0,e.realpath)(a).catch(()=>(0,g.resolve)(a));return"win32"===process.platform?b.toLowerCase():b}function l(a,b){return/^(npm:|git:|https?:|ssh:|git@)/.test(a)?null:a.startsWith("~/")?(0,g.join)((0,f.homedir)(),a.slice(2)):(0,g.resolve)(b,a)}function m(a,b){let c=(0,g.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,g.isAbsolute)(c)}async function n(a,b,c){let d=new Set((0,i.to)(a).disabled.map(h.LD)),f=new Set;for(let b of d){let c=l(b,a);c&&f.add(await k(c))}for(let c of b.listConfiguredPackages()){if("user"!==c.scope||!c.installedPath)continue;let b=l(c.source,a),e=b&&f.has(await k(b));(d.has((0,h.LD)(c.source))||e)&&f.add(await k(c.installedPath))}if(f.size>0){let d=(0,g.join)(a,"extensions"),h=await (0,e.readdir)(d,{withFileTypes:!0}).catch(a=>{if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return[];throw a}),i=[...b.listConfiguredPackages().filter(a=>"user"===a.scope).flatMap(a=>a.installedPath??[]),...h.filter(a=>!a.name.startsWith(".")&&"node_modules"!==a.name&&(a.isDirectory()||a.isSymbolicLink())).map(a=>(0,g.join)(d,a.name)),...(c.getGlobalSettings().extensions??[]).filter(a=>!/^[!+-]|[?*{}]/.test(a)).flatMap(b=>l(b,a)??[])],j=[];for(let a of i)await (0,e.stat)(a).then(a=>a.isDirectory(),()=>!1)&&j.push(await k(a));for(let a of(j.sort((a,b)=>b.length-a.length),[...f])){if(!await (0,e.stat)(a).then(a=>a.isFile(),()=>!1))continue;let b=j.find(b=>m(b,a));b&&f.add(b)}}let j=new Map;return async(a,b,c)=>{if(c&&d.has((0,h.LD)(a)))return!0;if(!b||b.startsWith("builtin:")||0===f.size)return!1;let e=j.get(b);e||(e=k(b),j.set(b,e));let g=await e;return[...f].some(a=>m(a,g))}}i=(j.then?(await j)():j)[0],d()}catch(a){d(a)}})},75613:(a,b,c)=>{c.d(b,{i:()=>n});var d=c(73024),e=c(51455),f=c(76760),g=c(56752);let h=/\u001b(?:\[[0-?]*[ -/]*[@-~]|\][^\u0007]*(?:\u0007|\u001b\\))/g;function i(a,b,c){for(let d of[...a])try{d(b)}catch(a){console.error("[Pi Desk][TextLogRuntime] 日志监听器执行失败",{path:c,errorName:a instanceof Error?a.name:"UnknownError"})}}async function j(a){let b;try{b=await (0,e.stat)(a)}catch(a){if("ENOENT"===a.code)return{text:"",truncated:!1};throw a}if(!b.isFile())throw Error(`Text log source is not a file: ${a}`);let c=Math.max(0,b.size-131072),d=b.size-c,f=await (0,e.open)(a,"r");try{let a=Buffer.alloc(d);d>0&&await f.read(a,0,d,c);let b=a.toString("utf8").replace(h,""),e=c>0;if(c>0){let a=b.indexOf("\n");a>=0&&(b=b.slice(a+1))}let g=b.split("\n");return g.length>1e3&&(b=g.slice(g.length-1e3).join("\n"),e=!0),{text:b,truncated:e}}finally{await f.close()}}class k{constructor(a,b){this.path=a,this.listeners=new Set,this.watcher=null,this.interval=null,this.refreshTimer=null,this.refreshPromise=null,this.disposed=!1,this.current=b}static async create(a){let b=new k(a,await j(a));return b.startWatching(),b}snapshot(){return{...this.current}}subscribe(a){if(this.disposed)throw Error("Text log runtime has been disposed");return this.listeners.add(a),()=>this.listeners.delete(a)}dispose(){this.disposed||(this.disposed=!0,this.watcher?.close(),this.interval&&clearInterval(this.interval),this.refreshTimer&&clearTimeout(this.refreshTimer),this.watcher=null,this.interval=null,this.refreshTimer=null,this.listeners.clear())}startWatching(){try{this.watcher=(0,d.watch)(this.path,()=>this.scheduleRefresh()),this.watcher.on("error",()=>this.scheduleRefresh())}catch{this.watcher=null}this.interval=setInterval(()=>this.scheduleRefresh(),500)}scheduleRefresh(){this.disposed||this.refreshTimer||(this.refreshTimer=setTimeout(()=>{this.refreshTimer=null,this.refresh()},40))}refresh(){return this.disposed?Promise.resolve():(this.refreshPromise||(this.refreshPromise=(async()=>{try{let a=await j(this.path);if(this.disposed||a.text===this.current.text&&a.truncated===this.current.truncated)return;let b=this.current;this.current=a;let c=a.text.startsWith(b.text)?a.text.slice(b.text.length):"";c&&a.truncated===b.truncated?i(this.listeners,{type:"text_append",text:c},this.path):i(this.listeners,{type:"snapshot",snapshot:{...a}},this.path)}catch(a){console.warn("[Pi Desk][TextLogRuntime] 刷新日志失败",{path:this.path,errorName:a instanceof Error?a.name:"UnknownError"}),i(this.listeners,{type:"unavailable"},this.path)}})().finally(()=>{this.refreshPromise=null})),this.refreshPromise)}}class l{async observe(a,b){if(this.disposed)throw Error("Text log pool has been disposed");let c=function(a){let b=a.trim();if(!b||b.length>32768||!(0,f.isAbsolute)(b))throw Error("Text log path must be an absolute path");return(0,f.resolve)(b)}(a),d=(0,g.b)(c),e=this.sharedByPath.get(d);if(!e){let a=this.pendingByPath.get(d);a||(a=k.create(c).then(a=>{if(this.disposed)throw a.dispose(),Error("Text log pool was disposed during initialization");let b={runtime:a,references:0};return this.sharedByPath.set(d,b),b}).finally(()=>{this.pendingByPath.delete(d)}),this.pendingByPath.set(d,a)),e=await a}e.references+=1;let h=e.runtime.subscribe(b),i=!1;return{snapshot:e.runtime.snapshot(),readSnapshot:()=>e.runtime.snapshot(),release:()=>{i||(i=!0,h(),e.references-=1,e.references>0||(this.sharedByPath.get(d)===e&&this.sharedByPath.delete(d),e.runtime.dispose()))}}}dispose(){if(!this.disposed){for(let a of(this.disposed=!0,this.sharedByPath.values()))a.runtime.dispose();this.sharedByPath.clear(),this.pendingByPath.clear()}}constructor(){this.sharedByPath=new Map,this.pendingByPath=new Map,this.disposed=!1}}let m=new l;function n(){return m}},76452:(a,b,c)=>{c.d(b,{s:()=>i});var d=c(77598),e=c(12727);let f=new WeakMap;function g(a){try{let b=JSON.stringify(a);return void 0===b?null:JSON.parse(b)}catch{return null}}class h{constructor(a){this.session=a,this.listeners=new Set,this.toolsById=new Map,this.disposed=!1,this.unsubscribeAgent=a.agent.subscribe(a=>this.captureAgentEvent(a)),this.unsubscribeSession=a.subscribe(a=>this.captureSessionEvent(a));const b=a.sessionManager.getBranch(),c=a.agent.state.pendingToolCalls;for(const a of function(a){let b=new Map;for(let c of a)if("message"===c.type)if("assistant"===c.message.role)for(let a of(0,e.zz)(c.message.content))b.set(a.id,a);else"toolResult"===c.message.role&&b.delete(c.message.toolCallId);return[...b.values()]}(b))c.has(a.id)&&this.upsertTool(a.id,a.name,a.input);const d=a.agent.state.streamingMessage;d&&this.syncStreamingTools(d,!1)}get size(){return this.toolsById.size}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}activeMessages(){return[...this.toolsById.values()].map(a=>({tempId:a.tempId,message:this.toolMessage(a)}))}tempId(a){return this.toolsById.get(a)?.tempId??null}syncStreamingTools(a,b=!0){if("assistant"===a.role)for(let c of(0,e.zz)(a.content)){let{tool:a,created:d,changed:e}=this.upsertTool(c.id,c.name,c.input);b&&(d?this.publish({type:"message_start",tempId:a.tempId,message:this.toolMessage(a)}):e&&this.publishToolUpdate(a))}}projectLiveResult(a,b){let c=this.toolsById.get(b);return(0,e.zK)(a,b,c?.display,c?.input)}remove(a){this.toolsById.delete(a)}discardAll(){for(let a of this.toolsById.values())this.publish({type:"message_discard",tempId:a.tempId});this.toolsById.clear()}dispose(){this.disposed||(this.disposed=!0,this.unsubscribeAgent(),this.unsubscribeSession(),this.listeners.clear(),this.toolsById.clear())}captureAgentEvent(a){if(!this.disposed&&(!("parentToolCallId"in a)||void 0===a.parentToolCallId))switch(a.type){case"tool_execution_start":this.startTool(a.toolCallId,a.toolName,a.args);return;case"tool_execution_update":this.updateTool(a.toolCallId,a.toolName,a.args,a.partialResult);return;case"tool_execution_end":this.endTool(a.toolCallId,a.toolName,a.result,a.isError);return;case"turn_end":this.discardAll();return;default:return}}captureSessionEvent(a){("agent_end"===a.type&&a.willRetry||"agent_settled"===a.type)&&queueMicrotask(()=>{this.disposed||this.discardAll()})}upsertTool(a,b,c){let f=c&&"object"==typeof c&&!Array.isArray(c)?{...c}:{},g=this.toolsById.get(a);if(g){var h;let a=(0,e.zG)(b,f,g.displayCache),c=g.name!==b||(h=g.display,h.reasoning!==a.reasoning||h.inputPreview!==a.inputPreview||h.activity!==a.activity);return g.name=b,g.input=f,g.display=a,{tool:g,created:!1,changed:c}}let i={},j={tempId:(0,d.randomUUID)(),toolCallId:a,name:b,display:(0,e.zG)(b,f,i),displayCache:i,input:f,partialResult:null,result:null,status:"running",startedAtMs:null,durationMs:null};return this.toolsById.set(a,j),{tool:j,created:!0,changed:!0}}startTool(a,b,c){let{tool:d,created:e,changed:f}=this.upsertTool(a,b,c),g="bash"===b&&null===d.startedAtMs;d.status="running",g&&(d.startedAtMs=Date.now()),e?this.publish({type:"message_start",tempId:d.tempId,message:this.toolMessage(d)}):(f||g)&&this.publishToolUpdate(d)}updateTool(a,b,c,d){this.startTool(a,b,c);let e=this.toolsById.get(a);e&&(e.partialResult=d,e.status="running",this.publishToolUpdate(e))}endTool(a,b,c,d){this.toolsById.has(a)||this.startTool(a,b,{});let e=this.toolsById.get(a);e&&("bash"===e.name&&null!==e.startedAtMs&&(e.durationMs=Math.max(0,Date.now()-e.startedAtMs),function(a,b){if(!a||"object"!=typeof a||Array.isArray(a))return;let c=a.details&&"object"==typeof a.details&&!Array.isArray(a.details)?a.details:{};a.details={...c,durationMs:b}}(c,e.durationMs)),e.result=c,e.status=d?"error":"completed",this.publishToolUpdate(e))}publishToolUpdate(a){this.publish({type:"message_update",tempId:a.tempId,message:this.toolMessage(a)})}toolMessage(a){let b;return{type:"tool",name:a.name,reasoning:a.display.reasoning,inputPreview:a.display.inputPreview,activity:a.display.activity,status:a.status,usage:null,output:"",startedAtMs:a.startedAtMs,durationMs:a.durationMs,declaration:{message:{kind:"tool",toolName:a.name,toolCallId:a.toolCallId,arguments:(b=g(a.input))&&"object"==typeof b&&!Array.isArray(b)?b:{},partialResult:g(a.partialResult),result:g(a.result),isError:"error"===a.status},raw:{toolCallId:a.toolCallId,toolName:a.name,args:a.input,partialResult:a.partialResult,result:a.result}}}}publish(a){for(let b of[...this.listeners])try{b(a)}catch(b){console.error("[Pi Desk][AgentToolRuntime] 事件监听器执行失败",{sessionId:this.session.sessionId,eventType:a.type,errorName:b instanceof Error?b.name:"UnknownError"})}}}function i(a){let b=f.get(a);b||(b={runtime:new h(a),references:0},f.set(a,b)),b.references+=1;let c=!1;return{runtime:b.runtime,release:()=>{c||(c=!0,b.references-=1,b.references>0||(f.delete(a),b.runtime.dispose()))}}}},77662:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{p:()=>r});var e=c(76760),f=c(75430),g=c(9753),h=c(59473),i=c(69503),j=c(73383),k=c(40333),l=a([f,j]);[f,j]=l.then?(await l)():l;let m=h.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),n=h.g1(h.Yj(),h.Pq()),o=h.g1(h.Yj().min(1),h.KC([n,h.ch()])),p=h.Ik({pluginName:m,event:m,data:n}).strict(),q=h.Ik({directory:h.Yj().min(1).max(4096).refine(a=>(0,e.isAbsolute)(a)&&!a.includes("\0")),default:h.zM().optional()}).strict();class r{constructor(a){this.options=a,this.controller=(0,f.createEventBus)(),this.slots=new Map,this.methods=new Map,this.unsubscribe=()=>void 0,this.unsubscribePush=()=>void 0,this.unsubscribePreviewDirectory=()=>void 0,this.disposed=!1,this.eventBus={emit:(a,b)=>{if(!this.disposed){if(a===g.Sl)return void this.applyMethodEvent(b);this.controller.emit(a,b)}},on:(a,b)=>this.disposed?()=>void 0:this.controller.on(a,b)},this.bindChannels()}createTaskRuntime(){let a=this.options;return new j.jd(this.controller,{onChanged:(b,c)=>{this.applyTaskSummaries(b),a.onTasksChanged(c),a.onChanged()},onInvalidReport:b=>a.onInvalidUpdate(b)})}bindChannels(){let a=this.options;this.taskRuntime=this.createTaskRuntime(),this.unsubscribe=this.controller.on(g.k0,b=>{if(this.disposed)return;let c=o.safeParse(b);if(!c.success)return void a.onInvalidUpdate(c.error);try{this.apply(c.data)&&a.onChanged()}catch(b){a.onInvalidUpdate(b)}}),this.unsubscribePreviewDirectory=this.controller.on(g.Nx,b=>{if(this.disposed)return;let c=q.safeParse(b);if(!c.success)return void a.onInvalidUpdate(c.error);try{this.applyPreviewDirectory(c.data)&&a.onChanged()}catch(b){a.onInvalidUpdate(b)}}),this.unsubscribePush=this.controller.on(g.Nb,b=>{if(this.disposed)return;let c=p.safeParse(b);c.success?Buffer.byteLength(JSON.stringify(c.data.data),"utf8")>65536?a.onInvalidUpdate(Error("Session Plugin Push data exceeds 64KB")):a.onPush(structuredClone(c.data)):a.onInvalidUpdate(c.error)})}activeTaskIds(){return this.taskRuntime.activeTaskIds()}taskRecord(a){return this.taskRuntime.record(a)}watchTaskDetail(a,b){return this.taskRuntime.watchDetail(a,b)}readTaskMessage(a,b){return this.taskRuntime.readMessage(a,b)}readTaskImage(a,b,c){return this.taskRuntime.readImage(a,b,c)}interruptTask(a){return this.taskRuntime.interrupt(a)}snapshot(){return Object.fromEntries([...this.slots.entries()].sort(([a],[b])=>a.localeCompare(b)).map(([a,b])=>[a,structuredClone(b.value)]))}async invokeMethod(a,b,c,d,e){if(this.disposed)throw Error("Pi session plugin runtime has been disposed");let f=(0,k.FX)(a),g=(0,k.QK)(b),h=this.methods.get((0,k.$m)(f,g));if(!h)throw new k.Tk(f,g);let i=await h.execute((0,k.nJ)(c,"input"),{source:d,extensionContext:e});return(0,k.nJ)(i,"output")}resetBranch(){this.disposed||(this.taskRuntime.dispose(),this.slots.clear(),this.taskRuntime=this.createTaskRuntime(),this.options.onTasksChanged([]),this.options.onChanged())}reset(){this.disposed||(this.unsubscribe(),this.unsubscribePush(),this.unsubscribePreviewDirectory(),this.taskRuntime.dispose(),this.controller.clear(),this.methods.clear(),this.slots.clear(),this.bindChannels(),this.options.onTasksChanged([]),this.options.onChanged())}dispose(){this.disposed||(this.disposed=!0,this.unsubscribe(),this.unsubscribePush(),this.unsubscribePreviewDirectory(),this.taskRuntime.dispose(),this.controller.clear(),this.methods.clear(),this.slots.clear())}applyMethodEvent(a){if(!a||"object"!=typeof a||Array.isArray(a))throw Error("Session plugin method event is invalid");let b=a.registration;if("register"!==a.type&&"unregister"!==a.type||!b||"object"!=typeof b||"string"!=typeof b.pluginName||"string"!=typeof b.method||"function"!=typeof b.execute)throw Error("Session plugin method registration is invalid");let c=(0,k.FX)(b.pluginName),d=(0,k.QK)(b.method),e=(0,k.$m)(c,d);if("register"===a.type){if(this.methods.has(e))throw new k.qs(c,d);this.methods.set(e,b);return}this.methods.get(e)===b&&this.methods.delete(e)}applyTaskSummaries(a){if(0===a.length)return void this.slots.delete("task-center");let b={tasks:a.map(a=>({...a,info:a.info.map(a=>({...a}))}))};this.slots.set("task-center",{serialized:JSON.stringify(b),value:b})}applyPreviewDirectory(a){let b=(0,e.resolve)(a.directory),c=(0,i.Yj)(b),d=this.slots.get(i.s6),f=(0,i.D)(d?.value),g=f.directories.find(a=>(0,i.Yj)(a)===c);if(!g&&f.directories.length>=i.xI)throw Error(`会话预览目录数量已达上限 ${i.xI}`);let h=g??b,j={directories:g?f.directories:[...f.directories,h],defaultDirectory:!0===a.default?h:f.defaultDirectory},k=JSON.stringify(j);return d?.serialized!==k&&(this.slots.set(i.s6,{serialized:k,value:j}),!0)}apply(a){if(Object.hasOwn(a,"task-center"))throw Error("task-center plugin slot is reserved by the Task Runtime");if(Object.hasOwn(a,i.s6))throw Error("project-preview 插件槽由会话预览目录登记管理");let b=!1;for(let[c,d]of Object.entries(a)){if(null===d){b=this.slots.delete(c)||b;continue}let a=JSON.stringify(d);this.slots.get(c)?.serialized!==a&&(this.slots.set(c,{serialized:a,value:d}),b=!0)}return b}}d()}catch(a){d(a)}})},77844:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{lr:()=>m,mu:()=>l,ni:()=>i,qc:()=>j,ti:()=>k});var e=c(73024),f=c(75430),g=c(54174),h=a([f]);f=(h.then?(await h)():h)[0];let m=0x1f00000;class n extends Error{constructor(a){super(a),this.name="L4PiChatInputError"}}function i(a){if(!a.text.trim()&&0===a.images.length)throw new n("请输入文字或添加图片");return{text:a.text,images:a.images.map(a=>({...a})),imageBytes:function(a){if(a.length>10)throw new n("单次最多发送 10 张图片");let b=0;for(let c of a){let a=(0,g.f1)(c);if(a.bytes.length>0xa00000)throw new n("单张图片压缩后不能超过 10MB");b+=a.bytes.length}if(b>0x1400000)throw new n("单次发送图片总量不能超过 20MB");return b}(a.images)}}function j(a,b,c,d){let h=function(a,b){var c,d;let e;if(!a.startsWith("/"))return a;let f=a.match(/^\/([^\s]+)(?:\s+([\s\S]*))?$/);if(!f)return a;let g=b.find(a=>a.name===f[1]);return g?(c=g.content,e=(d=function(a){let b=[],c="",d=null;for(let e of a){if(d){e===d?d=null:c+=e;continue}if('"'===e||"'"===e){d=e;continue}if(/\s/.test(e)){c&&b.push(c),c="";continue}c+=e}return c&&b.push(c),b}(f[2]??"")).join(" "),c.replace(/\$\{(\d+|ARGUMENTS|@):-([^}]*)\}|\$\{@:(\d+)(?::(\d+))?\}|\$(ARGUMENTS|@|\d+)/g,(a,b,c,f,g,h)=>{if("string"==typeof b)return("@"===b||"ARGUMENTS"===b?e:d[Number.parseInt(b,10)-1])||c;if("string"==typeof f){let a=Math.max(0,Number.parseInt(f,10)-1);return"string"==typeof g?d.slice(a,a+Number.parseInt(g,10)).join(" "):d.slice(a).join(" ")}return"ARGUMENTS"===h||"@"===h?e:d[Number.parseInt(h,10)-1]??""})):a}(function(a,b){if(!a.startsWith("/skill:"))return a;let c=a.indexOf(" "),d=-1===c?a.slice(7):a.slice(7,c),g=-1===c?"":a.slice(c+1).trim(),h=b.find(a=>a.name===d);if(!h)return a;try{let a=(0,f.stripFrontmatter)((0,e.readFileSync)(h.filePath,"utf8")).trim(),b=`<skill name="${h.name}" location="${h.filePath}">
29
29
  References are relative to ${h.baseDir}.
@@ -1 +1 @@
1
- globalThis.__BUILD_MANIFEST={polyfillFiles:["static/chunks/polyfills-42372ed130431b0a.js"],devFiles:[],lowPriorityFiles:["static/SUWCp0trQPQnnw0za1R_Y/_buildManifest.js","static/SUWCp0trQPQnnw0za1R_Y/_ssgManifest.js"],rootMainFiles:["static/chunks/webpack-a84310d111797bef.js","static/chunks/e388c842-1ca92f1ea0dfe8ee.js","static/chunks/64444-3e955f910569274d.js","static/chunks/main-app-6230945a5a062fce.js"],rootMainFilesTree:{},pages:{"/_app":[]}};
1
+ globalThis.__BUILD_MANIFEST={polyfillFiles:["static/chunks/polyfills-42372ed130431b0a.js"],devFiles:[],lowPriorityFiles:["static/OKkvmSoIKvwTgI3I2x3yp/_buildManifest.js","static/OKkvmSoIKvwTgI3I2x3yp/_ssgManifest.js"],rootMainFiles:["static/chunks/webpack-a84310d111797bef.js","static/chunks/e388c842-1ca92f1ea0dfe8ee.js","static/chunks/64444-3e955f910569274d.js","static/chunks/main-app-6230945a5a062fce.js"],rootMainFilesTree:{},pages:{"/_app":[]}};