@jetcrab/pi-desk 1.1.1 → 1.1.5-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 (119) hide show
  1. package/docs/pi-desk/README.md +47 -0
  2. package/docs/pi-desk/commands.md +76 -0
  3. package/docs/pi-desk/examples/local-application/browser/application.js +106 -0
  4. package/docs/pi-desk/examples/local-application/browser/entry.js +9 -0
  5. package/docs/pi-desk/examples/local-application/package.json +9 -0
  6. package/docs/pi-desk/examples/local-application/pi-desk.ts +11 -0
  7. package/docs/pi-desk/plugins.md +119 -0
  8. package/package.json +3 -2
  9. package/src/client/l2_biz/pi-settings/hooks/l2-use-pi-settings.ts +37 -21
  10. package/src/client/l2_biz/pi-settings/l2-pi-settings.tsx +37 -43
  11. package/src/client/l2_biz/pi-settings/views/l2-mcp-settings-editor.tsx +3 -1
  12. package/src/client/l2_biz/pi-settings/views/l2-mcp-settings-list.tsx +1 -1
  13. package/src/client/l2_biz/plugin-host/hooks/l2-use-plugin-catalog.ts +3 -1
  14. package/src/client/l2_biz/plugin-host/hooks/l2-use-plugin-download-source.ts +5 -1
  15. package/src/client/l2_biz/plugin-host/l2-plugin-capability-details.tsx +57 -41
  16. package/src/client/l2_biz/plugin-host/l2-plugin-management-controls.tsx +89 -116
  17. package/src/client/l2_biz/plugin-host/l2-plugin-management.tsx +492 -338
  18. package/src/client/l2_biz/plugin-host/l2-use-plugin-management.ts +72 -22
  19. package/src/client/l2_biz/plugin-host/views/l2-plugin-catalog-detail.tsx +104 -76
  20. package/src/client/l2_biz/plugin-host/views/l2-plugin-catalog-search.tsx +101 -56
  21. package/src/client/l2_biz/plugin-host/views/l2-plugin-direct-install.tsx +91 -59
  22. package/src/client/l2_biz/plugin-host/views/l2-plugin-download-source.tsx +36 -27
  23. package/src/client/l2_biz/plugin-host/views/l2-plugin-installed-list.tsx +218 -208
  24. package/src/client/l2_biz/plugin-host/views/l2-plugin-management-channel.tsx +12 -5
  25. package/src/client/l2_biz/plugin-host/views/l2-plugin-management-dialog.tsx +84 -106
  26. package/src/client/l2_biz/plugin-host/views/l2-plugin-readme.tsx +29 -15
  27. package/src/client/l2_biz/settings/hooks/l2-use-project-model-default-settings.ts +22 -11
  28. package/src/client/l2_biz/settings/l2-settings.tsx +6 -11
  29. package/src/client/l2_biz/settings/views/l2-project-model-default-settings.tsx +20 -14
  30. package/src/client/l2_biz/terminal/l2-terminal-workspace.tsx +35 -1
  31. package/src/client/l2_biz/workbench/file-workspace/l2-work-session-file-preview.tsx +6 -2
  32. package/src/client/l2_biz/workbench/hooks/l2-workbench-chat-viewport.ts +14 -1
  33. package/src/client/l2_biz/workbench/l2-workbench-branch-picker.tsx +33 -5
  34. package/src/client/l2_biz/workbench/l2-workbench-sidebar-layout.tsx +3 -1
  35. package/src/client/l2_biz/workbench/l2-workbench.tsx +20 -3
  36. package/src/client/l3_modules/conversation/l3-conversation-call-summary.tsx +0 -3
  37. package/src/client/l3_modules/project-files/l3-file-context-menu-content.tsx +1 -0
  38. package/src/client/l4_foundation/ui/l4-app-dialog.tsx +3 -1
  39. package/src/client/l4_foundation/ui/l4-image-viewer.tsx +21 -0
  40. package/src/client/l4_foundation/ui/shadcn/checkbox.tsx +27 -0
  41. package/src/client/l4_foundation/ui/shadcn/context-menu.tsx +8 -1
  42. package/src/client/l4_foundation/ui/shadcn/dropdown-menu.tsx +5 -0
  43. package/src/client/l4_foundation/ui/shadcn/popover.tsx +2 -0
  44. package/src/client/l4_foundation/ui/shadcn/select.tsx +2 -0
  45. package/src/client/l4_foundation/ui/shadcn/switch.tsx +31 -0
  46. package/src/client/l4_foundation/ui/shadcn/tabs.tsx +74 -0
  47. package/src/common/l2_biz/plugin/l2-plugin-management-messages.ts +52 -22
  48. package/src/common/l3_modules/conversation/l3-conversation-locale-messages.ts +2 -2
  49. package/src/common/l3_modules/conversation/l3-conversation-pidesk.ts +1 -1
  50. package/src/common/l4_foundation/plugin/l4-plugin-package.ts +1 -0
  51. package/src/server/l2_biz/plugin-management/l2-plugin-catalog.ts +16 -5
  52. package/src/server/l2_biz/plugin-management/l2-plugin-commands.ts +21 -1
  53. package/src/server/l2_biz/plugin-management/l2-plugin-management.ts +21 -2
  54. package/src/server/l2_biz/plugin-management/l2-plugin-updates.ts +17 -3
  55. package/src/server/l4_foundation/pi/l4-pi-basic-session-services.ts +3 -3
  56. package/src/server/l4_foundation/pi/l4-pi-package-maintenance-runner.mts +4 -11
  57. package/src/server/l4_foundation/pi/l4-pi-plugin-registry-config.ts +52 -34
  58. package/src/server/l4_foundation/pi/l4-pi-plugin-registry-network.ts +5 -3
  59. package/src/server/l4_foundation/pi/l4-pi-plugin-registry.ts +23 -8
  60. package/src/server/l4_foundation/pi/l4-pi-session-initialization.ts +2 -5
  61. package/src/server/l4_foundation/pidesk/l4-pidesk-command.ts +8 -1
  62. package/src/server/l4_foundation/pidesk/l4-pidesk-runtime.ts +24 -38
  63. package/src/server/l4_foundation/pidesk/l4-pidesk-system-prompt.ts +11 -0
  64. package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
  65. package/temp/build/pi-desk/release/.next/build-manifest.json +3 -3
  66. package/temp/build/pi-desk/release/.next/prerender-manifest.json +3 -3
  67. package/temp/build/pi-desk/release/.next/react-loadable-manifest.json +1 -1
  68. package/temp/build/pi-desk/release/.next/required-server-files.js +3 -3
  69. package/temp/build/pi-desk/release/.next/required-server-files.json +3 -3
  70. package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  71. package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
  72. package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +3 -3
  73. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +3 -3
  74. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +3 -3
  75. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  76. package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  77. package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
  78. package/temp/build/pi-desk/release/.next/server/app/login/page.js +1 -1
  79. package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
  80. package/temp/build/pi-desk/release/.next/server/app/page.js +79 -79
  81. package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
  82. package/temp/build/pi-desk/release/.next/server/chunks/25406.js +8 -77
  83. package/temp/build/pi-desk/release/.next/server/chunks/{81107.js → 35348.js} +2 -2
  84. package/temp/build/pi-desk/release/.next/server/chunks/35985.js +4 -4
  85. package/temp/build/pi-desk/release/.next/server/chunks/36361.js +1 -1
  86. package/temp/build/pi-desk/release/.next/server/chunks/47757.js +6 -75
  87. package/temp/build/pi-desk/release/.next/server/chunks/50520.js +4 -4
  88. package/temp/build/pi-desk/release/.next/server/chunks/58330.js +1 -1
  89. package/temp/build/pi-desk/release/.next/server/chunks/84231.js +2 -2
  90. package/temp/build/pi-desk/release/.next/server/chunks/89236.js +2 -2
  91. package/temp/build/pi-desk/release/.next/server/chunks/92386.js +5 -5
  92. package/temp/build/pi-desk/release/.next/server/chunks/94518.js +1 -1
  93. package/temp/build/pi-desk/release/.next/server/chunks/9874.js +1 -1
  94. package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
  95. package/temp/build/pi-desk/release/.next/server/middleware-react-loadable-manifest.js +1 -1
  96. package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
  97. package/temp/build/pi-desk/release/.next/server/server-reference-manifest.json +1 -1
  98. package/temp/build/pi-desk/release/.next/static/chunks/14197-3d3ddd426ac06c9c.js +3 -0
  99. package/temp/build/pi-desk/release/.next/static/chunks/34903-e4205c0becabea76.js +318 -0
  100. package/temp/build/pi-desk/release/.next/static/chunks/{54206.7c0792096df8a5cf.js → 54206.82a63ab971911eda.js} +3 -3
  101. package/temp/build/pi-desk/release/.next/static/chunks/74132-876f256c7a6101af.js +13 -0
  102. package/temp/build/pi-desk/release/.next/static/chunks/78923-17a9c337b29dcecd.js +1 -0
  103. package/temp/build/pi-desk/release/.next/static/chunks/96995-8f8313ea2ac3abd7.js +62 -0
  104. package/temp/build/pi-desk/release/.next/static/chunks/app/{layout-7c5409cced9c2501.js → layout-4faf3a52d219296d.js} +2 -2
  105. package/temp/build/pi-desk/release/.next/static/chunks/app/login/{page-8c87fb9e6c918848.js → page-bf893718bb151f3c.js} +1 -1
  106. package/temp/build/pi-desk/release/.next/static/chunks/app/page-28e1d77d6b884657.js +158 -0
  107. package/temp/build/pi-desk/release/.next/static/chunks/{webpack-45424d28099bbefa.js → webpack-7bfbf627379fb4c1.js} +1 -1
  108. package/temp/build/pi-desk/release/.next/static/css/3213ee28336bddc2.css +1 -0
  109. package/temp/build/pi-desk/release/.next/trace-build +1 -1
  110. package/src/server/l4_foundation/pidesk/l4-pidesk-skill-template.ts +0 -87
  111. package/temp/build/pi-desk/release/.next/static/chunks/27491-8b2d3e345b9142ea.js +0 -318
  112. package/temp/build/pi-desk/release/.next/static/chunks/7089-600a8f5593b7846c.js +0 -3
  113. package/temp/build/pi-desk/release/.next/static/chunks/74132-0884df6a6f11861a.js +0 -13
  114. package/temp/build/pi-desk/release/.next/static/chunks/78923-539a8b5f7af3c54a.js +0 -1
  115. package/temp/build/pi-desk/release/.next/static/chunks/96995-ae32167974365050.js +0 -62
  116. package/temp/build/pi-desk/release/.next/static/chunks/app/page-39b146293b6eb488.js +0 -158
  117. package/temp/build/pi-desk/release/.next/static/css/56486914a8ba0a1b.css +0 -1
  118. /package/temp/build/pi-desk/release/.next/static/{STVrBHA3z9KPtvBE4WcE2 → IgHJ40fniC07-ioYUKobL}/_buildManifest.js +0 -0
  119. /package/temp/build/pi-desk/release/.next/static/{STVrBHA3z9KPtvBE4WcE2 → IgHJ40fniC07-ioYUKobL}/_ssgManifest.js +0 -0
@@ -22,8 +22,8 @@ ${g}`:b}catch{return a}}(a,c),d),j=(b??[]).map(a=>{let b=(0,g.Z)(a.data);if(b.me
22
22
  步骤:导入插件模块`,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}
23
23
  步骤:执行插件工厂`,c,async()=>{if("function"!=typeof e.default)throw Error(`扩展必须导出工厂函数:${a.path}`);await e.default(b)})}})),q=f.SettingsManager.inMemory({},{projectTrusted:i.isProjectTrusted()});d=new f.DefaultResourceLoader({...b,cwd:a,agentDir:h,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)}
24
24
  步骤:${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 o(!1);let p=new Proxy(d,{get:(a,b)=>{if("reload"===b)return()=>o(!0);let c=Reflect.get(d,b,d);return"function"==typeof c?c.bind(d):c}}),q=p.getExtensions().runtime;for(let{name:a,config:b,extensionPath:c}of q.pendingProviderRegistrations)try{n.registerProvider(a,b)}catch(a){j.push({type:"error",message:`${c}: ${String(a)}`})}for(let{provider:a,extensionPath:b}of q.pendingNativeProviderRegistrations)try{n.registerNativeProvider(a)}catch(a){j.push({type:"error",message:`${b}: ${String(a)}`})}for(let{definition:a,extensionPath:b}of q.pendingVirtualModelRegistrations)try{n.registerVirtualModel(a)}catch(a){j.push({type:"error",message:`${b}: ${String(a)}`})}return q.pendingProviderRegistrations=[],q.pendingNativeProviderRegistrations=[],q.pendingVirtualModelRegistrations=[],await l("刷新模型与认证配置",c,()=>n.refresh({allowNetwork:!1})),j.push(...i.drainErrors().map(({error:a})=>({type:"error",message:a.message}))),{cwd:a,agentDir:h,settingsManager:i,modelRuntime:n,resourceLoader:p,diagnostics:j}}constructor(){this.selection=null}}d()}catch(a){d(a)}})},27519:(a,b,c)=>{c.d(b,{_g:()=>g,eC:()=>h,rh:()=>f});var d=c(36153);function e(a,b){return""===a?b:!(a.length>4096||a.startsWith("/")||a.includes("\\")||a.includes("\0")||/^[a-zA-Z]:/.test(a))&&a.split("/").every(a=>a.length>0&&"."!==a&&".."!==a)}let f=d.Yj().max(4096).refine(a=>e(a,!0),"目录路径必须是规范相对路径"),g=d.Yj().min(1).max(4096).refine(a=>e(a,!1),"文件路径必须是规范相对路径"),h=d.Yj().min(1).max(4096).refine(a=>e(a,!1)||a.length>0&&a.length<=4096&&!a.includes("\0")&&(a.startsWith("/")||a.startsWith("\\\\")||/^[a-zA-Z]:[\\/]/.test(a)),"预览路径必须是规范相对路径或绝对路径");d.k5(["compressed","original"]);let i=d.k5(["image/jpeg","image/png","image/webp","image/gif"]),j=d.Ik({name:d.Yj().min(1),type:d.k5(["directory","file"])}).strict();d.Ik({entries:d.YO(j).max(5e3),truncated:d.zM()}).strict(),d.Ik({matches:d.YO(g).max(100),truncated:d.zM()}).strict(),d.gM("kind",[d.Ik({kind:d.eu("text"),content:d.Yj(),size:d.ai().int().nonnegative().max(5242880)}).strict(),d.Ik({kind:d.eu("image"),mimeType:i,data:d.Yj().min(1),size:d.ai().int().positive().max(0xa00000)}).strict()])},32757:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{HJ:()=>x,Il:()=>u,L9:()=>v,dw:()=>w});var e=c(77598),f=c(73024),g=c(78555),h=c(60161),i=c(35350),j=c(42118),k=a([j]);function l(a){if(!a||"object"!=typeof a)return null;let b=a.role;return"string"==typeof b?b:null}function m(a){if(!a||"object"!=typeof a)return null;let b=a.toolCallId;return"string"==typeof b?b:null}function n(a){return null===a?null:"text-file"===a.kind?`text:${a.path}`:void 0!==a.session?a.session:`session-file:${a.sessionFile}`}function o(a,b,c){for(let d of[...a])try{d(b)}catch(a){console.error("[Pi Desk][TaskDetailRuntime] 事件监听器执行失败",{label:c,errorName:a instanceof Error?a.name:"UnknownError"})}}j=(k.then?(await k)():k)[0];class q{snapshot(){return null}subscribe(){return()=>void 0}dispose(){}}class r{constructor(a,b,c){this.path=a,this.observation=c,this.listeners=new Set,this.disposed=!1,this.current=b}static async create(a){let b=[],c=null,d=await (0,g.i)().observe(a,a=>{c?c.handleLogEvent(a):b.push(a)});for(let e of(c=new r(a,d.snapshot,d),b))c.handleLogEvent(e);return c}snapshot(){return{kind:"text",...this.current}}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}dispose(){this.disposed||(this.disposed=!0,this.observation.release(),this.listeners.clear())}handleLogEvent(a){if(!this.disposed){if("snapshot"===a.type){this.current={...a.snapshot},o(this.listeners,{type:"snapshot"},this.path);return}if("text_append"===a.type){this.current={...this.current,text:this.current.text+a.text},o(this.listeners,a,this.path);return}o(this.listeners,a,this.path)}}}class s{constructor(a,b){this.sessionFile=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 s(a,await (0,j.mH)(a));return b.startWatching(),b}snapshot(){return{kind:"conversation",entries:this.current.entries,temporaryMessages:[],truncated:this.current.truncated}}subscribe(a){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,f.watch)(this.sessionFile,()=>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 (0,j.mH)(this.sessionFile);if(this.disposed)return;let b=this.current.entries.map(a=>a.entryId),c=a.entries.map(a=>a.entryId);if(b.length===c.length&&b.every((a,b)=>a===c[b])){this.current=a;return}let d=!this.current.truncated&&!a.truncated&&b.every((a,b)=>a===c[b])?a.entries.slice(b.length):[];this.current=a,d.length>0?o(this.listeners,{type:"conversation_event",event:{type:"durable_append",entries:d}},this.sessionFile):o(this.listeners,{type:"snapshot"},this.sessionFile)}catch(a){console.warn("[Pi Desk][TaskSessionFileDetail] 刷新会话失败",{sessionFile:this.sessionFile,errorName:a instanceof Error?a.name:"UnknownError"}),o(this.listeners,{type:"unavailable"},this.sessionFile)}})().finally(()=>{this.refreshPromise=null})),this.refreshPromise)}}class t{constructor(a){for(const b of(this.session=a,this.listeners=new Set,this.temporaryMessages=new Map,this.temporaryOrder=[],this.pendingEvents=[],this.activeMessage=null,this.drainScheduled=!1,this.disposed=!1,this.toolRuntimeLease=(0,i.s)(a),this.toolRuntime=this.toolRuntimeLease.runtime,this.unsubscribeToolRuntime=this.toolRuntime.subscribe(a=>this.captureToolEvent(a)),this.unsubscribeAgent=a.agent.subscribe(b=>{try{this.captureAgentEvent(b)}catch(c){console.error("[Pi Desk][TaskAgentDetail] 捕获 AgentEvent 失败",{sessionId:a.sessionId,eventType:b.type,errorName:c instanceof Error?c.name:"UnknownError"})}}),this.entries=(0,h.xm)(a.sessionManager.getBranch()),this.toolRuntime.activeMessages()))this.setTemporary(b.tempId,b.message);const b=a.agent.state.streamingMessage;if(b){const a=(0,h.b7)(b);if(a){const c=(0,e.randomUUID)();for(const d of(this.activeMessage={tempId:c,started:!0,toolCallId:null},this.setTemporary(c,a),this.toolRuntime.syncStreamingTools(b,!1),this.toolRuntime.activeMessages()))this.setTemporary(d.tempId,d.message)}}}snapshot(){return{kind:"conversation",entries:this.entries,temporaryMessages:this.temporaryOrder.flatMap(a=>{let b=this.temporaryMessages.get(a);return b?[{tempId:a,message:b}]:[]}),truncated:!1}}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}dispose(){this.disposed||(this.disposed=!0,this.unsubscribeAgent(),this.unsubscribeToolRuntime(),this.toolRuntimeLease.release(),this.listeners.clear(),this.pendingEvents.length=0,this.temporaryMessages.clear(),this.temporaryOrder.length=0)}captureAgentEvent(a){if(!this.disposed)switch(a.type){case"message_start":this.startMessage(a.message);return;case"message_update":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}}captureToolEvent(a){if(!this.disposed){if("message_discard"===a.type){this.removeTemporary(a.tempId),this.queueEvent(a);return}this.setTemporary(a.tempId,a.message),this.queueEvent(a)}}startMessage(a){let b=l(a),c=(0,e.randomUUID)(),d=!0,f=null;if("toolResult"===b){let b=(f=m(a))?this.toolRuntime.tempId(f):null;b&&(c=b,d=!1)}let g=this.projectLiveMessage(a,f);g&&(this.activeMessage={tempId:c,started:d,toolCallId:f},this.setTemporary(c,g),this.queueEvent({type:d?"message_start":"message_update",tempId:c,message:g}))}updateMessage(a){let b=this.activeMessage;if(!b)return;let c=this.projectLiveMessage(a,b.toolCallId);c&&(this.setTemporary(b.tempId,c),this.queueEvent({type:"message_update",tempId:b.tempId,message:c}))}endMessage(a){let b=this.activeMessage,c=l(a),d="toolResult"===c?m(a):null;if(!b){let c=this.projectLiveMessage(a,d);if(!c)return;b={tempId:(0,e.randomUUID)(),started:!0,toolCallId:d},this.setTemporary(b.tempId,c),this.queueEvent({type:"message_start",tempId:b.tempId,message:c})}let f=this.projectLiveMessage(a,b.toolCallId);f&&(this.setTemporary(b.tempId,f),this.queueEvent({type:"message_update",tempId:b.tempId,message:f}));let g=this.session.sessionManager.getLeafEntry(),i=g?(0,h.B4)(g):null;g&&i?(this.entries.some(a=>a.entryId===i.entryId)||(this.entries=[...this.entries,i]),this.removeTemporary(b.tempId),this.queueEvent({type:"message_commit",tempId:b.tempId,entryId:i.entryId,timestampMs:function(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}(g.id,g.timestamp)})):b.started&&(this.removeTemporary(b.tempId),this.queueEvent({type:"message_discard",tempId:b.tempId})),b.toolCallId&&this.toolRuntime.remove(b.toolCallId),this.activeMessage=null}projectLiveMessage(a,b){return"toolResult"===l(a)&&b?this.toolRuntime.projectLiveResult(a,b):(0,h.b7)(a)}setTemporary(a,b){this.temporaryMessages.has(a)||this.temporaryOrder.push(a),this.temporaryMessages.set(a,b)}removeTemporary(a){this.temporaryMessages.delete(a);let b=this.temporaryOrder.indexOf(a);b>=0&&this.temporaryOrder.splice(b,1)}queueEvent(a){if(!this.disposed){if("message_update"===a.type){let b=this.pendingEvents.at(-1);b?.type==="message_update"&&b.tempId===a.tempId?this.pendingEvents[this.pendingEvents.length-1]=a:this.pendingEvents.push(a)}else this.pendingEvents.push(a);this.drainScheduled||(this.drainScheduled=!0,queueMicrotask(()=>this.drainEvents()))}}drainEvents(){if(this.drainScheduled=!1,!this.disposed)for(;this.pendingEvents.length>0;){let a=this.pendingEvents.shift();o(this.listeners,{type:"conversation_event",event:a},this.session.sessionId)}}}async function p(a){return null===a?new q:"text-file"===a.kind?r.create(a.path):void 0!==a.session?new t(a.session):s.create(a.sessionFile)}class u{constructor(a){this.readRecord=a,this.sharedByTaskId=new Map,this.operationTail=Promise.resolve(),this.disposed=!1}watch(a,b){return this.enqueue(()=>this.watchInternal(a,b))}taskChanged(a){this.enqueue(async()=>{let b=this.sharedByTaskId.get(a);if(!b)return;let c=this.readRecord(a);if(!c){o(b.listeners,{type:"unavailable"},a),this.disposeShared(a,b);return}n(c.detailSource)!==b.sourceIdentity?await this.replaceShared(a,b,c):b.canInterrupt!==c.canInterrupt&&(b.canInterrupt=c.canInterrupt,o(b.listeners,{type:"snapshot",snapshot:this.snapshot(a,b)},a))})}async readMessage(a,b){let c=this.readRecord(a);if(!c)throw new v(a);let d=c.detailSource;if(d?.kind!=="pi-conversation")throw new w(a);if(void 0!==d.session){let a=(0,h.xm)(d.session.sessionManager.getBranch()),c=a.findIndex(a=>a.entryId===b);if(c<0)throw new x(b);return{index:c,entry:a[c]}}let e=await (0,j.uS)(d.sessionFile,b),f=e.snapshot.entries.findIndex(a=>a.entryId===b);if(f<0)throw new x(b);return{index:f,entry:e.projected}}async readImage(a,b,c){if(!Number.isSafeInteger(c)||c<0)throw Error("图片位置无效");let d=this.readRecord(a);if(!d)throw new v(a);let e=d.detailSource;if(e?.kind!=="pi-conversation")throw new w(a);if(void 0===e.session)return(0,j.tE)(e.sessionFile,b,c);if(!e.session.sessionManager.getBranch().some(a=>a.id===b))throw new x(b);let f=e.session.sessionManager.getEntry(b);if(f?.type!=="message"||"user"!==f.message.role&&"toolResult"!==f.message.role)throw new x(b);let g=(0,h.Wl)(f.message.content,c);if(!g)throw new x(`${b}/${c}`);return g}dispose(){if(!this.disposed){for(let[a,b]of(this.disposed=!0,this.sharedByTaskId))this.disposeShared(a,b);this.sharedByTaskId.clear()}}async watchInternal(a,b){if(this.disposed)throw Error("Task detail pool has been disposed");let c=this.readRecord(a);if(!c)throw new v(a);let d=this.sharedByTaskId.get(a),e=n(c.detailSource);if(!d||d.sourceIdentity!==e){d?.unsubscribeSource(),d?.sourceRuntime.dispose();let b=await p(c.detailSource);if(this.disposed)throw b.dispose(),Error("Task detail pool was disposed during initialization");(d={sourceRuntime:b,sourceIdentity:e,canInterrupt:c.canInterrupt,listeners:new Set,unsubscribeSource:()=>void 0}).unsubscribeSource=b.subscribe(b=>this.handleSourceEvent(a,d,b)),this.sharedByTaskId.set(a,d)}d.canInterrupt=c.canInterrupt,d.listeners.add(b);let f=!1;return{snapshot:this.snapshot(a,d),readSnapshot:()=>this.snapshot(a,d),release:()=>{f||(f=!0,this.release(a,d,b))}}}enqueue(a){let b=this.operationTail.then(a,a);return this.operationTail=b.then(()=>void 0,()=>void 0),b}snapshot(a,b){return{taskId:a,canInterrupt:b.canInterrupt,body:b.sourceRuntime.snapshot()}}handleSourceEvent(a,b,c){if(this.sharedByTaskId.get(a)===b){if("snapshot"===c.type)return void o(b.listeners,{type:"snapshot",snapshot:this.snapshot(a,b)},a);o(b.listeners,c,a)}}release(a,b,c){this.sharedByTaskId.get(a)===b&&(b.listeners.delete(c),0===b.listeners.size&&this.disposeShared(a,b))}disposeShared(a,b){this.sharedByTaskId.get(a)===b&&this.sharedByTaskId.delete(a),b.unsubscribeSource(),b.sourceRuntime.dispose(),b.listeners.clear()}async replaceShared(a,b,c){try{let d=await p(c.detailSource);if(this.sharedByTaskId.get(a)!==b)return void d.dispose();b.unsubscribeSource(),b.sourceRuntime.dispose(),b.sourceRuntime=d,b.sourceIdentity=n(c.detailSource),b.canInterrupt=c.canInterrupt,b.unsubscribeSource=d.subscribe(c=>this.handleSourceEvent(a,b,c)),o(b.listeners,{type:"snapshot",snapshot:this.snapshot(a,b)},a)}catch(c){console.warn("[Pi Desk][TaskDetailPool] 替换详情来源失败",{taskId:a,errorName:c instanceof Error?c.name:"UnknownError"}),o(b.listeners,{type:"unavailable"},a),this.disposeShared(a,b)}}}class v extends Error{constructor(a){super(`Task detail was not found: ${a}`),this.name="L4PiTaskDetailNotFoundError"}}class w extends Error{constructor(a){super(`Task does not provide conversation detail: ${a}`),this.name="L4PiTaskDetailUnsupportedError"}}class x extends Error{constructor(a){super(`Task conversation message was not found: ${a}`),this.name="L4PiTaskMessageNotFoundError"}}d()}catch(a){d(a)}})},33448:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Wo:()=>u,er:()=>v,gb:()=>s,ls:()=>r,vC:()=>w,wz:()=>t});var e=c(73024),f=c(76760),g=c(75430),h=c(8438),i=c(6676),j=c(94074),k=c(60161),l=c(37787),m=c(7832),n=c(55881),o=c(27177),p=a([g,h,i,l,o]);[g,h,i,l,o]=p.then?(await p)():p;class u extends Error{constructor(a){super(a),this.name="L4PiSessionBranchBlockedError"}}class v extends Error{constructor(){super("Pi session has no durable entry to clone"),this.name="L4PiSessionCloneEmptyError"}}function q(){return globalThis.__piDeskPiWorkSessionRuntimes||(globalThis.__piDeskPiWorkSessionRuntimes=new Map),globalThis.__piDeskPiWorkSessionRuntimes}class w{constructor(a,b){this.sessionManager=a,this.branchIndex=b,this.resources=new o.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,h.O)().subscribe(()=>{if(null===this.capabilityModeValue||this.disposed)return;let a=(0,h.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,m.l)(b);return(0,l.Ko)(a),w.fromManager(g.SessionManager.open(c,b.getSessionDir()))}static async open(a,b){let c=q().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,l.vg)(a,b);if(!d)throw Error(`Pi session ${b} was not found in ${a}`);let e=w.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,k.xf)(this.sessionManager)}async readSessionTree(){this.assertActive();let a=this.sessionManager.getEntries().some(a=>"model_change"===a.type)?await g.ModelRuntime.create():void 0;return(0,n.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,n.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,k.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()}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){return this.assertActive(),this.chatWorker.send(a)}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 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,h.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(()=>{q().get(this.sessionId)===this&&q().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){this.assertActive(),this.assertBranchable(),this.syncBranchIndex();let b=(0,n.eD)(this.sessionManager,a);if(!b.changed)return b;let c=this.sessionManager.getLeafId(),d=this.pendingBranchAppend;this.pendingBranchAppend=null;let e=!1;try{return(e=await this.chatWorker.navigateTree(b.selectedEntryId))?b:{...b,changed:!1,targetLeafEntryId:this.sessionManager.getLeafId(),editorText:null}}finally{this.syncBranchIndex();let a=this.sessionManager.getLeafId();e||a!==c?(this.pendingBranchAppend=this.branchIndex.predictAppend(a),this.branchIdValue=this.pendingBranchAppend.branchId):this.pendingBranchAppend=d}}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 n.Ns("");let e=(0,n.u3)(this.sessionManager,a.entryId);b=e.selectedEntryId,c=e.targetLeafEntryId,d=e.editorText}else{if(!(b=a.entryId??this.sessionManager.getLeafId()??""))throw new v;if(!this.sessionManager.getEntry(b))throw new n.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,m.l)(f),(0,l.Ko)(this.cwd);let j=w.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 u(a instanceof Error?a.message:"当前 Pi 会话不能切换分支")}}createChatWorker(){return new i.EG(this.cwd,this.sessionManager,a=>this.confirmAppendedEntry(a),{mode:()=>this.capabilityModeValue,rules:()=>null===this.capabilityModeValue?void 0:(0,h.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=q().get(a.getSessionId());if(b)return b.assertActive(),b;let c=new w(a,new j.u(a.getEntries()));return q().set(c.sessionId,c),c}assertActive(){if(this.disposed)throw Error(`Pi session runtime has been disposed: ${this.sessionId}`)}}function r(a){let b=q().get(a);if(!b)throw Error(`Pi session runtime is not initialized: ${a}`);return b}async function s(a){await q().get(a)?.dispose()}async function t(){await Promise.all([...q().values()].map(a=>a.dispose()))}d()}catch(a){d(a)}})},35350:(a,b,c)=>{c.d(b,{s:()=>i});var d=c(77598),e=c(60161);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()))}}}},37787:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Ko:()=>q,vg:()=>p,xt:()=>r});var e=c(17691),f=c(77598),g=c(73024),h=c(76760),i=c(36153),j=c(64791),k=c(78180),l=c(18200),m=a([e,j,k,l]);[e,j,k,l]=m.then?(await m)():m;let s=i.Ik({cwd:i.Yj().trim().min(1),sessionCount:i.ai().int().nonnegative(),updatedAt:i.ai().int().nonnegative()}).strict(),t=i.Ik({directories:i.YO(s)}).strict();function n(){return(0,h.join)((0,e.M)(),"pi-directories.json")}function o(a){return(0,h.resolve)(a)}async function p(a,b){return(0,l.p)(o(a),b,(0,k.Ph)(a,b))}function q(a){let b=function(){if(!globalThis.__piDeskPiSessionCatalogState){let a=function(){let a=n();if(!(0,g.existsSync)(a))return null;try{return t.parse(JSON.parse((0,g.readFileSync)(a,"utf8"))).directories}catch(b){return console.warn("[Pi Desk][PiSessionCatalog] 项目目录持久缓存无效",{path:a,errorName:b instanceof Error?b.name:"UnknownError"}),null}}();globalThis.__piDeskPiSessionCatalogState={directorySummaryCache:null,directorySummaryValue:a,directorySummaryNeedsRefresh:null!==a}}return globalThis.__piDeskPiSessionCatalogState}();if(a||(b.directorySummaryNeedsRefresh=!0),a&&b.directorySummaryValue){let d=o(a),e=b.directorySummaryValue.find(a=>(0,j.sC)(a.cwd)===(0,j.sC)(d));e?(e.sessionCount+=1,e.updatedAt=Math.max(e.updatedAt,Date.now())):b.directorySummaryValue=[...b.directorySummaryValue,{cwd:d,sessionCount:1,updatedAt:Date.now()}].sort((a,b)=>b.updatedAt-a.updatedAt);var c=b.directorySummaryValue;let i=n(),k=`${i}.${process.pid}.${(0,f.randomUUID)()}.tmp`;try{(0,g.mkdirSync)((0,h.dirname)(i),{recursive:!0}),(0,g.writeFileSync)(k,`${JSON.stringify({directories:c},null,2)}
25
- `,"utf8"),(0,g.renameSync)(k,i)}catch(a){console.warn("[Pi Desk][PiSessionCatalog] 写入项目目录持久缓存失败",{path:i,errorName:a instanceof Error?a.name:"UnknownError"})}finally{(0,g.existsSync)(k)&&(0,g.unlinkSync)(k)}}(0,k.xt)(a)}function r(a){(0,k.xt)(a)}d()}catch(a){d(a)}})},38617:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{I:()=>j});var e=c(73024),f=c(76760),g=c(47757),h=c(75430),i=a([g,h]);[g,h]=i.then?(await i)():i;class k{constructor(a,b,c,d){this.cwd=a,this.agentDir=b,this.settings=c,this.createHostExtension=d,this.extensions={extensions:[],errors:[],runtime:(0,h.createExtensionRuntime)()},this.agentsFiles={agentsFiles:[]}}getExtensions(){return this.extensions}getSkills(){return{skills:(0,g.readL4PiDeskSkills)(),diagnostics:[]}}getPrompts(){return{prompts:[],diagnostics:[]}}getThemes(){return{themes:[],diagnostics:[]}}getAgentsFiles(){return this.agentsFiles}getSystemPrompt(){return this.systemPrompt?.content}getSystemPromptSource(){return this.systemPrompt?{path:this.systemPrompt.path}:void 0}getAppendSystemPrompt(){return this.appendPrompt?[this.appendPrompt.content]:[]}getAppendSystemPromptSources(){return this.appendPrompt?[{path:this.appendPrompt.path}]:[]}extendResources(){}async reload(){await this.settings.reload(),this.extensions={extensions:[this.createHostExtension()],errors:[],runtime:(0,h.createExtensionRuntime)()},this.agentsFiles={agentsFiles:(0,h.loadProjectContextFiles)({cwd:this.cwd,agentDir:this.agentDir})},this.systemPrompt=this.readPrompt("SYSTEM.md"),this.appendPrompt=this.readPrompt("APPEND_SYSTEM.md")}readPrompt(a){let b=[...this.settings.isProjectTrusted()?[(0,f.join)(this.cwd,h.CONFIG_DIR_NAME,a)]:[],(0,f.join)(this.agentDir,a)].find(a=>(0,e.existsSync)(a));return b?{path:b,content:(0,e.readFileSync)(b,"utf8")}:void 0}}async function j(a){let b=(0,h.getAgentDir)(),c=h.SettingsManager.create(a.cwd,b),d=await h.ModelRuntime.create({authPath:(0,f.join)(b,"auth.json"),modelsPath:(0,f.join)(b,"models.json")}),e=new k(a.cwd,b,c,a.createHostExtension);return await e.reload(),await d.refresh({allowNetwork:!1}),{cwd:a.cwd,agentDir:b,settingsManager:c,modelRuntime:d,resourceLoader:e,diagnostics:c.drainErrors().map(({error:a})=>({type:"error",message:a.message}))}}d()}catch(a){d(a)}})},40104:(a,b,c)=>{c.d(b,{bV:()=>J,Ak:()=>I});var d=c(51455),e=c(76760);c(27519);var f=c(76019),g=c(88134);class h extends Error{constructor(a,b,c){super(b),this.kind=a,this.localizedMessage=c,this.name="L4WorkSessionGitError"}}var i=c(11819),j=c(31421);let k={GIT_OPTIONAL_LOCKS:"0",GIT_NO_LAZY_FETCH:"1",GIT_TERMINAL_PROMPT:"0"};function l(a,b,c={}){return new Promise(d=>{(0,j.execFile)("git",["-C",a,...b],{encoding:"utf8",timeout:c.timeout??15e3,maxBuffer:0x4000000,windowsHide:!0,env:{...process.env,LC_ALL:"C",...!1===c.readOnly?{}:k}},(a,b,c)=>{d({code:"number"==typeof a?.code?a.code:a?null:0,stdout:String(b??""),stderr:String(c||(a instanceof Error?a.message:""))})})})}let m=new Set([".git","node_modules",".next","dist","build","coverage",".turbo"]),n=new Map,o=new Map,p=new Map;function q(a,b){return(0,e.relative)(a,b).split(e.sep).join("/")}function r(a){let b=a.trim().replaceAll(/\s+/g," ");return b.length>1600?`${b.slice(0,1597)}...`:b}function s(a,b){let c=r(b.stderr)||`Git 退出码 ${String(b.code)}`;return`${a}失败:${c}`}async function t(a,b,c){let d=Array(a.length),e=0;async function f(){for(;e<a.length;){let b=e;e+=1,d[b]=await c(a[b])}}return await Promise.all(Array.from({length:Math.min(b,a.length)},()=>f())),d}async function u(a){try{let b=await (0,d.realpath)(a);if(!(await (0,d.stat)(b)).isDirectory())throw new h("project-not-found","项目目录不存在");return b}catch(a){if(a instanceof h)throw a;throw new h("project-not-found","项目目录不存在")}}async function v(a){try{let b=await (0,d.stat)((0,e.join)(a,".git"));return b.isDirectory()||b.isFile()}catch{return!1}}async function w(a){let b;try{b=await (0,d.readdir)(a,{withFileTypes:!0})}catch{throw new h("read-failed","无法读取项目目录")}let c=[a,...b.filter(a=>a.isDirectory()&&!m.has(a.name)).map(b=>(0,e.resolve)(a,b.name))],f=(await t(c,32,async a=>await v(a)?a:null)).filter(a=>null!==a);if(f.length>i.y2)throw new h("scan-limit","项目中的 Git 仓库数量超过 100 个");return f}async function x(a,b){let c=await l(b,["rev-parse","--show-toplevel"]);if(0!==c.code||!c.stdout.trim()){let c=await (0,d.realpath)(b);return(0,g.C)(a,c)?{absoluteRoot:c,protocolRoot:q(a,c)}:null}try{let e=await (0,d.realpath)(c.stdout.trim());if(!(0,g.C)(a,e))return null;let f=await (0,d.realpath)(b);if((0,g.b)(f)!==(0,g.b)(e))return null;return{absoluteRoot:e,protocolRoot:q(a,e)}}catch{return null}}async function y(a){let b=await u(a),c=(0,g.b)(b),d=Date.now(),e=n.get(c);if(e&&e.expiresAt>d)return e.repositories;let f=o.get(c);if(f)return f;let h=(async()=>{let a=await w(b),e=await t(a,4,a=>x(b,a)),f=new Map;for(let a of e)a&&f.set((0,g.b)(a.absoluteRoot),a);let h=[...f.values()].sort((a,b)=>""===a.protocolRoot?-1:""===b.protocolRoot?1:a.protocolRoot.localeCompare(b.protocolRoot,void 0,{numeric:!0,sensitivity:"base"}));for(let[a,b]of n)b.expiresAt<=d&&n.delete(a);for(;n.size>=20;){let a=n.keys().next().value;if(!a)break;n.delete(a)}return n.set(c,{repositories:h,expiresAt:d+3e4}),h})();o.set(c,h);try{return await h}finally{o.get(c)===h&&o.delete(c)}}function z(a,b){let c=[],d=0;for(let e=0;e<b;e+=1){let b=a.indexOf(" ",d);if(b<0)return null;c.push(a.slice(d,b)),d=b+1}let e=a.slice(d);return e?{fields:c,path:e}:null}function A(a){switch(a){case".":case" ":return null;case"A":case"C":return"added";case"M":case"T":return"modified";case"D":return"deleted";case"R":return"renamed";case"U":return"unmerged";case"?":return"untracked";default:throw new h("read-failed",`无法识别 Git 文件状态:${a}`)}}function B(a,b,c){if(2!==b.length)throw new h("read-failed",`无法识别 Git XY 状态:${b}`);return{path:a,oldPath:c,indexStatus:A(b[0]),worktreeStatus:A(b[1])}}async function C(a,b){let c=await l(a.absoluteRoot,["status","--porcelain=v2","-z","--branch","--renames","--untracked-files=all"]);if(0!==c.code){let a=r(c.stderr)||`Git 退出码 ${String(c.code)}`;throw new h("read-failed",s("读取 Git 状态",c),(0,f.J8)(`读取 Git 状态失败:${a}`,`Could not read Git status: ${a}`))}let d=function(a){let b=a.split("\0"),c=null,d=null,e=[];for(let a=0;a<b.length;a+=1){let f=b[a];if(f){if(f.startsWith("# branch.head ")){let a=f.slice(14);c="(detached)"===a?null:a;continue}if(f.startsWith("# branch.oid ")){let a=f.slice(13);d="(initial)"===a?null:a;continue}if(!f.startsWith("# ")){if(f.startsWith("? ")){e.push({path:f.slice(2),oldPath:null,indexStatus:null,worktreeStatus:"untracked"});continue}if(!f.startsWith("! ")){if(f.startsWith("1 ")){let a=z(f,8);if(!a)throw new h("read-failed","Git 状态记录格式无效");e.push(B(a.path,a.fields[1],null));continue}if(f.startsWith("2 ")){let c=z(f,9),d=b[a+1];if(!c||!d)throw new h("read-failed","Git 重命名状态记录格式无效");a+=1,e.push(B(c.path,c.fields[1],d));continue}if(f.startsWith("u ")){let a=z(f,10);if(!a)throw new h("read-failed","Git 冲突状态记录格式无效");e.push({path:a.path,oldPath:null,indexStatus:"unmerged",worktreeStatus:"unmerged"});continue}throw new h("read-failed","Git 返回了不支持的状态记录")}}}}return{head:c?{type:"branch",name:c}:d&&/^[0-9a-f]{40,64}$/.test(d)?{type:"detached",commit:d}:{type:"branch",name:"HEAD"},changes:e.sort((a,b)=>a.path.localeCompare(b.path))}}(c.stdout),e=b.filter(b=>b.absoluteRoot!==a.absoluteRoot&&(0,g.C)(a.absoluteRoot,b.absoluteRoot)).map(b=>q(a.absoluteRoot,b.absoluteRoot)).filter(Boolean),j=d.changes.filter(a=>{var b;return b=a.path,!e.some(a=>b===a||b.startsWith(`${a}/`))});if(j.length>i.vZ)throw new h("scan-limit","仓库变更文件超过 50000 个",(0,f.J8)("仓库变更文件超过 50000 个","Repository changes exceed 50,000 files"));return{root:a.protocolRoot,state:"ready",head:d.head,changes:j}}async function D(a,b){let c,f=await u(a);if(b.includes("/"))throw new h("not-repository","只支持项目根目录及其直接子目录中的 Git 仓库");let i=b?(0,e.resolve)(f,...b.split("/")):f;if(!(0,g.C)(f,i))throw new h("outside-project","Git 仓库不在当前项目目录内");try{c=await (0,d.realpath)(i)}catch{throw new h("not-repository","Git 仓库不存在")}if(!(0,g.C)(f,c))throw new h("outside-project","Git 仓库不在当前项目目录内");let j=await l(c,["rev-parse","--show-toplevel"]);if(0!==j.code||!j.stdout.trim())throw new h("not-repository","目标目录不是 Git 仓库");try{let a=await (0,d.realpath)(j.stdout.trim());if((0,g.b)(a)!==(0,g.b)(c))throw new h("not-repository","目标目录不是 Git 仓库根目录")}catch(a){if(a instanceof h)throw a;throw new h("not-repository","Git 仓库根目录无效")}return{absoluteRoot:c,protocolRoot:q(f,c)}}async function E(a,b){let c="local"===b.type?`refs/heads/${b.name}`:`refs/remotes/${b.name}`;if(0!==(await l(a,["show-ref","--verify","--quiet",c])).code)throw new h("invalid-ref",`${"local"===b.type?"本地":"远程"}分支不存在:${b.name}`);return b.name}async function F(a,b){if(0!==(await l(a,["check-ref-format","--branch",b])).code)throw new h("invalid-ref",`分支名称无效:${b}`);if(0===(await l(a,["show-ref","--verify","--quiet",`refs/heads/${b}`])).code)throw new h("invalid-ref",`本地分支已经存在:${b}`)}async function G(a,b){let c=(0,g.b)(a),d=p.get(c)??Promise.resolve(),e=()=>void 0,f=new Promise(a=>{e=a}),h=d.catch(()=>void 0).then(()=>f);p.set(c,h),await d.catch(()=>void 0);try{return await b()}finally{e(),p.get(c)===h&&p.delete(c)}}async function H(a,b){return C(b,await y(a))}async function I(a,b,c){let d=await D(a,b);return G(d.absoluteRoot,async()=>{let b=await E(d.absoluteRoot,c),e="local"===c.type?["switch",b]:["switch","--track",b],f=await l(d.absoluteRoot,e,{timeout:12e4,readOnly:!1});if(0!==f.code)throw new h("operation-failed",s("切换 Git 分支",f));return H(a,d)})}async function J(a,b,c,d){let e=await D(a,b);return G(e.absoluteRoot,async()=>{await F(e.absoluteRoot,c);let b=d?await E(e.absoluteRoot,d):null,f=await l(e.absoluteRoot,b?["switch","-c",c,b]:["switch","-c",c],{timeout:12e4,readOnly:!1});if(0!==f.code)throw new h("operation-failed",s("新建 Git 分支",f));return H(a,e)})}},41743:(a,b,c)=>{c.d(b,{AA:()=>p,C3:()=>j,ER:()=>m,Kx:()=>i,MT:()=>l,MY:()=>q,TO:()=>n,_A:()=>k,eW:()=>g,ik:()=>h,jw:()=>o,kg:()=>r});var d=c(36153),e=c(78143),f=c(75106);let g=d.Yj().trim().min(1),h=e.m4,i=e.$E,j=e.Rv,k=d.Yj().trim().min(1),l=d.ai().int().nonnegative(),m=d.Ik({workId:g,cwd:h,sessionId:i}).strict(),n=d.YO(m),o=d.k5(["main_running","background_running","completed","idle"]),p=d.Ik({user:d.ai().int().nonnegative(),total:d.ai().int().nonnegative()}).strict().refine(a=>a.user<=a.total,{message:"user message count cannot exceed total message count"}),q=m.extend({branchId:k,projectName:d.Yj().trim().min(1),sessionTitle:d.Yj().trim().min(1).nullable(),status:o,messageCounts:p,lastMessageUpdatedAt:f.k.nullable()}).strict(),r=d.Ik({workSessions:d.YO(q),pinnedCount:l}).strict().refine(a=>a.pinnedCount<=a.workSessions.length,{message:"pinnedCount cannot exceed work session count",path:["pinnedCount"]});d.Ik({cwd:h,sessionId:i.optional()}).strict(),d.Ik({workSession:q}).strict(),d.Ik({workId:g}).strict(),d.Ik({workIds:d.YO(g),pinnedCount:l}).strict().superRefine((a,b)=>{new Set(a.workIds).size!==a.workIds.length&&b.addIssue({code:"custom",message:"workIds cannot contain duplicates",path:["workIds"]}),a.pinnedCount>a.workIds.length&&b.addIssue({code:"custom",message:"pinnedCount cannot exceed workIds length",path:["pinnedCount"]})}),d.KC([d.Ik({workId:g,cwd:h,sessionId:i}).strict(),d.Ik({workId:g}).strict()])},42035:(a,b,c)=>{c.d(b,{LO:()=>d.L,Nb:()=>e.Nb,O0:()=>e.O0,Sl:()=>e.Sl,k0:()=>e.k0}),c(63603),c(59214);var d=c(48180),e=c(80159)},42118:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{mH:()=>i,tE:()=>k,uS:()=>j});var e=c(51455),f=c(75430),g=c(60161),h=a([f]);async function i(a){let b=await (0,e.readFile)(a,"utf8"),c=(0,f.parseSessionEntries)(b),d=c[0];if(!d||"session"!==d.type||!d.id||!d.cwd)throw Error(`Pi session file has an invalid header: ${a}`);let h=c.slice(1).filter(a=>"session"!==a.type),i=function(a){let b=a.at(-1);if(!b)return[];let c=new Map(a.map(a=>[a.id,a])),d=[],e=new Set,f=b;for(;f;){if(e.has(f.id))throw Error(`Pi session parent cycle detected: ${f.id}`);e.add(f.id),d.push(f),f=f.parentId?c.get(f.parentId):void 0}return d.reverse()}(h);return{header:d,branch:i,entries:(0,g.xm)(i),truncated:!1}}async function j(a,b){let c=await i(a),d=c.branch.findIndex(a=>a.id===b);if(d<0)throw Error(`Pi session entry is not on the current branch: ${b}`);let e=(0,g.xm)(c.branch.slice(0,d+1)).at(-1);if(!e||e.entryId!==b)throw Error(`Pi session entry is not a visible message: ${b}`);return{snapshot:c,entry:c.branch[d],projected:e}}async function k(a,b,c){if(!Number.isSafeInteger(c)||c<0)throw Error("图片位置无效");let{entry:d}=await j(a,b);if("message"!==d.type||"user"!==d.message.role&&"toolResult"!==d.message.role)throw Error(`Pi session entry has no message images: ${b}`);let e=(0,g.Wl)(d.message.content,c);if(!e)throw Error(`Pi message image was not found: ${b}/${c}`);return e}f=(h.then?(await h)():h)[0],d()}catch(a){d(a)}})},43520:(a,b,c)=>{c.d(b,{L6:()=>e,k_:()=>f});var d=c(87048);let e={extensionMode:"normal",presentationMode:"normal",initializationError:null,queues:{steering:[],followUp:[]},model:null,capabilityMode:null,contextUsage:null,plugins:{}};function f(a,b){if("session_sync"===b.type){if("full"===b.mode)return{...(0,d.zR)(a,b.messages,b.temporaryMessages),runtime:b.runtime};let c=a.messages.at(-1);if(!c||c.location.index!==b.baseCursor.index||c.location.entryId!==b.baseCursor.entryId)throw Error("Incremental chat sync does not match the current durable cursor");let e=new Set(a.messages.map(a=>a.location.entryId));for(let a of b.messages){if(e.has(a.location.entryId))throw Error(`Incremental chat sync contains a duplicate entryId: ${a.location.entryId}`);e.add(a.location.entryId)}return{messages:[...a.messages,...b.messages],temporaryMessages:b.temporaryMessages,runtime:b.runtime}}return"runtime_update"===b.type?{...a,runtime:b.runtime}:{...(0,d.kn)(a,b),runtime:a.runtime}}Object.freeze({messages:[],temporaryMessages:[],runtime:e})},44164:(a,b,c)=>{c.d(b,{H:()=>g});var d=c(75278);function e(a,b){return JSON.stringify(a)===JSON.stringify(b)}function f(a,b,c,d,f){for(let g of new Set([...Object.keys(b),...Object.keys(c)])){let h=b[g],i=Object.hasOwn(c,g),j=i?c[g]:null;if(e(h,j))continue;let k=i?function(a,b){if("string"==typeof a&&"string"==typeof b&&b.startsWith(a))return b.slice(a.length)||null;if(Array.isArray(a)&&Array.isArray(b)&&a.length<=b.length&&a.every((a,c)=>e(a,b[c]))){let c=b.slice(a.length);return c.length>0?c:null}return null}(h,j):null;null!==k?f[`${a}.${g.replace(/\\/g,"\\\\").replace(/\./g,"\\.")}`]=k:d[g]=j}}function g(a,b){var c,e;let g;if(a.fixed.type!==b.fixed.type)throw Error(`Chat message type changed: ${a.fixed.type}/${b.fixed.type}`);let h=(g={},a.fixed.viewKey!==b.fixed.viewKey&&(g.viewKey=b.fixed.viewKey),"status"in a.fixed&&"status"in b.fixed&&a.fixed.status!==b.fixed.status&&(g.status=b.fixed.status),a.fixed.hasDetail!==b.fixed.hasDetail&&(g.hasDetail=b.fixed.hasDetail),"usage"in a.fixed&&"usage"in b.fixed&&(c=a.fixed.usage)!==(e=b.fixed.usage)&&(null===c||null===e||c.inputTokens!==e.inputTokens||c.outputTokens!==e.outputTokens||c.cacheReadTokens!==e.cacheReadTokens||c.costUsd!==e.costUsd)&&(g.usage=b.fixed.usage),Object.keys(g).length>0?g:void 0),i={},j={},k={};f("summary",a.summary,b.summary,i,k),b.fixed.hasDetail&&f("detail",a.detail??{},b.detail??{},j,k);let l=Object.keys(i).length>0,m=Object.keys(j).length>0,n=Object.keys(k).length>0;return h||l||m||n?d.ef.parse({type:"message_update",location:a.location,...h?{fixed:h}:{},...l?{summary:i}:{},...m?{detail:j}:{},...n?{increments:k}:{}}):null}},44937:(a,b,c)=>{c.d(b,{FF:()=>h,LK:()=>i});var d=c(36153),e=c(72497),f=c(62695);let g=d.Ik({name:d.Yj().trim().min(1),description:d.Yj(),parameters:e.Dz}).strict(),h=d.Ik({source:f.Pi}).strict(),i=d.Ik({systemPrompt:d.Yj(),tools:d.YO(g)}).strict()},45166:(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}},45870:(a,b,c)=>{c.d(b,{H:()=>g,k:()=>h});var d=c(77598),e=c(57975),f=c(88277);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}}},47757:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.r(b),c.d(b,{createL4PiDeskTool:()=>s,disposeL4PiDeskCommands:()=>p,executeL4PiDeskCommand:()=>r,initializeL4PiDeskCommands:()=>o,readL4PiDeskSkills:()=>q});var e=c(51455),f=c(76760),g=c(75430),h=c(60815),i=c(17691),j=c(16056),k=c(55574),l=c(84641),m=a([g,h,i]);function n(a){return a.replaceAll("\\","/")}async function o(a,b=!1){let c=(0,g.getAgentDir)(),d=process.cwd(),h=JSON.parse(await (0,e.readFile)((0,f.join)(d,"package.json"),"utf8"));if(!h||"object"!=typeof h||!("version"in h)||"string"!=typeof h.version)throw Error("Pi Desk package.json 缺少版本号");let{createRequire:j}=process.getBuiltinModule("module"),k=(0,f.dirname)((0,f.dirname)(j((0,f.join)(d,"package.json")).resolve("@jetcrab/pi-desk-sdk"))),m=(0,f.join)((0,i.M)(),b?"dev-skills":"skills","pi-desk");await (0,e.mkdir)((0,f.join)(m,"references"),{recursive:!0}),await Promise.all([(0,e.writeFile)((0,f.join)(m,"SKILL.md"),(0,l.i)({agentDir:n(c),sdkRoot:n(k),piDocs:n((0,g.getDocsPath)())}),"utf8"),(0,e.writeFile)((0,f.join)(m,"references","plugins.md"),(0,l._)(n(c)),"utf8")]);let p=(0,g.loadSkillsFromDir)({dir:m,source:"pidesk"}).skills.find(a=>"pi-desk"===a.name);if(!p)throw Error("Pi Desk Skill 生成后无法加载");let q={handler:a,skill:p,version:h.version,development:b,agentDir:c};globalThis.__piDeskCommandRuntime=q,console.info("[Pi Desk][Commands] 命令入口与 Skill 已准备完成",{skillPath:p.filePath})}function p(){globalThis.__piDeskCommandRuntime=void 0}function q(a=[]){let b=globalThis.__piDeskCommandRuntime?.skill;return b?[...a.filter(a=>a.name!==b.name),b]:[...a]}async function r(a,b){let c=globalThis.__piDeskCommandRuntime;if(!c)throw Error("Pi Desk 命令入口尚未准备完成");b.signal.throwIfAborted();let d=(0,k.h)(a);if("help"===d.kind)return{mode:"sync",message:d.message};if("version"===d.kind)return{mode:"sync",message:c.version};if("info"===d.kind)return{mode:"sync",message:JSON.stringify({version:c.version,environment:c.development?"development":"production",mode:(0,j.P)()?"basic":"normal",cwd:b.cwd,agentDir:c.agentDir,skillDirectory:c.skill.baseDir})};if("session"===d.kind)return b.reload();if("plugins"!==d.kind)throw Error("Pi Desk 命令无效");return c.handler(d,b)}[g,h,i]=m.then?(await m)():m;let t=h.Type.Object({args:h.Type.Array(h.Type.String({minLength:1,maxLength:2048}),{maxItems:32})},{additionalProperties:!1});function s(a){return globalThis.__piDeskCommandRuntime?(0,g.defineTool)({name:"pidesk",exposure:"model-only",label:"Pi Desk",description:"Pi Desk 命令入口。",parameters:t,async execute(b,c){let d=await a(c.args,b),e=(0,g.truncateHead)(d.message),f={mode:d.mode,message:e.truncated?`${e.content}
26
- …结果过长,已截断。`:d.message};return{content:[{type:"text",text:JSON.stringify(f)}],details:f}}}):null}d()}catch(a){d(a)}})},48180:(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}},48958:(a,b,c)=>{c.a(a,async(a,b)=>{try{var d=c(17691);c(77598),c(73024),c(76760);var e=c(75430),f=c(28802),g=a([d,e,f]);[d,e,f]=g.then?(await g)():g,b()}catch(a){b(a)}})},49240:(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(26178),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)}})},53120:(a,b,c)=>{c.d(b,{Cn:()=>l,WJ:()=>n,g$:()=>m,i0:()=>i,iW:()=>k,u1:()=>j});var d=c(36153),e=c(75106),f=c(41743);let g=d.k5(["user","assistant","tool","bash","custom_message","compaction","branch_summary","custom","model_change","thinking_level_change","session_info","label"]),h=d.Ik({entryId:f.C3,parentEntryId:f.C3.nullable(),timestampMs:e.k,kind:g,preview:d.Yj(),label:d.Yj().trim().min(1).nullable()}).strict(),i=d.Ik({workId:f.eW,sessionId:f.Kx}).strict(),j=d.Ik({sessionId:f.Kx,leafEntryId:f.C3.nullable(),nodes:d.YO(h)}).strict().superRefine((a,b)=>{let c=new Set;for(let[d,e]of a.nodes.entries())c.has(e.entryId)&&b.addIssue({code:"custom",message:"work session tree entryId values must be unique",path:["nodes",d,"entryId"]}),c.add(e.entryId);null===a.leafEntryId||c.has(a.leafEntryId)||b.addIssue({code:"custom",message:"work session tree leafEntryId must reference a node",path:["leafEntryId"]})}),k=d.Ik({workId:f.eW,sessionId:f.Kx,entryId:f.C3}).strict(),l=d.Ik({entryId:f.C3,kind:g,content:d.Yj(),truncated:d.zM()}).strict();d.k5(["tree","fork","clone"]);let m=d.gM("action",[d.Ik({action:d.eu("tree"),workId:f.eW,sessionId:f.Kx,entryId:f.C3}).strict(),d.Ik({action:d.eu("fork"),workId:f.eW,sessionId:f.Kx,entryId:f.C3}).strict(),d.Ik({action:d.eu("clone"),workId:f.eW,sessionId:f.Kx}).strict()]),n=d.Ik({workSessions:d.YO(f.MY),pinnedCount:f.MT,targetWorkId:f.eW,editorText:d.Yj().nullable()}).strict().superRefine((a,b)=>{a.pinnedCount>a.workSessions.length&&b.addIssue({code:"custom",message:"pinnedCount cannot exceed work session count",path:["pinnedCount"]}),a.workSessions.some(b=>b.workId===a.targetWorkId)||b.addIssue({code:"custom",message:"targetWorkId must reference a returned work session",path:["targetWorkId"]})})},55490:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{dM:()=>o,nJ:()=>q,yO:()=>s});var e=c(44937),f=c(62695),g=c(43520),h=c(16056),i=c(6676),j=c(5340),k=c(33448),l=a([i,j,k]);[i,j,k]=l.then?(await l)():l;class o extends Error{constructor(a){super(`Chat source is not current: ${a.workId}/${a.sessionId}/${a.branchId}`),this.name="L2ChatSourceBindingError"}}class p extends Error{constructor(a){super(`Chat message was not found: ${a}`),this.name="L2ChatMessageNotFoundError"}}class q extends Error{constructor(a){super(`Chat commands are blocked by WorkSession lifecycle: ${a}`),this.name="L2ChatLifecycleBlockedError"}}class r extends Error{constructor(a,b){super(`工作会话 ${a} 阻止插件重载:${b}`),this.workId=a,this.reason=b,this.name="L2PluginReloadBlockedError"}}function m(a){try{return structuredClone(a)}catch{let{declaration:b,...c}=a;return structuredClone(c)}}function n(a,b){return JSON.stringify(a)===JSON.stringify(b)}class s{async initialize(a){let b=a.map(a=>this.buildRecord(a));for(let a of(this.recordsByWorkId.clear(),b))this.recordsByWorkId.set(a.source.workId,a)}addWorkSession(a){this.recordsByWorkId.set(a.workId,this.buildRecord(a))}async replaceWorkSession(a,b){let c=this.recordsByWorkId.get(a.workId)?.source;await this.closeRecord(a.workId),c&&this.publish({type:"source_invalidated",source:c}),this.recordsByWorkId.set(b.workId,this.buildRecord(b)),a.sessionId!==b.sessionId&&await (0,k.gb)(a.sessionId)}async refreshWorkSession(a){let b=this.recordsByWorkId.get(a.workId)?.source;await this.closeRecord(a.workId),b&&this.publish({type:"source_invalidated",source:b}),this.recordsByWorkId.set(a.workId,this.buildRecord(a))}async removeWorkSession(a){let b=this.recordsByWorkId.get(a.workId)?.source;await this.closeRecord(a.workId),b&&this.publish({type:"source_invalidated",source:b}),await (0,k.gb)(a.sessionId)}async pauseWorkSession(a){let b=this.recordsByWorkId.get(a);b&&(b.acceptingCommands=!1,(0,k.ls)(b.source.sessionId).nativeUi.cancelAll(),await b.commandTail)}resumeWorkSession(a){let b=this.recordsByWorkId.get(a);b&&(b.acceptingCommands=!0)}async pauseForProcessRestart(){let a=[...this.recordsByWorkId.values()],b=a.map(a=>({record:a,reason:this.pluginReloadBlockReason(a)})).find(a=>null!==a.reason);if(b?.reason)throw new r(b.record.source.workId,b.reason);for(let b of a)b.acceptingCommands=!1;await Promise.all(a.map(a=>a.commandTail));let c=a.map(a=>({record:a,reason:this.pluginReloadBlockReason(a)})).find(a=>null!==a.reason);if(c?.reason){for(let b of a)b.acceptingCommands=!0;throw new r(c.record.source.workId,c.reason)}let d=!0;return()=>{if(d)for(let b of(d=!1,a))this.recordsByWorkId.get(b.source.workId)===b&&(b.acceptingCommands=!0)}}metadataFor(a){return this.recordFor(a).metadata}statusFor(a){return this.statusForRecord(this.recordFor(a))}statusForRecord(a){return a.mainRunning?"main_running":a.backgroundTaskIds.size>0?"background_running":a.completedPending?"completed":"idle"}acknowledgeCompleted(a){let b=this.recordsByWorkId.get(a);if(!b||!b.completedPending)return!1;let c=this.statusForRecord(b);return b.completedPending=!1,this.publishRecordChanged(a,b.metadata,c),!0}isCurrentSource(a){let b=f.Pi.parse(a),c=this.recordsByWorkId.get(b.workId);return void 0!==c&&this.matches(c.source,b)}refreshPluginMessages(){for(let a of this.recordsByWorkId.values())if("basic"!==a.state.runtime.presentationMode)try{this.reprojectRecord(a,a.state.runtime.presentationMode)}catch(b){console.error("[Pi Desk][WorkSessionChatRuntime] 插件消息刷新失败,保留已有聊天",{workId:a.source.workId,message:b instanceof Error?b.message:String(b)})}}setPresentation(a,b){let c=this.currentRecord(a);return this.enqueueCommand(c,async()=>{if(((0,h.P)()||"basic"===c.state.runtime.extensionMode)&&"normal"===b)throw Error("基础模式不启用插件消息展示,请先恢复插件聊天");c.state.runtime.presentationMode!==b&&this.reprojectRecord(c,b)})}reprojectRecord(a,b){let c=(0,k.ls)(a.source.sessionId).readChatSnapshot(),d=new Map(c.entries.map(a=>[a.entryId,a])),e="basic"===b,f=a.state.messages.map(b=>{let c=d.get(b.location.entryId);if(!c)throw Error(`无法重新投影消息:${b.location.entryId}`);return(0,j.Cz)(b.location.index,c.entryId,c.timestampMs,c.message,a.source,e)}),g=a.state.temporaryMessages.map(b=>{let c=a.rawTemporaryMessages.get(b.location.tempId);if(!c)throw Error(`临时消息基线尚不可重投影:${b.location.tempId}`);return(0,j.QS)(b.location.tempId,c,a.source,!1,"update",e)});a.state={messages:f,temporaryMessages:g,runtime:{...a.state.runtime,presentationMode:b}},a.forceFullSync=!0,a.sourceEventVersion+=1,this.publish({type:"source_event",source:a.source,version:a.sourceEventVersion,event:this.createSync(a.source,null).event})}prepareSource(a){let b=this.currentRecord(a);return this.enqueueCommand(b,()=>this.syncRecordRuntime(b))}async syncRecordRuntime(a){let b=a.source,c=f.wf.parse({...await (0,k.ls)(b.sessionId).readChatRuntime(),presentationMode:a.state.runtime.presentationMode});this.isCurrentSource(b)&&(n(a.state.runtime,c)||this.applySourceEvent(b,{type:"runtime_update",runtime:c}),"basic"===c.extensionMode&&"basic"!==a.state.runtime.presentationMode&&this.reprojectRecord(a,"basic"))}createSync(a,b){let c=this.currentRecord(a),d=c.source,e=c.state.messages,f=c.state.temporaryMessages,g=c.state.runtime,h=null===b?void 0:e[b.index],i=null!==b&&h?.location.entryId===b.entryId;return null===b||i||console.warn("[Pi Desk][WorkSessionChatRuntime] 客户端消息 cursor 不匹配,回退全量",{workId:d.workId,sessionId:d.sessionId,branchId:d.branchId,clientCursorIndex:b.index,clientCursorEntryId:b.entryId,serverEntryIdAtIndex:h?.location.entryId??null,serverLatestIndex:e.at(-1)?.location.index??-1}),{event:null!==b&&i&&!c.forceFullSync?{type:"session_sync",mode:"incremental",baseCursor:b,messages:e.slice(b.index+1).map(j.NA),temporaryMessages:f,runtime:g}:{type:"session_sync",mode:"full",baseCursor:null,messages:e.map(j.NA),temporaryMessages:f,runtime:g},watermark:c.sourceEventVersion}}getImage(a){let b=f.kF.parse(a),c=this.recordForSession(b.sessionId,b.branchId),d=c.state.messages.find(a=>a.location.entryId===b.entryId);if(!d||"user"!==d.fixed.type&&"tool"!==d.fixed.type)throw new p(`${b.entryId}/${b.imageIndex}`);return f.mB.parse((0,k.ls)(c.source.sessionId).readChatImage(b.entryId,b.imageIndex))}getMessageDetail(a){let b=f.VK.parse(a),c=this.recordForSession(b.sessionId,b.branchId).state.messages.find(a=>a.location.entryId===b.entryId);if(!c)throw new p(b.entryId);return f.ps.parse({index:c.location.index,entryId:c.location.entryId,detail:c.detail??null})}getModelContext(a){let b=e.FF.parse(a),c=this.currentRecord(b.source);return this.enqueueCommand(c,async()=>e.LK.parse(await (0,k.ls)(c.source.sessionId).readModelContext()))}send(a){let b=this.currentRecord(a.source);if((0,k.ls)(a.source.sessionId).nativeUi.hasPending)return Promise.reject(Error("请先处理当前插件问题,或停止当前任务"));let c=()=>b.workSession.send({mode:a.mode,text:a.text,images:a.images});return b.compactionStart?b.acceptingCommands?b.compactionStart.then(a=>{if(!b.acceptingCommands)throw new q(b.source.workId);return a?c():this.enqueueCommand(b,c)}):Promise.reject(new q(b.source.workId)):this.enqueueCommand(b,c)}interrupt(a){let b=this.currentRecord(a);return(0,k.ls)(a.sessionId).nativeUi.hasPending?b.workSession.interrupt():this.enqueueCommand(b,()=>b.workSession.interrupt())}compact(a){let b,c=this.currentRecord(a);if(c.compactionStart)return Promise.reject(Error("上下文正在压缩"));let d=new Promise(a=>{b=a});c.compactionStart=d;let e=this.enqueueCommand(c,()=>{try{let a=(0,k.ls)(c.source.sessionId).compact();return b(!0),a}catch(a){throw b(!1),a}});return e.then(()=>{b(!1),c.compactionStart===d&&(c.compactionStart=null)},()=>{b(!1),c.compactionStart===d&&(c.compactionStart=null)}),e}reload(a,b){let c=this.currentRecord(a);return(0,k.ls)(a.sessionId).nativeUi.cancelAll(),this.enqueueCommand(c,async()=>{try{await (0,k.ls)(c.source.sessionId).reload(b)}finally{this.recordsByWorkId.get(a.workId)===c&&(await this.syncRecordRuntime(c),"basic"===c.state.runtime.extensionMode&&"basic"!==c.state.runtime.presentationMode&&this.reprojectRecord(c,"basic"))}})}restoreQueuedMessages(a){let b=this.currentRecord(a);return this.enqueueCommand(b,()=>b.workSession.restoreQueuedMessages())}setModel(a){let b=this.currentRecord(a.source);return this.enqueueCommand(b,()=>b.workSession.setModel(a.model))}setCapabilityMode(a){let b=this.currentRecord(a.source);return this.enqueueCommand(b,()=>(0,k.ls)(b.source.sessionId).setCapabilityMode(a.capabilityMode))}invokePluginMethod(a){let b=this.currentRecord(a.source);return this.enqueueCommand(b,()=>(0,k.ls)(b.source.sessionId).invokePluginMethod(b.source,a.pluginName,a.method,a.input))}listNativeCommands(a){let b=this.currentRecord(a);return this.enqueueCommand(b,()=>(0,k.ls)(b.source.sessionId).listNativeCommands())}executeNativeCommand(a,b,c){let d=this.currentRecord(a);return this.enqueueCommand(d,()=>(0,k.ls)(d.source.sessionId).executeNativeCommand(b,c))}listNativeTools(a){let b=this.currentRecord(a);return this.enqueueCommand(b,()=>(0,k.ls)(b.source.sessionId).listNativeTools())}executeDirectBash(a,b){let c=this.currentRecord(a);return c.directBashActive?Promise.reject(new i.yT):(c.directBashActive=!0,this.enqueueCommand(c,()=>(0,k.ls)(c.source.sessionId).executeDirectBash(b)).finally(()=>{c.directBashActive=!1}))}abortDirectBash(a){let b=this.currentRecord(a);return(0,k.ls)(b.source.sessionId).abortDirectBash()}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}subscribeRecordChanges(a){return this.recordListeners.add(a),()=>this.recordListeners.delete(a)}subscribePluginPush(a){return this.pluginPushListeners.add(a),()=>this.pluginPushListeners.delete(a)}buildRecord(a){let b=this.sourceFor(a),c=(0,k.ls)(a.sessionId),d=c.readChatSnapshot(),e=d.entries.map((a,c)=>(0,j.Cz)(c,a.entryId,a.timestampMs,a.message,b,(0,h.P)())),i=f.oc.parse({messages:e,temporaryMessages:[],runtime:{...g.L6,extensionMode:(0,h.P)()?"basic":"normal",presentationMode:(0,h.P)()?"basic":"normal"}}),l=i.messages.find(a=>"user"===a.fixed.type),m=l?f.xE.safeParse(l.summary):null,n=m?.success&&m.data.text.trim()||null,o={workSession:a,source:b,state:i,sourceEventVersion:0,forceFullSync:(0,h.P)(),rawTemporaryMessages:new Map,metadata:{sessionTitle:d.sessionName??n,messageCounts:{user:i.messages.filter(a=>"user"===a.fixed.type).length,total:i.messages.length},lastMessageUpdatedAt:i.messages.at(-1)?.fixed.timestampMs??null},mainRunning:!1,backgroundTaskIds:new Set(c.readChatBackgroundTaskIds()),completedPending:!1,acceptingCommands:!0,directBashActive:!1,compactionStart:null,commandTail:Promise.resolve(),unsubscribeWorker:()=>void 0};return o.unsubscribeWorker=c.subscribeChat(a=>this.handleWorkerEvent(o,a)),o}handleWorkerEvent(a,b){if(this.recordsByWorkId.get(a.source.workId)!==a)return;let c=a.metadata,d=this.statusForRecord(a);switch(b.type){case"message_start":a.rawTemporaryMessages.set(b.tempId,m(b.message)),this.applySourceEvent(a.source,{type:"message_start",snapshot:(0,j.QS)(b.tempId,b.message,a.source,!1,"temporary","basic"===a.state.runtime.presentationMode)});return;case"message_update":{let c=a.state.temporaryMessages.find(a=>a.location.tempId===b.tempId);if(!c)throw Error(`Temporary chat message was not found: ${b.tempId}`);a.rawTemporaryMessages.set(b.tempId,m(b.message));let d=(0,j.Ht)(c,(0,j.QS)(b.tempId,b.message,a.source,!1,"update","basic"===a.state.runtime.presentationMode));d&&this.applySourceEvent(a.source,d);return}case"message_commit":{let c=a.state.temporaryMessages.find(a=>a.location.tempId===b.tempId);if(!c)throw Error(`Temporary chat message was not found: ${b.tempId}`);let d=(0,j.QS)(b.tempId,b.message,a.source,!1,"final","basic"===a.state.runtime.presentationMode),e=(0,j.Ht)(c,d);e&&this.applySourceEvent(a.source,e),this.replaceCanonicalTemporary(a,b.tempId,b.message),a.rawTemporaryMessages.delete(b.tempId),this.applySourceEvent(a.source,{type:"message_commit",location:{tempId:b.tempId},durable:{index:a.state.messages.length,entryId:b.entryId},fixed:{timestampMs:b.timestampMs}});return}case"message_discard":a.rawTemporaryMessages.delete(b.tempId),this.applySourceEvent(a.source,{type:"message_discard",location:{tempId:b.tempId}});return;case"plugin_push":this.publishPluginPush({pluginName:b.pluginName,target:{scope:"session",source:a.source},event:b.event,data:structuredClone(b.data)});return;case"runtime_changed":{let c=f.wf.parse({...b.runtime,presentationMode:a.state.runtime.presentationMode});n(a.state.runtime,c)||this.applySourceEvent(a.source,{type:"runtime_update",runtime:c}),"basic"===c.extensionMode&&"basic"!==a.state.runtime.presentationMode&&this.reprojectRecord(a,"basic");return}case"agent_started":if(a.mainRunning)return;a.mainRunning=!0,a.completedPending=!1,this.publishRecordChanged(a.source.workId,c,d);return;case"main_operation_cancelled":case"main_operation_finished":if(!a.mainRunning)return;a.mainRunning=!1,a.completedPending=!1,this.publishRecordChanged(a.source.workId,c,d);return;case"agent_settled":{let b=a.mainRunning||a.backgroundTaskIds.size>0;a.mainRunning=!1,b&&0===a.backgroundTaskIds.size&&(a.completedPending=!0),this.publishRecordChanged(a.source.workId,c,d);return}case"background_tasks_changed":{let e=a.mainRunning||a.backgroundTaskIds.size>0;a.backgroundTaskIds=new Set(b.taskIds),e&&!a.mainRunning&&0===a.backgroundTaskIds.size&&(a.completedPending=!0),this.publishRecordChanged(a.source.workId,c,d);return}case"session_info_changed":a.metadata={...a.metadata,sessionTitle:b.sessionTitle},this.publishRecordChanged(a.source.workId,c,d);return}}replaceCanonicalTemporary(a,b,c){let d=a.state.temporaryMessages.findIndex(a=>a.location.tempId===b);if(d<0)throw Error(`Temporary chat message was not found: ${b}`);let e=[...a.state.temporaryMessages];e[d]=(0,j.QS)(b,c,a.source,!0,"final","basic"===a.state.runtime.presentationMode),a.state={...a.state,temporaryMessages:e}}applySourceEvent(a,b){let c=this.currentRecord(a),d=c.source;if(c.state=(0,g.k_)(c.state,b),c.sourceEventVersion+=1,"message_commit"===b.type){let a=c.state.messages[b.durable.index];if(!a||a.location.entryId!==b.durable.entryId)throw Error(`Committed chat message is missing: ${b.durable.index}/${b.durable.entryId}`);let e=c.metadata;c.metadata=this.metadataFromState(c),this.publishRecordChanged(d.workId,e,this.statusForRecord(c))}this.publish({type:"source_event",source:d,version:c.sourceEventVersion,event:b})}metadataFromState(a){let b=a.state.messages.find(a=>"user"===a.fixed.type),c=b?f.xE.safeParse(b.summary):null,d=c?.success&&c.data.text.trim()||null;return{sessionTitle:a.metadata.sessionTitle??d,messageCounts:{user:a.state.messages.filter(a=>"user"===a.fixed.type).length,total:a.state.messages.length},lastMessageUpdatedAt:a.state.messages.at(-1)?.fixed.timestampMs??null}}enqueueCommand(a,b){if(!a.acceptingCommands)return Promise.reject(new q(a.source.workId));let c=a.commandTail.then(b,b);return a.commandTail=c.then(()=>void 0,()=>void 0),c}pluginReloadBlockReason(a){return(0,k.ls)(a.source.sessionId).nativeUi.hasPending?"原生插件问题正在等待回答":a.directBashActive?"Direct Bash 正在运行":a.mainRunning?"主 Agent 正在运行":a.backgroundTaskIds.size>0?"插件后台任务正在运行":(0,k.ls)(a.source.sessionId).readPluginReloadBlockReason()}async closeRecord(a){let b=this.recordsByWorkId.get(a);b&&(b.acceptingCommands=!1,(0,k.ls)(b.source.sessionId).nativeUi.cancelAll(),await b.commandTail,b.unsubscribeWorker(),b.rawTemporaryMessages.clear(),this.recordsByWorkId.delete(a))}recordFor(a){let b=this.recordsByWorkId.get(a.workId);if(!b||!this.matches(b.source,this.sourceFor(a)))throw Error(`WorkSession chat state is not initialized: ${a.workId}`);return b}sourceFor(a){return f.Pi.parse({workId:a.workId,sessionId:a.sessionId,branchId:a.branchId})}currentRecord(a){let b=f.Pi.parse(a),c=this.recordsByWorkId.get(b.workId);if(!c||!this.matches(c.source,b))throw new o(b);return c}recordForSession(a,b){let c=[...this.recordsByWorkId.values()].find(c=>c.source.sessionId===a&&c.source.branchId===b);if(c)return c;throw new o({workId:"unknown",sessionId:a,branchId:b})}matches(a,b){return a.workId===b.workId&&a.sessionId===b.sessionId&&a.branchId===b.branchId}publishPluginPush(a){for(let b of[...this.pluginPushListeners])try{b(a)}catch(b){console.error("[Pi Desk][WorkSessionChatRuntime] Plugin Push 监听器执行失败",{pluginName:a.pluginName,event:a.event,errorName:b instanceof Error?b.name:"UnknownError"})}}publish(a){for(let b of[...this.listeners])try{b(a)}catch(b){console.error("[Pi Desk][WorkSessionChatRuntime] Source 事件监听器执行失败",{eventType:a.type,workId:a.source.workId,errorName:b instanceof Error?b.name:"UnknownError"})}}publishRecordChanged(a,b,c){for(let d of[...this.recordListeners])try{d(a,b,c)}catch(b){console.error("[Pi Desk][WorkSessionChatRuntime] Record 监听器执行失败",{workId:a,errorName:b instanceof Error?b.name:"UnknownError"})}}constructor(){this.recordsByWorkId=new Map,this.listeners=new Set,this.recordListeners=new Set,this.pluginPushListeners=new Set}}d()}catch(a){d(a)}})},55574:(a,b,c)=>{c.d(b,{h:()=>g});let d=[{path:["--version"],description:"查看 Pi Desk 版本"},{path:["info"],description:"查看当前宿主环境与目录"},{path:["session","reload"],description:"等待当前会话空闲后重载 Pi 配置与已安装插件;完成后通知并唤醒本会话"},{path:["plugins","list"],description:"查看全局插件及维护状态;可按跟随渠道筛选并检查更新,不改变渠道",scope:"optional",tag:!0,checkUpdates:!0},{path:["plugins","show"],description:"查看插件详情",name:"single",scope:"required"},{path:["plugins","install"],description:"安装、更新或重新安装一个或多个插件;版本可省略,完成后向本会话汇总结果",name:"multiple",scope:"required",version:!0,tag:!0},{path:["plugins","remove"],description:"卸载一个或多个包来源;完成后向本会话汇总结果",name:"multiple",scope:"required"}];function e(a){return["pidesk",...a.path,...a.name?["multiple"===a.name?"<name...>":"<name>"]:[],..."required"===a.scope?["--scope global"]:a.scope?["[--scope global]"]:[],...a.checkUpdates?["[--check-updates]"]:[],...a.version?["[--tag <tag> | --version <exact>]"]:a.tag?["[--tag <tag>]"]:[]].join(" ")}function f(a){let b=d.filter(b=>a.every((a,c)=>b.path[c]===a));if(0===b.length)throw Error("未知命令,请使用 pidesk --help");return[...b.map(a=>`${e(a)}
25
+ `,"utf8"),(0,g.renameSync)(k,i)}catch(a){console.warn("[Pi Desk][PiSessionCatalog] 写入项目目录持久缓存失败",{path:i,errorName:a instanceof Error?a.name:"UnknownError"})}finally{(0,g.existsSync)(k)&&(0,g.unlinkSync)(k)}}(0,k.xt)(a)}function r(a){(0,k.xt)(a)}d()}catch(a){d(a)}})},38617:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{I:()=>j});var e=c(73024),f=c(76760),g=c(47757),h=c(75430),i=a([g,h]);[g,h]=i.then?(await i)():i;class k{constructor(a,b,c,d){this.cwd=a,this.agentDir=b,this.settings=c,this.createHostExtension=d,this.extensions={extensions:[],errors:[],runtime:(0,h.createExtensionRuntime)()},this.agentsFiles={agentsFiles:[]}}getExtensions(){return this.extensions}getSkills(){return{skills:[],diagnostics:[]}}getPrompts(){return{prompts:[],diagnostics:[]}}getThemes(){return{themes:[],diagnostics:[]}}getAgentsFiles(){return this.agentsFiles}getSystemPrompt(){return this.systemPrompt?.content}getSystemPromptSource(){return this.systemPrompt?{path:this.systemPrompt.path}:void 0}getAppendSystemPrompt(){return(0,g.appendL4PiDeskSystemPrompt)(this.appendPrompt?[this.appendPrompt.content]:[])}getAppendSystemPromptSources(){return this.appendPrompt?[{path:this.appendPrompt.path}]:[]}extendResources(){}async reload(){await this.settings.reload(),this.extensions={extensions:[this.createHostExtension()],errors:[],runtime:(0,h.createExtensionRuntime)()},this.agentsFiles={agentsFiles:(0,h.loadProjectContextFiles)({cwd:this.cwd,agentDir:this.agentDir})},this.systemPrompt=this.readPrompt("SYSTEM.md"),this.appendPrompt=this.readPrompt("APPEND_SYSTEM.md")}readPrompt(a){let b=[...this.settings.isProjectTrusted()?[(0,f.join)(this.cwd,h.CONFIG_DIR_NAME,a)]:[],(0,f.join)(this.agentDir,a)].find(a=>(0,e.existsSync)(a));return b?{path:b,content:(0,e.readFileSync)(b,"utf8")}:void 0}}async function j(a){let b=(0,h.getAgentDir)(),c=h.SettingsManager.create(a.cwd,b),d=await h.ModelRuntime.create({authPath:(0,f.join)(b,"auth.json"),modelsPath:(0,f.join)(b,"models.json")}),e=new k(a.cwd,b,c,a.createHostExtension);return await e.reload(),await d.refresh({allowNetwork:!1}),{cwd:a.cwd,agentDir:b,settingsManager:c,modelRuntime:d,resourceLoader:e,diagnostics:c.drainErrors().map(({error:a})=>({type:"error",message:a.message}))}}d()}catch(a){d(a)}})},40104:(a,b,c)=>{c.d(b,{bV:()=>J,Ak:()=>I});var d=c(51455),e=c(76760);c(27519);var f=c(76019),g=c(88134);class h extends Error{constructor(a,b,c){super(b),this.kind=a,this.localizedMessage=c,this.name="L4WorkSessionGitError"}}var i=c(11819),j=c(31421);let k={GIT_OPTIONAL_LOCKS:"0",GIT_NO_LAZY_FETCH:"1",GIT_TERMINAL_PROMPT:"0"};function l(a,b,c={}){return new Promise(d=>{(0,j.execFile)("git",["-C",a,...b],{encoding:"utf8",timeout:c.timeout??15e3,maxBuffer:0x4000000,windowsHide:!0,env:{...process.env,LC_ALL:"C",...!1===c.readOnly?{}:k}},(a,b,c)=>{d({code:"number"==typeof a?.code?a.code:a?null:0,stdout:String(b??""),stderr:String(c||(a instanceof Error?a.message:""))})})})}let m=new Set([".git","node_modules",".next","dist","build","coverage",".turbo"]),n=new Map,o=new Map,p=new Map;function q(a,b){return(0,e.relative)(a,b).split(e.sep).join("/")}function r(a){let b=a.trim().replaceAll(/\s+/g," ");return b.length>1600?`${b.slice(0,1597)}...`:b}function s(a,b){let c=r(b.stderr)||`Git 退出码 ${String(b.code)}`;return`${a}失败:${c}`}async function t(a,b,c){let d=Array(a.length),e=0;async function f(){for(;e<a.length;){let b=e;e+=1,d[b]=await c(a[b])}}return await Promise.all(Array.from({length:Math.min(b,a.length)},()=>f())),d}async function u(a){try{let b=await (0,d.realpath)(a);if(!(await (0,d.stat)(b)).isDirectory())throw new h("project-not-found","项目目录不存在");return b}catch(a){if(a instanceof h)throw a;throw new h("project-not-found","项目目录不存在")}}async function v(a){try{let b=await (0,d.stat)((0,e.join)(a,".git"));return b.isDirectory()||b.isFile()}catch{return!1}}async function w(a){let b;try{b=await (0,d.readdir)(a,{withFileTypes:!0})}catch{throw new h("read-failed","无法读取项目目录")}let c=[a,...b.filter(a=>a.isDirectory()&&!m.has(a.name)).map(b=>(0,e.resolve)(a,b.name))],f=(await t(c,32,async a=>await v(a)?a:null)).filter(a=>null!==a);if(f.length>i.y2)throw new h("scan-limit","项目中的 Git 仓库数量超过 100 个");return f}async function x(a,b){let c=await l(b,["rev-parse","--show-toplevel"]);if(0!==c.code||!c.stdout.trim()){let c=await (0,d.realpath)(b);return(0,g.C)(a,c)?{absoluteRoot:c,protocolRoot:q(a,c)}:null}try{let e=await (0,d.realpath)(c.stdout.trim());if(!(0,g.C)(a,e))return null;let f=await (0,d.realpath)(b);if((0,g.b)(f)!==(0,g.b)(e))return null;return{absoluteRoot:e,protocolRoot:q(a,e)}}catch{return null}}async function y(a){let b=await u(a),c=(0,g.b)(b),d=Date.now(),e=n.get(c);if(e&&e.expiresAt>d)return e.repositories;let f=o.get(c);if(f)return f;let h=(async()=>{let a=await w(b),e=await t(a,4,a=>x(b,a)),f=new Map;for(let a of e)a&&f.set((0,g.b)(a.absoluteRoot),a);let h=[...f.values()].sort((a,b)=>""===a.protocolRoot?-1:""===b.protocolRoot?1:a.protocolRoot.localeCompare(b.protocolRoot,void 0,{numeric:!0,sensitivity:"base"}));for(let[a,b]of n)b.expiresAt<=d&&n.delete(a);for(;n.size>=20;){let a=n.keys().next().value;if(!a)break;n.delete(a)}return n.set(c,{repositories:h,expiresAt:d+3e4}),h})();o.set(c,h);try{return await h}finally{o.get(c)===h&&o.delete(c)}}function z(a,b){let c=[],d=0;for(let e=0;e<b;e+=1){let b=a.indexOf(" ",d);if(b<0)return null;c.push(a.slice(d,b)),d=b+1}let e=a.slice(d);return e?{fields:c,path:e}:null}function A(a){switch(a){case".":case" ":return null;case"A":case"C":return"added";case"M":case"T":return"modified";case"D":return"deleted";case"R":return"renamed";case"U":return"unmerged";case"?":return"untracked";default:throw new h("read-failed",`无法识别 Git 文件状态:${a}`)}}function B(a,b,c){if(2!==b.length)throw new h("read-failed",`无法识别 Git XY 状态:${b}`);return{path:a,oldPath:c,indexStatus:A(b[0]),worktreeStatus:A(b[1])}}async function C(a,b){let c=await l(a.absoluteRoot,["status","--porcelain=v2","-z","--branch","--renames","--untracked-files=all"]);if(0!==c.code){let a=r(c.stderr)||`Git 退出码 ${String(c.code)}`;throw new h("read-failed",s("读取 Git 状态",c),(0,f.J8)(`读取 Git 状态失败:${a}`,`Could not read Git status: ${a}`))}let d=function(a){let b=a.split("\0"),c=null,d=null,e=[];for(let a=0;a<b.length;a+=1){let f=b[a];if(f){if(f.startsWith("# branch.head ")){let a=f.slice(14);c="(detached)"===a?null:a;continue}if(f.startsWith("# branch.oid ")){let a=f.slice(13);d="(initial)"===a?null:a;continue}if(!f.startsWith("# ")){if(f.startsWith("? ")){e.push({path:f.slice(2),oldPath:null,indexStatus:null,worktreeStatus:"untracked"});continue}if(!f.startsWith("! ")){if(f.startsWith("1 ")){let a=z(f,8);if(!a)throw new h("read-failed","Git 状态记录格式无效");e.push(B(a.path,a.fields[1],null));continue}if(f.startsWith("2 ")){let c=z(f,9),d=b[a+1];if(!c||!d)throw new h("read-failed","Git 重命名状态记录格式无效");a+=1,e.push(B(c.path,c.fields[1],d));continue}if(f.startsWith("u ")){let a=z(f,10);if(!a)throw new h("read-failed","Git 冲突状态记录格式无效");e.push({path:a.path,oldPath:null,indexStatus:"unmerged",worktreeStatus:"unmerged"});continue}throw new h("read-failed","Git 返回了不支持的状态记录")}}}}return{head:c?{type:"branch",name:c}:d&&/^[0-9a-f]{40,64}$/.test(d)?{type:"detached",commit:d}:{type:"branch",name:"HEAD"},changes:e.sort((a,b)=>a.path.localeCompare(b.path))}}(c.stdout),e=b.filter(b=>b.absoluteRoot!==a.absoluteRoot&&(0,g.C)(a.absoluteRoot,b.absoluteRoot)).map(b=>q(a.absoluteRoot,b.absoluteRoot)).filter(Boolean),j=d.changes.filter(a=>{var b;return b=a.path,!e.some(a=>b===a||b.startsWith(`${a}/`))});if(j.length>i.vZ)throw new h("scan-limit","仓库变更文件超过 50000 个",(0,f.J8)("仓库变更文件超过 50000 个","Repository changes exceed 50,000 files"));return{root:a.protocolRoot,state:"ready",head:d.head,changes:j}}async function D(a,b){let c,f=await u(a);if(b.includes("/"))throw new h("not-repository","只支持项目根目录及其直接子目录中的 Git 仓库");let i=b?(0,e.resolve)(f,...b.split("/")):f;if(!(0,g.C)(f,i))throw new h("outside-project","Git 仓库不在当前项目目录内");try{c=await (0,d.realpath)(i)}catch{throw new h("not-repository","Git 仓库不存在")}if(!(0,g.C)(f,c))throw new h("outside-project","Git 仓库不在当前项目目录内");let j=await l(c,["rev-parse","--show-toplevel"]);if(0!==j.code||!j.stdout.trim())throw new h("not-repository","目标目录不是 Git 仓库");try{let a=await (0,d.realpath)(j.stdout.trim());if((0,g.b)(a)!==(0,g.b)(c))throw new h("not-repository","目标目录不是 Git 仓库根目录")}catch(a){if(a instanceof h)throw a;throw new h("not-repository","Git 仓库根目录无效")}return{absoluteRoot:c,protocolRoot:q(f,c)}}async function E(a,b){let c="local"===b.type?`refs/heads/${b.name}`:`refs/remotes/${b.name}`;if(0!==(await l(a,["show-ref","--verify","--quiet",c])).code)throw new h("invalid-ref",`${"local"===b.type?"本地":"远程"}分支不存在:${b.name}`);return b.name}async function F(a,b){if(0!==(await l(a,["check-ref-format","--branch",b])).code)throw new h("invalid-ref",`分支名称无效:${b}`);if(0===(await l(a,["show-ref","--verify","--quiet",`refs/heads/${b}`])).code)throw new h("invalid-ref",`本地分支已经存在:${b}`)}async function G(a,b){let c=(0,g.b)(a),d=p.get(c)??Promise.resolve(),e=()=>void 0,f=new Promise(a=>{e=a}),h=d.catch(()=>void 0).then(()=>f);p.set(c,h),await d.catch(()=>void 0);try{return await b()}finally{e(),p.get(c)===h&&p.delete(c)}}async function H(a,b){return C(b,await y(a))}async function I(a,b,c){let d=await D(a,b);return G(d.absoluteRoot,async()=>{let b=await E(d.absoluteRoot,c),e="local"===c.type?["switch",b]:["switch","--track",b],f=await l(d.absoluteRoot,e,{timeout:12e4,readOnly:!1});if(0!==f.code)throw new h("operation-failed",s("切换 Git 分支",f));return H(a,d)})}async function J(a,b,c,d){let e=await D(a,b);return G(e.absoluteRoot,async()=>{await F(e.absoluteRoot,c);let b=d?await E(e.absoluteRoot,d):null,f=await l(e.absoluteRoot,b?["switch","-c",c,b]:["switch","-c",c],{timeout:12e4,readOnly:!1});if(0!==f.code)throw new h("operation-failed",s("新建 Git 分支",f));return H(a,e)})}},41743:(a,b,c)=>{c.d(b,{AA:()=>p,C3:()=>j,ER:()=>m,Kx:()=>i,MT:()=>l,MY:()=>q,TO:()=>n,_A:()=>k,eW:()=>g,ik:()=>h,jw:()=>o,kg:()=>r});var d=c(36153),e=c(78143),f=c(75106);let g=d.Yj().trim().min(1),h=e.m4,i=e.$E,j=e.Rv,k=d.Yj().trim().min(1),l=d.ai().int().nonnegative(),m=d.Ik({workId:g,cwd:h,sessionId:i}).strict(),n=d.YO(m),o=d.k5(["main_running","background_running","completed","idle"]),p=d.Ik({user:d.ai().int().nonnegative(),total:d.ai().int().nonnegative()}).strict().refine(a=>a.user<=a.total,{message:"user message count cannot exceed total message count"}),q=m.extend({branchId:k,projectName:d.Yj().trim().min(1),sessionTitle:d.Yj().trim().min(1).nullable(),status:o,messageCounts:p,lastMessageUpdatedAt:f.k.nullable()}).strict(),r=d.Ik({workSessions:d.YO(q),pinnedCount:l}).strict().refine(a=>a.pinnedCount<=a.workSessions.length,{message:"pinnedCount cannot exceed work session count",path:["pinnedCount"]});d.Ik({cwd:h,sessionId:i.optional()}).strict(),d.Ik({workSession:q}).strict(),d.Ik({workId:g}).strict(),d.Ik({workIds:d.YO(g),pinnedCount:l}).strict().superRefine((a,b)=>{new Set(a.workIds).size!==a.workIds.length&&b.addIssue({code:"custom",message:"workIds cannot contain duplicates",path:["workIds"]}),a.pinnedCount>a.workIds.length&&b.addIssue({code:"custom",message:"pinnedCount cannot exceed workIds length",path:["pinnedCount"]})}),d.KC([d.Ik({workId:g,cwd:h,sessionId:i}).strict(),d.Ik({workId:g}).strict()])},42035:(a,b,c)=>{c.d(b,{LO:()=>d.L,Nb:()=>e.Nb,O0:()=>e.O0,Sl:()=>e.Sl,k0:()=>e.k0}),c(63603),c(59214);var d=c(48180),e=c(80159)},42118:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{mH:()=>i,tE:()=>k,uS:()=>j});var e=c(51455),f=c(75430),g=c(60161),h=a([f]);async function i(a){let b=await (0,e.readFile)(a,"utf8"),c=(0,f.parseSessionEntries)(b),d=c[0];if(!d||"session"!==d.type||!d.id||!d.cwd)throw Error(`Pi session file has an invalid header: ${a}`);let h=c.slice(1).filter(a=>"session"!==a.type),i=function(a){let b=a.at(-1);if(!b)return[];let c=new Map(a.map(a=>[a.id,a])),d=[],e=new Set,f=b;for(;f;){if(e.has(f.id))throw Error(`Pi session parent cycle detected: ${f.id}`);e.add(f.id),d.push(f),f=f.parentId?c.get(f.parentId):void 0}return d.reverse()}(h);return{header:d,branch:i,entries:(0,g.xm)(i),truncated:!1}}async function j(a,b){let c=await i(a),d=c.branch.findIndex(a=>a.id===b);if(d<0)throw Error(`Pi session entry is not on the current branch: ${b}`);let e=(0,g.xm)(c.branch.slice(0,d+1)).at(-1);if(!e||e.entryId!==b)throw Error(`Pi session entry is not a visible message: ${b}`);return{snapshot:c,entry:c.branch[d],projected:e}}async function k(a,b,c){if(!Number.isSafeInteger(c)||c<0)throw Error("图片位置无效");let{entry:d}=await j(a,b);if("message"!==d.type||"user"!==d.message.role&&"toolResult"!==d.message.role)throw Error(`Pi session entry has no message images: ${b}`);let e=(0,g.Wl)(d.message.content,c);if(!e)throw Error(`Pi message image was not found: ${b}/${c}`);return e}f=(h.then?(await h)():h)[0],d()}catch(a){d(a)}})},43520:(a,b,c)=>{c.d(b,{L6:()=>e,k_:()=>f});var d=c(87048);let e={extensionMode:"normal",presentationMode:"normal",initializationError:null,queues:{steering:[],followUp:[]},model:null,capabilityMode:null,contextUsage:null,plugins:{}};function f(a,b){if("session_sync"===b.type){if("full"===b.mode)return{...(0,d.zR)(a,b.messages,b.temporaryMessages),runtime:b.runtime};let c=a.messages.at(-1);if(!c||c.location.index!==b.baseCursor.index||c.location.entryId!==b.baseCursor.entryId)throw Error("Incremental chat sync does not match the current durable cursor");let e=new Set(a.messages.map(a=>a.location.entryId));for(let a of b.messages){if(e.has(a.location.entryId))throw Error(`Incremental chat sync contains a duplicate entryId: ${a.location.entryId}`);e.add(a.location.entryId)}return{messages:[...a.messages,...b.messages],temporaryMessages:b.temporaryMessages,runtime:b.runtime}}return"runtime_update"===b.type?{...a,runtime:b.runtime}:{...(0,d.kn)(a,b),runtime:a.runtime}}Object.freeze({messages:[],temporaryMessages:[],runtime:e})},44164:(a,b,c)=>{c.d(b,{H:()=>g});var d=c(75278);function e(a,b){return JSON.stringify(a)===JSON.stringify(b)}function f(a,b,c,d,f){for(let g of new Set([...Object.keys(b),...Object.keys(c)])){let h=b[g],i=Object.hasOwn(c,g),j=i?c[g]:null;if(e(h,j))continue;let k=i?function(a,b){if("string"==typeof a&&"string"==typeof b&&b.startsWith(a))return b.slice(a.length)||null;if(Array.isArray(a)&&Array.isArray(b)&&a.length<=b.length&&a.every((a,c)=>e(a,b[c]))){let c=b.slice(a.length);return c.length>0?c:null}return null}(h,j):null;null!==k?f[`${a}.${g.replace(/\\/g,"\\\\").replace(/\./g,"\\.")}`]=k:d[g]=j}}function g(a,b){var c,e;let g;if(a.fixed.type!==b.fixed.type)throw Error(`Chat message type changed: ${a.fixed.type}/${b.fixed.type}`);let h=(g={},a.fixed.viewKey!==b.fixed.viewKey&&(g.viewKey=b.fixed.viewKey),"status"in a.fixed&&"status"in b.fixed&&a.fixed.status!==b.fixed.status&&(g.status=b.fixed.status),a.fixed.hasDetail!==b.fixed.hasDetail&&(g.hasDetail=b.fixed.hasDetail),"usage"in a.fixed&&"usage"in b.fixed&&(c=a.fixed.usage)!==(e=b.fixed.usage)&&(null===c||null===e||c.inputTokens!==e.inputTokens||c.outputTokens!==e.outputTokens||c.cacheReadTokens!==e.cacheReadTokens||c.costUsd!==e.costUsd)&&(g.usage=b.fixed.usage),Object.keys(g).length>0?g:void 0),i={},j={},k={};f("summary",a.summary,b.summary,i,k),b.fixed.hasDetail&&f("detail",a.detail??{},b.detail??{},j,k);let l=Object.keys(i).length>0,m=Object.keys(j).length>0,n=Object.keys(k).length>0;return h||l||m||n?d.ef.parse({type:"message_update",location:a.location,...h?{fixed:h}:{},...l?{summary:i}:{},...m?{detail:j}:{},...n?{increments:k}:{}}):null}},44937:(a,b,c)=>{c.d(b,{FF:()=>h,LK:()=>i});var d=c(36153),e=c(72497),f=c(62695);let g=d.Ik({name:d.Yj().trim().min(1),description:d.Yj(),parameters:e.Dz}).strict(),h=d.Ik({source:f.Pi}).strict(),i=d.Ik({systemPrompt:d.Yj(),tools:d.YO(g)}).strict()},45166:(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}},45870:(a,b,c)=>{c.d(b,{H:()=>g,k:()=>h});var d=c(77598),e=c(57975),f=c(88277);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}}},47757:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.r(b),c.d(b,{appendL4PiDeskSystemPrompt:()=>q,createL4PiDeskTool:()=>s,disposeL4PiDeskCommands:()=>p,executeL4PiDeskCommand:()=>r,initializeL4PiDeskCommands:()=>o});var e=c(51455),f=c(76760),g=c(75430),h=c(60815),i=c(17691),j=c(16056),k=c(55574),l=c(77167),m=a([g,h,i]);function n(a){return a.replaceAll("\\","/")}async function o(a,b=!1){let c=(0,g.getAgentDir)(),d=process.cwd(),h=JSON.parse(await (0,e.readFile)((0,f.join)(d,"package.json"),"utf8"));if(!h||"object"!=typeof h||!("version"in h)||"string"!=typeof h.version)throw Error("Pi Desk package.json 缺少版本号");let{createRequire:j}=process.getBuiltinModule("module"),k=(0,f.dirname)((0,f.dirname)(j((0,f.join)(d,"package.json")).resolve("@jetcrab/pi-desk-sdk"))),m=(0,f.join)(d,"docs","pi-desk");await Promise.all(["README.md","commands.md","plugins.md"].map(a=>(0,e.access)((0,f.join)(m,a)))),await (0,e.rm)((0,f.join)((0,i.M)(),b?"dev-skills":"skills","pi-desk"),{recursive:!0,force:!0});let p={handler:a,docsDirectory:m,systemPrompt:(0,l.O)({docsDirectory:n(m),sdkRoot:n(k)}),version:h.version,development:b,agentDir:c};globalThis.__piDeskCommandRuntime=p,console.info("[Pi Desk][Commands] 命令入口与系统资料导航已准备完成",{docsDirectory:m})}function p(){globalThis.__piDeskCommandRuntime=void 0}function q(a=[]){let b=globalThis.__piDeskCommandRuntime?.systemPrompt;return b?[...a,b]:[...a]}async function r(a,b){let c=globalThis.__piDeskCommandRuntime;if(!c)throw Error("Pi Desk 命令入口尚未准备完成");b.signal.throwIfAborted();let d=(0,k.h)(a);if("help"===d.kind)return{mode:"sync",message:d.message};if("version"===d.kind)return{mode:"sync",message:c.version};if("info"===d.kind)return{mode:"sync",message:JSON.stringify({version:c.version,environment:c.development?"development":"production",mode:(0,j.P)()?"basic":"normal",cwd:b.cwd,agentDir:c.agentDir,docsDirectory:c.docsDirectory})};if("session"===d.kind)return b.reload();if("plugins"!==d.kind)throw Error("Pi Desk 命令无效");return c.handler(d,b)}[g,h,i]=m.then?(await m)():m;let t=h.Type.Object({args:h.Type.Array(h.Type.String({minLength:1,maxLength:2048}),{maxItems:32})},{additionalProperties:!1});function s(a){return globalThis.__piDeskCommandRuntime?(0,g.defineTool)({name:"pidesk",exposure:"model-only",label:"Pi Desk",description:"Pi Desk 命令入口。",parameters:t,async execute(b,c){let d=await a(c.args,b),e=(0,g.truncateHead)(d.message),f={mode:d.mode,message:e.truncated?`${e.content}
26
+ …结果过长,已截断。`:d.message};return{content:[{type:"text",text:JSON.stringify(f)}],details:f}}}):null}d()}catch(a){d(a)}})},48180:(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}},48958:(a,b,c)=>{c.a(a,async(a,b)=>{try{var d=c(17691);c(77598),c(73024),c(76760);var e=c(75430),f=c(28802),g=a([d,e,f]);[d,e,f]=g.then?(await g)():g,b()}catch(a){b(a)}})},49240:(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(26178),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)}})},53120:(a,b,c)=>{c.d(b,{Cn:()=>l,WJ:()=>n,g$:()=>m,i0:()=>i,iW:()=>k,u1:()=>j});var d=c(36153),e=c(75106),f=c(41743);let g=d.k5(["user","assistant","tool","bash","custom_message","compaction","branch_summary","custom","model_change","thinking_level_change","session_info","label"]),h=d.Ik({entryId:f.C3,parentEntryId:f.C3.nullable(),timestampMs:e.k,kind:g,preview:d.Yj(),label:d.Yj().trim().min(1).nullable()}).strict(),i=d.Ik({workId:f.eW,sessionId:f.Kx}).strict(),j=d.Ik({sessionId:f.Kx,leafEntryId:f.C3.nullable(),nodes:d.YO(h)}).strict().superRefine((a,b)=>{let c=new Set;for(let[d,e]of a.nodes.entries())c.has(e.entryId)&&b.addIssue({code:"custom",message:"work session tree entryId values must be unique",path:["nodes",d,"entryId"]}),c.add(e.entryId);null===a.leafEntryId||c.has(a.leafEntryId)||b.addIssue({code:"custom",message:"work session tree leafEntryId must reference a node",path:["leafEntryId"]})}),k=d.Ik({workId:f.eW,sessionId:f.Kx,entryId:f.C3}).strict(),l=d.Ik({entryId:f.C3,kind:g,content:d.Yj(),truncated:d.zM()}).strict();d.k5(["tree","fork","clone"]);let m=d.gM("action",[d.Ik({action:d.eu("tree"),workId:f.eW,sessionId:f.Kx,entryId:f.C3}).strict(),d.Ik({action:d.eu("fork"),workId:f.eW,sessionId:f.Kx,entryId:f.C3}).strict(),d.Ik({action:d.eu("clone"),workId:f.eW,sessionId:f.Kx}).strict()]),n=d.Ik({workSessions:d.YO(f.MY),pinnedCount:f.MT,targetWorkId:f.eW,editorText:d.Yj().nullable()}).strict().superRefine((a,b)=>{a.pinnedCount>a.workSessions.length&&b.addIssue({code:"custom",message:"pinnedCount cannot exceed work session count",path:["pinnedCount"]}),a.workSessions.some(b=>b.workId===a.targetWorkId)||b.addIssue({code:"custom",message:"targetWorkId must reference a returned work session",path:["targetWorkId"]})})},55490:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{dM:()=>o,nJ:()=>q,yO:()=>s});var e=c(44937),f=c(62695),g=c(43520),h=c(16056),i=c(6676),j=c(5340),k=c(33448),l=a([i,j,k]);[i,j,k]=l.then?(await l)():l;class o extends Error{constructor(a){super(`Chat source is not current: ${a.workId}/${a.sessionId}/${a.branchId}`),this.name="L2ChatSourceBindingError"}}class p extends Error{constructor(a){super(`Chat message was not found: ${a}`),this.name="L2ChatMessageNotFoundError"}}class q extends Error{constructor(a){super(`Chat commands are blocked by WorkSession lifecycle: ${a}`),this.name="L2ChatLifecycleBlockedError"}}class r extends Error{constructor(a,b){super(`工作会话 ${a} 阻止插件重载:${b}`),this.workId=a,this.reason=b,this.name="L2PluginReloadBlockedError"}}function m(a){try{return structuredClone(a)}catch{let{declaration:b,...c}=a;return structuredClone(c)}}function n(a,b){return JSON.stringify(a)===JSON.stringify(b)}class s{async initialize(a){let b=a.map(a=>this.buildRecord(a));for(let a of(this.recordsByWorkId.clear(),b))this.recordsByWorkId.set(a.source.workId,a)}addWorkSession(a){this.recordsByWorkId.set(a.workId,this.buildRecord(a))}async replaceWorkSession(a,b){let c=this.recordsByWorkId.get(a.workId)?.source;await this.closeRecord(a.workId),c&&this.publish({type:"source_invalidated",source:c}),this.recordsByWorkId.set(b.workId,this.buildRecord(b)),a.sessionId!==b.sessionId&&await (0,k.gb)(a.sessionId)}async refreshWorkSession(a){let b=this.recordsByWorkId.get(a.workId)?.source;await this.closeRecord(a.workId),b&&this.publish({type:"source_invalidated",source:b}),this.recordsByWorkId.set(a.workId,this.buildRecord(a))}async removeWorkSession(a){let b=this.recordsByWorkId.get(a.workId)?.source;await this.closeRecord(a.workId),b&&this.publish({type:"source_invalidated",source:b}),await (0,k.gb)(a.sessionId)}async pauseWorkSession(a){let b=this.recordsByWorkId.get(a);b&&(b.acceptingCommands=!1,(0,k.ls)(b.source.sessionId).nativeUi.cancelAll(),await b.commandTail)}resumeWorkSession(a){let b=this.recordsByWorkId.get(a);b&&(b.acceptingCommands=!0)}async pauseForProcessRestart(){let a=[...this.recordsByWorkId.values()],b=a.map(a=>({record:a,reason:this.pluginReloadBlockReason(a)})).find(a=>null!==a.reason);if(b?.reason)throw new r(b.record.source.workId,b.reason);for(let b of a)b.acceptingCommands=!1;await Promise.all(a.map(a=>a.commandTail));let c=a.map(a=>({record:a,reason:this.pluginReloadBlockReason(a)})).find(a=>null!==a.reason);if(c?.reason){for(let b of a)b.acceptingCommands=!0;throw new r(c.record.source.workId,c.reason)}let d=!0;return()=>{if(d)for(let b of(d=!1,a))this.recordsByWorkId.get(b.source.workId)===b&&(b.acceptingCommands=!0)}}metadataFor(a){return this.recordFor(a).metadata}statusFor(a){return this.statusForRecord(this.recordFor(a))}statusForRecord(a){return a.mainRunning?"main_running":a.backgroundTaskIds.size>0?"background_running":a.completedPending?"completed":"idle"}acknowledgeCompleted(a){let b=this.recordsByWorkId.get(a);if(!b||!b.completedPending)return!1;let c=this.statusForRecord(b);return b.completedPending=!1,this.publishRecordChanged(a,b.metadata,c),!0}isCurrentSource(a){let b=f.Pi.parse(a),c=this.recordsByWorkId.get(b.workId);return void 0!==c&&this.matches(c.source,b)}refreshPluginMessages(){for(let a of this.recordsByWorkId.values())if("basic"!==a.state.runtime.presentationMode)try{this.reprojectRecord(a,a.state.runtime.presentationMode)}catch(b){console.error("[Pi Desk][WorkSessionChatRuntime] 插件消息刷新失败,保留已有聊天",{workId:a.source.workId,message:b instanceof Error?b.message:String(b)})}}setPresentation(a,b){let c=this.currentRecord(a);return this.enqueueCommand(c,async()=>{if(((0,h.P)()||"basic"===c.state.runtime.extensionMode)&&"normal"===b)throw Error("基础模式不启用插件消息展示,请先恢复插件聊天");c.state.runtime.presentationMode!==b&&this.reprojectRecord(c,b)})}reprojectRecord(a,b){let c=(0,k.ls)(a.source.sessionId).readChatSnapshot(),d=new Map(c.entries.map(a=>[a.entryId,a])),e="basic"===b,f=a.state.messages.map(b=>{let c=d.get(b.location.entryId);if(!c)throw Error(`无法重新投影消息:${b.location.entryId}`);return(0,j.Cz)(b.location.index,c.entryId,c.timestampMs,c.message,a.source,e)}),g=a.state.temporaryMessages.map(b=>{let c=a.rawTemporaryMessages.get(b.location.tempId);if(!c)throw Error(`临时消息基线尚不可重投影:${b.location.tempId}`);return(0,j.QS)(b.location.tempId,c,a.source,!1,"update",e)});a.state={messages:f,temporaryMessages:g,runtime:{...a.state.runtime,presentationMode:b}},a.forceFullSync=!0,a.sourceEventVersion+=1,this.publish({type:"source_event",source:a.source,version:a.sourceEventVersion,event:this.createSync(a.source,null).event})}prepareSource(a){let b=this.currentRecord(a);return this.enqueueCommand(b,()=>this.syncRecordRuntime(b))}async syncRecordRuntime(a){let b=a.source,c=f.wf.parse({...await (0,k.ls)(b.sessionId).readChatRuntime(),presentationMode:a.state.runtime.presentationMode});this.isCurrentSource(b)&&(n(a.state.runtime,c)||this.applySourceEvent(b,{type:"runtime_update",runtime:c}),"basic"===c.extensionMode&&"basic"!==a.state.runtime.presentationMode&&this.reprojectRecord(a,"basic"))}createSync(a,b){let c=this.currentRecord(a),d=c.source,e=c.state.messages,f=c.state.temporaryMessages,g=c.state.runtime,h=null===b?void 0:e[b.index],i=null!==b&&h?.location.entryId===b.entryId;return null===b||i||console.warn("[Pi Desk][WorkSessionChatRuntime] 客户端消息 cursor 不匹配,回退全量",{workId:d.workId,sessionId:d.sessionId,branchId:d.branchId,clientCursorIndex:b.index,clientCursorEntryId:b.entryId,serverEntryIdAtIndex:h?.location.entryId??null,serverLatestIndex:e.at(-1)?.location.index??-1}),{event:null!==b&&i&&!c.forceFullSync?{type:"session_sync",mode:"incremental",baseCursor:b,messages:e.slice(b.index+1).map(j.NA),temporaryMessages:f,runtime:g}:{type:"session_sync",mode:"full",baseCursor:null,messages:e.map(j.NA),temporaryMessages:f,runtime:g},watermark:c.sourceEventVersion}}getImage(a){let b=f.kF.parse(a),c=this.recordForSession(b.sessionId,b.branchId),d=c.state.messages.find(a=>a.location.entryId===b.entryId);if(!d||"user"!==d.fixed.type&&"tool"!==d.fixed.type)throw new p(`${b.entryId}/${b.imageIndex}`);return f.mB.parse((0,k.ls)(c.source.sessionId).readChatImage(b.entryId,b.imageIndex))}getMessageDetail(a){let b=f.VK.parse(a),c=this.recordForSession(b.sessionId,b.branchId).state.messages.find(a=>a.location.entryId===b.entryId);if(!c)throw new p(b.entryId);return f.ps.parse({index:c.location.index,entryId:c.location.entryId,detail:c.detail??null})}getModelContext(a){let b=e.FF.parse(a),c=this.currentRecord(b.source);return this.enqueueCommand(c,async()=>e.LK.parse(await (0,k.ls)(c.source.sessionId).readModelContext()))}send(a){let b=this.currentRecord(a.source);if((0,k.ls)(a.source.sessionId).nativeUi.hasPending)return Promise.reject(Error("请先处理当前插件问题,或停止当前任务"));let c=()=>b.workSession.send({mode:a.mode,text:a.text,images:a.images});return b.compactionStart?b.acceptingCommands?b.compactionStart.then(a=>{if(!b.acceptingCommands)throw new q(b.source.workId);return a?c():this.enqueueCommand(b,c)}):Promise.reject(new q(b.source.workId)):this.enqueueCommand(b,c)}interrupt(a){let b=this.currentRecord(a);return(0,k.ls)(a.sessionId).nativeUi.hasPending?b.workSession.interrupt():this.enqueueCommand(b,()=>b.workSession.interrupt())}compact(a){let b,c=this.currentRecord(a);if(c.compactionStart)return Promise.reject(Error("上下文正在压缩"));let d=new Promise(a=>{b=a});c.compactionStart=d;let e=this.enqueueCommand(c,()=>{try{let a=(0,k.ls)(c.source.sessionId).compact();return b(!0),a}catch(a){throw b(!1),a}});return e.then(()=>{b(!1),c.compactionStart===d&&(c.compactionStart=null)},()=>{b(!1),c.compactionStart===d&&(c.compactionStart=null)}),e}reload(a,b){let c=this.currentRecord(a);return(0,k.ls)(a.sessionId).nativeUi.cancelAll(),this.enqueueCommand(c,async()=>{try{await (0,k.ls)(c.source.sessionId).reload(b)}finally{this.recordsByWorkId.get(a.workId)===c&&(await this.syncRecordRuntime(c),"basic"===c.state.runtime.extensionMode&&"basic"!==c.state.runtime.presentationMode&&this.reprojectRecord(c,"basic"))}})}restoreQueuedMessages(a){let b=this.currentRecord(a);return this.enqueueCommand(b,()=>b.workSession.restoreQueuedMessages())}setModel(a){let b=this.currentRecord(a.source);return this.enqueueCommand(b,()=>b.workSession.setModel(a.model))}setCapabilityMode(a){let b=this.currentRecord(a.source);return this.enqueueCommand(b,()=>(0,k.ls)(b.source.sessionId).setCapabilityMode(a.capabilityMode))}invokePluginMethod(a){let b=this.currentRecord(a.source);return this.enqueueCommand(b,()=>(0,k.ls)(b.source.sessionId).invokePluginMethod(b.source,a.pluginName,a.method,a.input))}listNativeCommands(a){let b=this.currentRecord(a);return this.enqueueCommand(b,()=>(0,k.ls)(b.source.sessionId).listNativeCommands())}executeNativeCommand(a,b,c){let d=this.currentRecord(a);return this.enqueueCommand(d,()=>(0,k.ls)(d.source.sessionId).executeNativeCommand(b,c))}listNativeTools(a){let b=this.currentRecord(a);return this.enqueueCommand(b,()=>(0,k.ls)(b.source.sessionId).listNativeTools())}executeDirectBash(a,b){let c=this.currentRecord(a);return c.directBashActive?Promise.reject(new i.yT):(c.directBashActive=!0,this.enqueueCommand(c,()=>(0,k.ls)(c.source.sessionId).executeDirectBash(b)).finally(()=>{c.directBashActive=!1}))}abortDirectBash(a){let b=this.currentRecord(a);return(0,k.ls)(b.source.sessionId).abortDirectBash()}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}subscribeRecordChanges(a){return this.recordListeners.add(a),()=>this.recordListeners.delete(a)}subscribePluginPush(a){return this.pluginPushListeners.add(a),()=>this.pluginPushListeners.delete(a)}buildRecord(a){let b=this.sourceFor(a),c=(0,k.ls)(a.sessionId),d=c.readChatSnapshot(),e=d.entries.map((a,c)=>(0,j.Cz)(c,a.entryId,a.timestampMs,a.message,b,(0,h.P)())),i=f.oc.parse({messages:e,temporaryMessages:[],runtime:{...g.L6,extensionMode:(0,h.P)()?"basic":"normal",presentationMode:(0,h.P)()?"basic":"normal"}}),l=i.messages.find(a=>"user"===a.fixed.type),m=l?f.xE.safeParse(l.summary):null,n=m?.success&&m.data.text.trim()||null,o={workSession:a,source:b,state:i,sourceEventVersion:0,forceFullSync:(0,h.P)(),rawTemporaryMessages:new Map,metadata:{sessionTitle:d.sessionName??n,messageCounts:{user:i.messages.filter(a=>"user"===a.fixed.type).length,total:i.messages.length},lastMessageUpdatedAt:i.messages.at(-1)?.fixed.timestampMs??null},mainRunning:!1,backgroundTaskIds:new Set(c.readChatBackgroundTaskIds()),completedPending:!1,acceptingCommands:!0,directBashActive:!1,compactionStart:null,commandTail:Promise.resolve(),unsubscribeWorker:()=>void 0};return o.unsubscribeWorker=c.subscribeChat(a=>this.handleWorkerEvent(o,a)),o}handleWorkerEvent(a,b){if(this.recordsByWorkId.get(a.source.workId)!==a)return;let c=a.metadata,d=this.statusForRecord(a);switch(b.type){case"message_start":a.rawTemporaryMessages.set(b.tempId,m(b.message)),this.applySourceEvent(a.source,{type:"message_start",snapshot:(0,j.QS)(b.tempId,b.message,a.source,!1,"temporary","basic"===a.state.runtime.presentationMode)});return;case"message_update":{let c=a.state.temporaryMessages.find(a=>a.location.tempId===b.tempId);if(!c)throw Error(`Temporary chat message was not found: ${b.tempId}`);a.rawTemporaryMessages.set(b.tempId,m(b.message));let d=(0,j.Ht)(c,(0,j.QS)(b.tempId,b.message,a.source,!1,"update","basic"===a.state.runtime.presentationMode));d&&this.applySourceEvent(a.source,d);return}case"message_commit":{let c=a.state.temporaryMessages.find(a=>a.location.tempId===b.tempId);if(!c)throw Error(`Temporary chat message was not found: ${b.tempId}`);let d=(0,j.QS)(b.tempId,b.message,a.source,!1,"final","basic"===a.state.runtime.presentationMode),e=(0,j.Ht)(c,d);e&&this.applySourceEvent(a.source,e),this.replaceCanonicalTemporary(a,b.tempId,b.message),a.rawTemporaryMessages.delete(b.tempId),this.applySourceEvent(a.source,{type:"message_commit",location:{tempId:b.tempId},durable:{index:a.state.messages.length,entryId:b.entryId},fixed:{timestampMs:b.timestampMs}});return}case"message_discard":a.rawTemporaryMessages.delete(b.tempId),this.applySourceEvent(a.source,{type:"message_discard",location:{tempId:b.tempId}});return;case"plugin_push":this.publishPluginPush({pluginName:b.pluginName,target:{scope:"session",source:a.source},event:b.event,data:structuredClone(b.data)});return;case"runtime_changed":{let c=f.wf.parse({...b.runtime,presentationMode:a.state.runtime.presentationMode});n(a.state.runtime,c)||this.applySourceEvent(a.source,{type:"runtime_update",runtime:c}),"basic"===c.extensionMode&&"basic"!==a.state.runtime.presentationMode&&this.reprojectRecord(a,"basic");return}case"agent_started":if(a.mainRunning)return;a.mainRunning=!0,a.completedPending=!1,this.publishRecordChanged(a.source.workId,c,d);return;case"main_operation_cancelled":case"main_operation_finished":if(!a.mainRunning)return;a.mainRunning=!1,a.completedPending=!1,this.publishRecordChanged(a.source.workId,c,d);return;case"agent_settled":{let b=a.mainRunning||a.backgroundTaskIds.size>0;a.mainRunning=!1,b&&0===a.backgroundTaskIds.size&&(a.completedPending=!0),this.publishRecordChanged(a.source.workId,c,d);return}case"background_tasks_changed":{let e=a.mainRunning||a.backgroundTaskIds.size>0;a.backgroundTaskIds=new Set(b.taskIds),e&&!a.mainRunning&&0===a.backgroundTaskIds.size&&(a.completedPending=!0),this.publishRecordChanged(a.source.workId,c,d);return}case"session_info_changed":a.metadata={...a.metadata,sessionTitle:b.sessionTitle},this.publishRecordChanged(a.source.workId,c,d);return}}replaceCanonicalTemporary(a,b,c){let d=a.state.temporaryMessages.findIndex(a=>a.location.tempId===b);if(d<0)throw Error(`Temporary chat message was not found: ${b}`);let e=[...a.state.temporaryMessages];e[d]=(0,j.QS)(b,c,a.source,!0,"final","basic"===a.state.runtime.presentationMode),a.state={...a.state,temporaryMessages:e}}applySourceEvent(a,b){let c=this.currentRecord(a),d=c.source;if(c.state=(0,g.k_)(c.state,b),c.sourceEventVersion+=1,"message_commit"===b.type){let a=c.state.messages[b.durable.index];if(!a||a.location.entryId!==b.durable.entryId)throw Error(`Committed chat message is missing: ${b.durable.index}/${b.durable.entryId}`);let e=c.metadata;c.metadata=this.metadataFromState(c),this.publishRecordChanged(d.workId,e,this.statusForRecord(c))}this.publish({type:"source_event",source:d,version:c.sourceEventVersion,event:b})}metadataFromState(a){let b=a.state.messages.find(a=>"user"===a.fixed.type),c=b?f.xE.safeParse(b.summary):null,d=c?.success&&c.data.text.trim()||null;return{sessionTitle:a.metadata.sessionTitle??d,messageCounts:{user:a.state.messages.filter(a=>"user"===a.fixed.type).length,total:a.state.messages.length},lastMessageUpdatedAt:a.state.messages.at(-1)?.fixed.timestampMs??null}}enqueueCommand(a,b){if(!a.acceptingCommands)return Promise.reject(new q(a.source.workId));let c=a.commandTail.then(b,b);return a.commandTail=c.then(()=>void 0,()=>void 0),c}pluginReloadBlockReason(a){return(0,k.ls)(a.source.sessionId).nativeUi.hasPending?"原生插件问题正在等待回答":a.directBashActive?"Direct Bash 正在运行":a.mainRunning?"主 Agent 正在运行":a.backgroundTaskIds.size>0?"插件后台任务正在运行":(0,k.ls)(a.source.sessionId).readPluginReloadBlockReason()}async closeRecord(a){let b=this.recordsByWorkId.get(a);b&&(b.acceptingCommands=!1,(0,k.ls)(b.source.sessionId).nativeUi.cancelAll(),await b.commandTail,b.unsubscribeWorker(),b.rawTemporaryMessages.clear(),this.recordsByWorkId.delete(a))}recordFor(a){let b=this.recordsByWorkId.get(a.workId);if(!b||!this.matches(b.source,this.sourceFor(a)))throw Error(`WorkSession chat state is not initialized: ${a.workId}`);return b}sourceFor(a){return f.Pi.parse({workId:a.workId,sessionId:a.sessionId,branchId:a.branchId})}currentRecord(a){let b=f.Pi.parse(a),c=this.recordsByWorkId.get(b.workId);if(!c||!this.matches(c.source,b))throw new o(b);return c}recordForSession(a,b){let c=[...this.recordsByWorkId.values()].find(c=>c.source.sessionId===a&&c.source.branchId===b);if(c)return c;throw new o({workId:"unknown",sessionId:a,branchId:b})}matches(a,b){return a.workId===b.workId&&a.sessionId===b.sessionId&&a.branchId===b.branchId}publishPluginPush(a){for(let b of[...this.pluginPushListeners])try{b(a)}catch(b){console.error("[Pi Desk][WorkSessionChatRuntime] Plugin Push 监听器执行失败",{pluginName:a.pluginName,event:a.event,errorName:b instanceof Error?b.name:"UnknownError"})}}publish(a){for(let b of[...this.listeners])try{b(a)}catch(b){console.error("[Pi Desk][WorkSessionChatRuntime] Source 事件监听器执行失败",{eventType:a.type,workId:a.source.workId,errorName:b instanceof Error?b.name:"UnknownError"})}}publishRecordChanged(a,b,c){for(let d of[...this.recordListeners])try{d(a,b,c)}catch(b){console.error("[Pi Desk][WorkSessionChatRuntime] Record 监听器执行失败",{workId:a,errorName:b instanceof Error?b.name:"UnknownError"})}}constructor(){this.recordsByWorkId=new Map,this.listeners=new Set,this.recordListeners=new Set,this.pluginPushListeners=new Set}}d()}catch(a){d(a)}})},55574:(a,b,c)=>{c.d(b,{h:()=>g});let d=[{path:["--version"],description:"查看 Pi Desk 版本"},{path:["info"],description:"查看当前宿主环境与目录"},{path:["session","reload"],description:"等待当前会话空闲后重载 Pi 配置与已安装插件;完成后通知并唤醒本会话"},{path:["plugins","list"],description:"查看全局插件及维护状态;可按跟随渠道筛选并检查更新,不改变渠道",scope:"optional",tag:!0,checkUpdates:!0},{path:["plugins","show"],description:"查看插件详情",name:"single",scope:"required"},{path:["plugins","install"],description:"安装、更新或重新安装一个或多个插件;版本可省略,完成后向本会话汇总结果",name:"multiple",scope:"required",version:!0,tag:!0},{path:["plugins","reload"],description:"重新加载一个或多个已安装插件;不下载、不重启宿主,不重载已有 Pi 会话;完成后向本会话汇总结果",name:"multiple",scope:"required"},{path:["plugins","remove"],description:"卸载一个或多个包来源;完成后向本会话汇总结果",name:"multiple",scope:"required"}];function e(a){return["pidesk",...a.path,...a.name?["multiple"===a.name?"<name...>":"<name>"]:[],..."required"===a.scope?["--scope global"]:a.scope?["[--scope global]"]:[],...a.checkUpdates?["[--check-updates]"]:[],...a.version?["[--tag <tag> | --version <exact>]"]:a.tag?["[--tag <tag>]"]:[]].join(" ")}function f(a){let b=d.filter(b=>a.every((a,c)=>b.path[c]===a));if(0===b.length)throw Error("未知命令,请使用 pidesk --help");return[...b.map(a=>`${e(a)}
27
27
  ${a.description}`),"各级命令均支持 --help。当前插件管理只支持 global 范围。",..."plugins"===a[0]&&(1===a.length||"install"===a[1])?["install = install + update + reinstall。版本和渠道均可省略:新 npm 插件默认 latest,已有插件沿保存的渠道;--tag 选择跟随渠道,--version 固定完整版本号,两者互斥。","多个插件可共用同一渠道或具体版本;同版本仍重新安装。","本地扩展使用 Pi 全局 extensions 目录中的名字,加载当前代码;不接受版本、渠道或自定义路径。","异步接纳不代表生效;结果会插入本会话并唤醒模型,无需持续查询。"]:[]].join("\n\n")}function g(a){let b,c,g,h;if(a.length>32)throw Error("命令参数最多 32 项");if(0===a.length)return{kind:"help",message:f([])};let i=d.find(b=>b.path.every((b,c)=>a[c]===b));if(a.includes("--help")||a.includes("-h")||1===a.length&&["plugins","session"].includes(a[0])){let b=["plugins","session"].includes(a[0])?a[0]:null,c=i?.path??(b?[b]:[]);if(!i&&!b&&!["--help","-h"].includes(a[0]))throw Error("未知命令,请使用 pidesk --help");if(!i&&b&&a[1]&&!["--help","-h"].includes(a[1]))throw Error(`未知子命令,请使用 pidesk ${b} --help`);return{kind:"help",message:f(c)}}if(!i)throw Error("未知命令,请使用 pidesk --help");let j=[];for(let d=i.path.length;d<a.length;d+=1){let f=a[d];if("--scope"===f&&i.scope){if(void 0!==b)throw Error("--scope 不允许重复");if(!(b=a[++d])||b.startsWith("--"))throw Error("--scope 缺少范围")}else if("--version"===f&&i.version){if(void 0!==c)throw Error("--version 不允许重复");if(!(c=a[++d])||c.startsWith("--"))throw Error("--version 缺少版本号")}else if("--tag"===f&&i.tag){if(void 0!==g)throw Error("--tag 不允许重复");if(!(g=a[++d])||g.startsWith("--"))throw Error("--tag 缺少渠道标签")}else if("--check-updates"===f&&i.checkUpdates){if(void 0!==h)throw Error("--check-updates 不允许重复");h=!0}else if(i.name&&("multiple"===i.name||0===j.length)&&!f.startsWith("-"))j.push(f);else throw Error(`不支持的参数:${f}
28
28
  ${e(i)}`)}if("required"===i.scope&&void 0===b)throw Error(`必须指定 --scope global
29
29
  ${e(i)}`);if(void 0!==b&&"global"!==b)throw Error("当前插件管理只支持 global 范围,不支持项目级操作");if(i.name){if(0===j.length)throw Error(`缺少插件名字
@@ -37,79 +37,10 @@ ${k(a.usage)}`;case"model_change":return`${a.provider}/${c?.getModel(a.provider,
37
37
  当前步骤耗时:${Math.round(performance.now()-this.stageStartedAt)} 毫秒`}async initialize(a){let b=performance.now();if(this.assertActive(),"normal"===this.options.mode&&o.size>=4)throw Error("尚未结束的插件初始化或关闭任务过多,请重启服务后再加载插件");let c=new Promise((a,b)=>{this.onLifecycleError=b}),d=async()=>(this.assertActive(),a&&(this.setStage("刷新插件资源"),(0,i.N)(),this.options.resources.reset(),this.assertActive()),this.create());this.execution=d();try{let a=await this.ui.waitForOperation(Promise.race([this.execution,c]),6e4,()=>Error("Pi 会话初始化超时(60 秒);不含等待用户回答"));return this.assertActive(),this.setStage("会话已就绪"),console.info("[Pi Desk][PiSession] 会话初始化完成",{sessionId:this.sessionId,cwd:this.options.cwd,mode:this.options.mode,durationMs:Math.round(performance.now()-b)}),a}catch(d){let a=d instanceof Error?d:Error(String(d));if(!this.active)throw console.info("[Pi Desk][PiSession] 会话初始化已取消",{sessionId:this.sessionId,cwd:this.options.cwd,mode:this.options.mode,durationMs:Math.round(performance.now()-b)}),a;let c=`${a.stack??a.message}
38
38
 
39
39
  最后处理步骤:${this.describeStage()}`;throw console.error("[Pi Desk][PiSession] 会话初始化失败",{sessionId:this.sessionId,cwd:this.options.cwd,mode:this.options.mode,durationMs:Math.round(performance.now()-b),message:c}),this.dispose(),Error(c)}finally{this.onLifecycleError=null}}dispose(a=!0){if(!this.active)return;this.active=!1,this.onLifecycleError?.(Error(p)),this.ui.reset(!1),this.messages.dispose(),this.plugins.dispose(),this.capabilities.dispose();let b=this.session;this.session=null;try{b?.dispose()}catch(a){console.warn("[Pi Desk][PiSession] 释放会话失败",{sessionId:this.sessionId,message:a instanceof Error?a.message:String(a)})}finally{this.accessRevoked=!0}if(!this.execution)return;let c=b&&a?Promise.resolve().then(()=>b.extensionRunner.emit({type:"session_shutdown",reason:"quit"})):Promise.resolve(),d=Promise.allSettled([this.execution,c]);o.add(d);let e=setTimeout(()=>{console.warn("[Pi Desk][PiSession] 旧实例仍在后台清理,不阻塞基础聊天",{sessionId:this.sessionId,cwd:this.options.cwd,stage:this.describeStage()})},1500);e.unref(),d.then(()=>{clearTimeout(e),o.delete(d)})}assertActive(){if(!this.active)throw Error(p)}assertAccess(){if(this.accessRevoked)throw Error(p)}validateResources(a,b){let c=a.getExtensions().errors.map(({path:a,error:b})=>`${b}
40
- 插件入口:${a}`);for(let a of b)"error"===a.type?c.push(a.message):console.info("[Pi Desk][PiSession] 初始化诊断",{cwd:this.options.cwd,...a});if(c.length>0){for(let a of c)(0,j.pL)(this.options.cwd,a);throw a.getExtensions().runtime.invalidate(p),Error(c.join("\n"))}}async create(){this.setStage("加载 Pi 配置与插件");let a=()=>{this.ui.reset();let a=this.capabilities.createHostExtension((a,b)=>(this.assertActive(),this.options.onInput(a,b)),()=>{this.ui.reset(!1),this.plugins.reset()});a.handlers.set("session_tree",[async()=>this.options.onTree?.()]),a.handlers.set("session_before_tree",[async a=>{if(a.signal.aborted)return{cancel:!0}}]);let b=this.options.onCommand?(0,f.createL4PiDeskTool)(this.options.onCommand):null;return b&&a.tools.set(b.name,{definition:b,sourceInfo:a.sourceInfo}),a},b="basic"===this.options.mode?await (0,h.I)({cwd:this.options.cwd,createHostExtension:a}):await this.options.resources.createServices(this.options.cwd,{skillsOverride:a=>({...a,skills:(0,f.readL4PiDeskSkills)(a.skills)}),eventBus:this.capabilities.eventBus(this.plugins.eventBus),extensionsOverride:b=>{if(!this.active)throw b.runtime.invalidate(p),Error(p);let c=a(),d="<inline:pi-desk-branch-state>",e={...c,path:d,resolvedPath:d,sourceInfo:{...c.sourceInfo,path:d},handlers:new Map([["session_tree",c.handlers.get("session_tree")]]),tools:new Map};return c.handlers.delete("session_tree"),{...b,extensions:[e,...b.extensions,c]}}},a=>this.setStage(a));this.assertActive(),this.validateResources(b.resourceLoader,b.diagnostics),this.setStage("创建会话与恢复模型"),b.resourceLoader=this.capabilities.resources(b.resourceLoader);let{session:c}=await (0,e.createAgentSessionFromServices)({services:b,sessionManager:this.manager});return this.assertActive(),this.session=c,this.capabilities.attach(c),this.setStage("启动插件"),await c.bindExtensions({mode:"rpc",uiContext:this.ui.bind(c.extensionRunner.getUIContext(),()=>this.assertActive()),onError:a=>{let b=`${a.stack??a.error}
40
+ 插件入口:${a}`);for(let a of b)"error"===a.type?c.push(a.message):console.info("[Pi Desk][PiSession] 初始化诊断",{cwd:this.options.cwd,...a});if(c.length>0){for(let a of c)(0,j.pL)(this.options.cwd,a);throw a.getExtensions().runtime.invalidate(p),Error(c.join("\n"))}}async create(){this.setStage("加载 Pi 配置与插件");let a=()=>{this.ui.reset();let a=this.capabilities.createHostExtension((a,b)=>(this.assertActive(),this.options.onInput(a,b)),()=>{this.ui.reset(!1),this.plugins.reset()});a.handlers.set("session_tree",[async()=>this.options.onTree?.()]),a.handlers.set("session_before_tree",[async a=>{if(a.signal.aborted)return{cancel:!0}}]);let b=this.options.onCommand?(0,f.createL4PiDeskTool)(this.options.onCommand):null;return b&&a.tools.set(b.name,{definition:b,sourceInfo:a.sourceInfo}),a},b="basic"===this.options.mode?await (0,h.I)({cwd:this.options.cwd,createHostExtension:a}):await this.options.resources.createServices(this.options.cwd,{appendSystemPromptOverride:f.appendL4PiDeskSystemPrompt,eventBus:this.capabilities.eventBus(this.plugins.eventBus),extensionsOverride:b=>{if(!this.active)throw b.runtime.invalidate(p),Error(p);let c=a(),d="<inline:pi-desk-branch-state>",e={...c,path:d,resolvedPath:d,sourceInfo:{...c.sourceInfo,path:d},handlers:new Map([["session_tree",c.handlers.get("session_tree")]]),tools:new Map};return c.handlers.delete("session_tree"),{...b,extensions:[e,...b.extensions,c]}}},a=>this.setStage(a));this.assertActive(),this.validateResources(b.resourceLoader,b.diagnostics),this.setStage("创建会话与恢复模型"),b.resourceLoader=this.capabilities.resources(b.resourceLoader);let{session:c}=await (0,e.createAgentSessionFromServices)({services:b,sessionManager:this.manager});return this.assertActive(),this.session=c,this.capabilities.attach(c),this.setStage("启动插件"),await c.bindExtensions({mode:"rpc",uiContext:this.ui.bind(c.extensionRunner.getUIContext(),()=>this.assertActive()),onError:a=>{let b=`${a.stack??a.error}
41
41
  插件入口:${a.extensionPath}
42
- 事件:${a.event}`;this.active&&(console.error("[Pi Desk][PiSession] 扩展处理失败",{sessionId:this.sessionId,message:b}),this.onLifecycleError?.(Error(b)),("session_tree"===a.event||"session_before_tree"===a.event)&&this.session?.extensionRunner.getUIContext().notify(`会话树扩展处理失败:${a.error}`,"error"))}}),this.assertActive(),this.messages.installExtensionRuntime(b.resourceLoader.getExtensions().runtime),this.setStage("应用会话能力"),await this.capabilities.apply(),this.assertActive(),c}}d()}catch(a){d(a)}})},78143:(a,b,c)=>{c.d(b,{$E:()=>f,Rv:()=>g,m4:()=>e});var d=c(36153);let e=d.Yj().trim().min(1),f=d.Yj().trim().min(1),g=d.Yj().trim().min(1)},78180:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Ph:()=>q,xt:()=>r});var e=c(17691),f=c(77598),g=c(73024);c(51455);var h=c(76760);c(80481);var i=c(75430),j=c(36153),k=c(18200),l=a([e,i,k]);[e,i,k]=l.then?(await l)():l;let s=j.Ik({entryId:j.Yj().min(1),timestampMs:j.ai().int().nonnegative(),text:j.Yj()}).strict(),t=j.Ik({path:j.Yj().min(1),sessionId:j.Yj().min(1),cwd:j.Yj().min(1),name:j.Yj().nullable(),createdAt:j.ai().int().nonnegative(),updatedAt:j.ai().int().nonnegative(),messageCount:j.ai().int().nonnegative(),userMessageCount:j.ai().int().nonnegative(),firstMessage:j.Yj(),userMessages:j.YO(s),assistantMessages:j.YO(s),textBytes:j.ai().int().nonnegative()}).strict(),u=j.Ik({descriptor:j.Ik({path:j.Yj().min(1),size:j.ai().int().nonnegative(),modifiedAt:j.ai().int().nonnegative()}).strict(),record:t.nullable()}).strict(),v=j.Ik({cwd:j.Yj().min(1),files:j.YO(u)}).strict();v.extend({version:j.eu(2)});let w=j.Ik({version:j.eu(1),catalogs:j.YO(v)}).strict();function m(){return(0,h.join)((0,e.M)(),"pi-session-history")}function n(a){let b=(0,f.createHash)("sha256").update(a).digest("hex");return(0,h.join)(m(),`${b}.json`)}function o(){return globalThis.__piDeskPiSessionHistoryCatalogState||(!function(){let a=(0,h.join)((0,e.M)(),"pi-session-history.json");if((0,g.existsSync)(a))try{let b=w.parse(JSON.parse((0,g.readFileSync)(a,"utf8")));for(let a of b.catalogs){let b=function(a){let b=(0,h.resolve)(a.cwd),c=new Map;for(let d of a.files){let a=null;if(d.record&&d.record.path===d.descriptor.path&&(0,h.resolve)(d.record.cwd)===b){let b=d.record.assistantMessages.filter(a=>a.text.trim()),c=d.record.assistantMessages.reduce((a,b)=>a+(b.text.trim()?0:Buffer.byteLength(b.text,"utf8")),0);a={...d.record,assistantMessages:b,textBytes:d.record.textBytes-c}}c.set(d.descriptor.path,{descriptor:d.descriptor,record:a})}let d=Array.from(c.values()).flatMap(a=>a.record?[a.record]:[]).sort((a,b)=>b.updatedAt-a.updatedAt),e=Date.now();return{cwd:b,files:c,sessions:d,textBytes:d.reduce((a,b)=>a+b.textBytes,0),dirty:!1,validatedAt:0,lastAccessedAt:e}}(a);if(!(0,g.existsSync)(n(b.cwd))&&!function(a){let b=n(a.cwd),c=`${b}.${process.pid}.${(0,f.randomUUID)()}.tmp`;try{(0,g.mkdirSync)((0,h.dirname)(b),{recursive:!0}),(0,g.writeFileSync)(c,`${JSON.stringify({version:2,cwd:a.cwd,files:Array.from(a.files.values())})}
43
- `,"utf8"),(0,g.renameSync)(c,b);let d=m(),e=(0,g.readdirSync)(d).filter(a=>/^[a-f0-9]{64}\.json$/u.test(a)).map(a=>{let b=(0,h.join)(d,a),c=(0,g.statSync)(b);return{path:b,size:c.size,modifiedAt:c.mtimeMs}}).sort((a,b)=>a.modifiedAt-b.modifiedAt),f=e.reduce((a,b)=>a+b.size,0);for(;e.length>1&&(e.length>8||f>0x4000000);){let a=e.shift();(0,g.unlinkSync)(a.path),f-=a.size}return!0}catch(a){return console.warn("[Pi Desk][PiSessionHistoryCatalog] 写入历史会话持久缓存失败",{path:b,errorName:a instanceof Error?a.name:"UnknownError"}),!1}finally{(0,g.existsSync)(c)&&(0,g.unlinkSync)(c)}}(b))return}(0,g.unlinkSync)(a),console.info("[Pi Desk][PiSessionHistoryCatalog] 已迁移历史会话缓存",{catalogCount:b.catalogs.length})}catch(b){console.warn("[Pi Desk][PiSessionHistoryCatalog] 迁移历史会话缓存失败",{path:a,errorName:b instanceof Error?b.name:"UnknownError"})}}(),globalThis.__piDeskPiSessionHistoryCatalogState={epochs:new Map,activeLoads:new Map,catalogs:new Map}),globalThis.__piDeskPiSessionHistoryCatalogState}function p(a){let b=(o().epochs.get(a)??0)+1;return o().epochs.set(a,b),b}function q(a,b){let c=o().catalogs.get((0,h.resolve)(a));if(c&&!c.dirty)return c.sessions.find(a=>a.sessionId===b)?.path}function r(a){let b=o();if(a){let c=(0,h.resolve)(a);p(c);let d=b.catalogs.get(c);d&&(d.dirty=!0);return}for(let a of new Set([...b.catalogs.keys(),...b.activeLoads.keys()])){p(a);let c=b.catalogs.get(a);c&&(c.dirty=!0)}}d()}catch(a){d(a)}})},78220:(a,b,c)=>{function d(a){if(!/^(0|[1-9]\d*)$/.test(a))return a;let b=Number(a);if(!Number.isSafeInteger(b))throw Error(`Increment array index is invalid: ${a}`);return b}function e(a){if(!a||a.length>1024)throw Error("Increment path length is invalid");let b=[],c="",e=!1;for(let d of a){if(e){if("."!==d&&"\\"!==d)throw Error(`Increment path contains an invalid escape: \\${d}`);c+=d,e=!1;continue}if("\\"===d){e=!0;continue}if("."===d){if(!c)throw Error("Increment path contains an empty segment");b.push(c),c="";continue}c+=d}if(e)throw Error("Increment path ends with an escape");if(!c)throw Error("Increment path contains an empty segment");b.push(c);let f=b.shift();if("summary"!==f&&"detail"!==f)throw Error("Increment path root must be summary or detail");return{root:f,segments:b.map(d)}}function f(a,b){return a.root===b.root&&!(a.segments.length>b.segments.length)&&a.segments.every((a,c)=>a===b.segments[c])}c.d(b,{U:()=>e,v:()=>f})},78555:(a,b,c)=>{c.d(b,{i:()=>n});var d=c(73024),e=c(51455),f=c(76760),g=c(88134);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}},80159:(a,b,c)=>{c.d(b,{Hj:()=>g,Nb:()=>f,O0:()=>h,Sl:()=>e,k0:()=>d}),c(77598),c(48180);let d="pi-desk:session-plugins",e="pi-desk:session-plugin-methods:v1",f="pi-desk:session-plugin-push:v1",g="pi-desk:session-capabilities",h="pi-desk:task-report:v1"},84641:(a,b,c)=>{function d(a){return`---
44
- name: pi-desk
45
- description: 管理 Pi Desk,或开发、安装、更新、加载供 Pi Desk 使用的插件时使用。
46
- ---
47
-
48
- # Pi Desk
49
-
50
- 通过 \`pidesk\` 工具执行宿主命令,参数为 \`{ "args": ["命令", "子命令", "参数"] }\`。当前命令以 \`["--help"]\` 为准,具体命令也支持 \`--help\`。
51
-
52
- - 插件开发、安装、更新或卸载:先阅读 [插件管理](references/plugins.md)。
53
- - 开发 Pi Desk 插件:阅读 ${a.sdkRoot}/README.md 和当前版本的公开类型声明;涉及界面时,先向用户取得对应版本的 UI 标准及分册,并完整阅读。
54
- - 原生 Pi 扩展:阅读 ${a.piDocs}/extensions.md。
55
-
56
- ## 执行结果
57
-
58
- - \`mode: sync\`:本次执行已经结束,直接使用返回结果。
59
- - \`mode: async\`:本次操作已接纳,尚未完成。宿主会向本会话插入最终结果并唤醒模型;无独立工作时结束当前轮,不持续查询或重复提交。
60
- - 工具报错表示请求失败;不能把已接纳、等待加载或等待重启说成已生效。
61
-
62
- ## 重载当前会话
63
-
64
- 调用 \`{ "args": ["session", "reload"] }\`,等同输入框“更多 → 重载 Pi 配置”。保留聊天历史与当前分支,重新加载 Pi 配置、Skills 和本机已安装插件的当前代码;不会自动下载插件新版本,需要更新时先使用插件安装命令。
65
-
66
- 接纳后结束本轮对话,等待宿主在当前会话完全空闲后执行;最终结果会通知并唤醒本会话。重载可能重建插件内存状态、使缓存失效;配置或工具定义变化也可能影响模型的提示词缓存命中。
67
-
68
- ## 当前目录
69
-
70
- Pi AgentDir:${a.agentDir}
71
- 全局本地扩展:${a.agentDir}/extensions
72
-
73
- 这些文件由当前宿主启动时生成;修改指引应修改宿主源码中的模板。
74
- `}function e(a){return`# 插件管理
75
-
76
- 通过 \`pidesk\` 的 \`plugins\` 子命令复用设置中的插件管理。当前只支持全局范围;项目级管理与裸扩展卸载不在当前能力中。
77
-
78
- | 任务 | args |
79
- | --- | --- |
80
- | 查询清单与状态 | \`["plugins", "list"]\` |
81
- | 批量检查更新 | \`["plugins", "list", "--check-updates"]\` |
82
- | 只检查跟随 dev 的插件 | \`["plugins", "list", "--check-updates", "--tag", "dev"]\` |
83
- | 查询插件详情 | \`["plugins", "show", "<name>", "--scope", "global"]\` |
84
- | 安装、更新或重装 | \`["plugins", "install", "<name>", "--scope", "global"]\` |
85
- | 批量安装或更新 | \`["plugins", "install", "<name-1>", "<name-2>", "--scope", "global"]\` |
86
- | 安装并跟随 dev 渠道 | \`["plugins", "install", "<name>", "--scope", "global", "--tag", "dev"]\` |
87
- | 安装指定 npm 版本 | \`["plugins", "install", "<name>", "--scope", "global", "--version", "1.2.3"]\` |
88
- | 批量卸载包来源 | \`["plugins", "remove", "<name-1>", "<name-2>", "--scope", "global"]\` |
89
-
90
- \`install/remove\` 可传一个或多个名字;批量安装共用所选标签或版本。不指定版本或标签也可以安装。
91
-
92
- ## 本地开发
93
-
94
- 源码放在 ${a}/extensions/<name>/,使用插件清单或固定目录中的名字,不传自定义路径。单文件扩展也可使用清单中的名字。
95
-
96
- 开发完成后验证代码并调用 \`install\`,修改后仍调用 \`install\` 重新加载当前代码。原生 TypeScript 可直接加载;存在浏览器构建入口时先完成必要编译,不要求发布 npm 或生成安装包。本地来源不接受 \`--version\` 或 \`--tag\`。
97
-
98
- ## npm 插件
99
-
100
- 使用完整 npm 包名,例如 \`@example/plugin\`。\`install\` 统一表示首次安装、更新和重新安装;已是目标版本也执行重装。
101
-
102
- 版本和标签均可省略:新插件默认 \`latest\`,已有插件沿保存的更新渠道。\`--tag dev\` 安装该标签指向的版本并保存后续跟随渠道;\`--version\` 只指定本次完整版本,不改变已有渠道。两者不能同时使用,不从版本后缀猜测更新渠道。
103
-
104
- \`list --check-updates\` 按各插件自己的渠道检查;附加 \`--tag dev\` 只检查跟随 dev 的插件,不修改渠道、不执行安装。缺少标签或查询失败仅报告对应项错误,不回退 latest。需要只调整渠道、不安装时,在插件管理界面多选后使用“设置渠道”。
105
-
106
- 插件文件与 \`settings.json\` 由 Pi 官方包管理器维护。不要直接覆盖配置或自行修改安装目录。存在同名来源冲突时,先确认目标,不猜测。
107
-
108
- ## 生效与卸载
109
-
110
- 安装与卸载接纳后由宿主串行处理,只等待目标插件必要的在途调用,不冻结常规聊天、不自动重载已有 Pi 会话。完成表示插件包及宿主能力已应用;新建会话采用最新工具配置,需要让已有会话采用新版工具时,再按用户需要重载该会话。
111
-
112
- 每批只发送一条结果汇总,逐项区分成功、未接纳、失败和等待重启;部分失败不代表其他项失败。最终结果以会话通知为准,需要重启时沿用插件管理界面的维护流程,不能提前报告成功。
113
-
114
- \`remove\` 只作用于现有插件管理支持的包来源,不附带业务数据清理,不用删除源码或新增禁用规则代替卸载。
115
- `}c.d(b,{_:()=>e,i:()=>d})},87048:(a,b,c)=>{c.d(b,{FR:()=>m,kn:()=>l,zR:()=>k});var d=c(56255),e=c(78220);function f(a){return`${a.location.index}:${a.location.entryId}`}let g={user:["viewKey","hasDetail"],assistant:["viewKey","status","hasDetail","usage"],tool:["viewKey","status","hasDetail","usage"],bash:["viewKey","status","hasDetail"],custom:["viewKey","hasDetail"]};function h(a,b,c){if(!b)return a;let e={...a,...b};return"summary"===c?d.Hf.parse(e):d.D8.parse(e)}function i(a,b){if(Array.isArray(a.parent)){if("number"!=typeof a.key)throw Error("Increment array key is invalid");a.parent[a.key]=b;return}if("string"!=typeof a.key)throw Error("Increment object key is invalid");a.parent[a.key]=b}function j(a,b,c){let e=structuredClone(a),f=function(a,b){if(0===b.length)throw Error("Increment cannot append to the message layer root");let c=a;for(let a of b.slice(0,-1)){if("number"==typeof a){if(!Array.isArray(c)||a>=c.length)throw Error(`Increment array path does not exist: ${a}`);c=c[a];continue}if(!c||"object"!=typeof c||Array.isArray(c))throw Error(`Increment object path does not exist: ${a}`);if(!Object.hasOwn(c,a))throw Error(`Increment object field does not exist: ${a}`);c=c[a]}let d=b.at(-1);if("number"==typeof d){if(!Array.isArray(c)||d>=c.length)throw Error(`Increment array target does not exist: ${d}`);return{parent:c,key:d,value:c[d]}}if(!c||"object"!=typeof c||Array.isArray(c))throw Error(`Increment object target does not exist: ${d}`);if(!Object.hasOwn(c,d))throw Error(`Increment target does not exist: ${d}`);return{parent:c,key:d,value:c[d]}}(e,b);if("string"==typeof c){if("string"!=typeof f.value)throw Error("Increment target is not a string");return i(f,`${f.value}${c}`),d.Hf.parse(e)}if(!Array.isArray(f.value))throw Error("Increment target is not an array");return i(f,[...f.value,...c]),d.Hf.parse(e)}function k(a,b,c){let e=new Map(a.messages.filter(a=>void 0!==a.detail).map(a=>[f(a),a]));return{messages:b.map(a=>{let b=e.get(f(a));return a.fixed.hasDetail&&b&&b.fixed.type===a.fixed.type&&b.fixed.viewKey===a.fixed.viewKey&&void 0!==b.detail?d.mj.parse({...a,detail:b.detail}):a}),temporaryMessages:[...c]}}function l(a,b){if("message_start"===b.type){if(a.temporaryMessages.some(a=>a.location.tempId===b.snapshot.location.tempId))throw Error(`Temporary conversation message already exists: ${b.snapshot.location.tempId}`);return{...a,temporaryMessages:[...a.temporaryMessages,b.snapshot]}}let c=a.temporaryMessages.findIndex(a=>a.location.tempId===b.location.tempId);if(c<0)throw Error(`Temporary conversation message was not found: ${b.location.tempId}`);if("message_update"===b.type){let f=[...a.temporaryMessages];return f[c]=function(a,b){var c,f;if(a.location.tempId!==b.location.tempId)throw Error(`Conversation update tempId mismatch: ${b.location.tempId}`);let i=(c=a.fixed,(f=b.fixed)?(!function(a,b,c){let d=Object.keys(a).filter(a=>!b.includes(a));if(d.length>0)throw Error(`${c} patch contains fields invalid for the current message: ${d}`)}(f,g[c.type],`${c.type} fixed`),d.q5.parse({...c,...f})):c),k=h(a.summary,b.summary,"summary"),l=a.detail;if(void 0!==b.detail||Object.keys(b.increments??{}).some(a=>"detail"===(0,e.U)(a).root)){if(b.fixed?.hasDetail===!1)throw Error("Realtime detail cannot be updated while explicitly clearing hasDetail");i.hasDetail||(i=d.q5.parse({...i,hasDetail:!0}))}for(let[a,c]of(b.detail&&(l=h(l??{},b.detail,"detail")),Object.entries(b.increments??{}))){let b=(0,e.U)(a);"summary"===b.root?k=j(k,b.segments,c):l=j(l??{},b.segments,c)}return i.hasDetail||(l=void 0),d.s4.parse({location:a.location,fixed:i,summary:k,...void 0===l?{}:{detail:l}})}(f[c],b),{...a,temporaryMessages:f}}if("message_discard"===b.type)return{...a,temporaryMessages:a.temporaryMessages.filter(a=>a.location.tempId!==b.location.tempId)};if(b.durable.index!==a.messages.length)throw Error(`Conversation commit index is not continuous: expected ${a.messages.length}, received ${b.durable.index}`);if(a.messages.some(a=>a.location.entryId===b.durable.entryId))throw Error(`Conversation commit entryId already exists: ${b.durable.entryId}`);let{detail:f,fixed:i,...k}=a.temporaryMessages[c],l=d.mj.parse({...k,location:b.durable,fixed:{...i,timestampMs:b.fixed.timestampMs},...i.hasDetail&&void 0!==f?{detail:f}:{}});return{messages:[...a.messages,l],temporaryMessages:a.temporaryMessages.filter(a=>a.location.tempId!==b.location.tempId)}}function m(a,b){return"durable_append"===b.type?function(a,b){let c=a.messages.length;if(b.messages[0]?.location.index!==c)throw Error(`Conversation append index is not continuous: expected ${c}, received ${b.messages[0]?.location.index}`);let d=new Set(a.messages.map(a=>a.location.entryId));for(let a of b.messages){if(d.has(a.location.entryId))throw Error(`Conversation append entryId already exists: ${a.location.entryId}`);d.add(a.location.entryId)}return{...a,messages:[...a.messages,...b.messages]}}(a,b):l(a,b)}},88134:(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)}},88277:(a,b,c)=>{c.d(b,{P:()=>h,WR:()=>g,YB:()=>i,Z$:()=>j,l3:()=>k});var d=c(36153);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:{}}}},92411:(a,b,c)=>{c.d(b,{IM:()=>k});var d=c(36153),e=c(41743),f=c(72415);let g=d.Yj().trim().min(1),h=d.Yj().trim().min(1),i=d.Ik({provider:g,modelId:h,name:d.Yj().trim().min(1),input:d.YO(d.k5(["text","image"])).min(1),kind:d.k5(["physical","virtual"]),contextWindow:d.ai().int().positive().max(Number.MAX_SAFE_INTEGER).nullable(),thinkingLevels:d.YO(f.$).min(1)}).strict(),j=d.Ik({provider:g,modelId:h,thinkingLevel:f.$,color:d.Yj().trim().min(1).nullable()}).strict();d.Ik({workId:e.eW}).strict();let k=d.Ik({models:d.YO(i),presets:d.YO(j)}).strict()},94074:(a,b,c)=>{c.d(b,{u:()=>e});let d="v1:main";class e{constructor(a){for(const b of(this.entryIds=new Set,this.branchIdByEntryId=new Map,this.childCountByParentId=new Map,a))this.appendEntry(b)}branchIdForEntry(a){let b=this.branchIdByEntryId.get(a);if(!b)throw Error(`Pi session entry has no branch identity: ${a}`);return b}branchIdForHead(a){return null===a?d:this.branchIdForEntry(a)}predictAppend(a){if(null!==a&&!this.entryIds.has(a))throw Error(`Cannot append to missing Pi session parent: ${a}`);let b=(this.childCountByParentId.get(a)??0)+1;return{parentEntryId:a,childOrdinal:b,branchId:this.branchIdForChild(a,b)}}appendEntry(a){this.assertEntry(a);let b=this.predictAppend(a.parentId);return this.entryIds.add(a.id),this.branchIdByEntryId.set(a.id,b.branchId),this.childCountByParentId.set(a.parentId,b.childOrdinal),b}confirmAppend(a,b){let c=this.predictAppend(b.parentId);if(a.parentEntryId!==c.parentEntryId||a.childOrdinal!==c.childOrdinal||a.branchId!==c.branchId)throw Error(`Pi branch append conflict: expected ${a.branchId}/${a.childOrdinal}, got ${c.branchId}/${c.childOrdinal}`);return this.appendEntry(b),c.branchId}branchIdForChild(a,b){return null===a?1===b?d:`v1:fork:r:${b}`:1===b?this.branchIdForEntry(a):`v1:fork:e:${encodeURIComponent(a)}:${b}`}assertEntry(a){if(!a.id)throw Error("Pi session entry is missing an id");if(this.entryIds.has(a.id))throw Error(`Pi session contains duplicate entry id: ${a.id}`);if(null!==a.parentId&&(!a.parentId||!this.entryIds.has(a.parentId)))throw Error(`Pi session entry ${a.id} has missing parent: ${a.parentId}`)}}},98761:(a,b,c)=>{c.d(b,{$C:()=>z,A8:()=>D,GR:()=>p,MQ:()=>C,Pq:()=>A,Wh:()=>q,Xo:()=>n,YT:()=>y});var d=c(36153),e=c(59214),f=c(13127),g=c(72497),h=c(75106);let i=d.Yj().uuid(),j=d.k5(["info","success","warning","error"]),k=d.Yj().trim().min(1).max(120),l=d.Yj().trim().max(320).nullable(),m=d.Ik({type:d.eu("plugin"),pluginName:g.tv,name:g.f7,data:g.Dz}).strict(),n=d.Ik({notificationId:i,level:j,title:k,description:l,createdAt:h.k,event:m.nullable()}).strict(),o=d.g1(g.tv,g.Dz),p=d.Ik({mode:d.k5(["normal","basic"]).default("normal"),notifications:d.YO(n),plugins:o,capabilityModes:f.Wu,settings:e.J.default({region:{locale:"en",timeZone:"UTC"}})}).strict(),q=d.Ik({level:j.optional(),title:k.optional(),description:l.optional()}).strict().refine(a=>Object.keys(a).length>0,{message:"notification changes cannot be empty"}),r=d.Ik({type:d.eu("add"),notification:n}).strict(),s=d.Ik({type:d.eu("update"),notificationId:i,changes:q}).strict(),t=d.Ik({type:d.eu("delete"),notificationId:i}).strict(),u=d.gM("type",[r,s,t]),v=d.Ik({pluginName:g.tv,state:g.Dz.nullable()}).strict(),w=d.Ik({key:d.eu("capabilityModes"),update:f.Wu}).strict(),x=d.Ik({key:d.eu("settings"),update:e.J}).strict();d.gM("key",[x,w,d.Ik({key:d.eu("notifications"),update:u}).strict(),d.Ik({key:d.eu("plugins"),update:v}).strict()]);let y=d.KC([x.extend({type:d.eu("update")}),w.extend({type:d.eu("update")}),d.Ik({type:d.eu("replace"),runtime:p}).strict(),d.Ik({type:d.eu("update"),key:d.eu("notifications"),update:u}).strict(),d.Ik({type:d.eu("update"),key:d.eu("plugins"),update:v}).strict()]),z=d.gM("key",[d.Ik({key:d.eu("notifications"),update:t}).strict(),d.Ik({key:d.eu("settings"),update:d.Ik({region:e.a.unwrap().partial().strict().refine(a=>Object.keys(a).length>0,"地区更新不能为空")}).strict()}).strict()]),A=d.Ik({}).strict(),B=d.Ik({name:g.f7,data:g.Dz}).strict(),C=d.Ik({level:j,title:k,description:d.Yj().trim().max(320).optional(),event:B.optional()}).strict(),D=d.Ik({level:j.optional(),title:k.optional(),description:l.optional()}).strict().refine(a=>Object.keys(a).length>0,{message:"plugin notification changes cannot be empty"})}};
42
+ 事件:${a.event}`;this.active&&(console.error("[Pi Desk][PiSession] 扩展处理失败",{sessionId:this.sessionId,message:b}),this.onLifecycleError?.(Error(b)),("session_tree"===a.event||"session_before_tree"===a.event)&&this.session?.extensionRunner.getUIContext().notify(`会话树扩展处理失败:${a.error}`,"error"))}}),this.assertActive(),this.messages.installExtensionRuntime(b.resourceLoader.getExtensions().runtime),this.setStage("应用会话能力"),await this.capabilities.apply(),this.assertActive(),c}}d()}catch(a){d(a)}})},77167:(a,b,c)=>{c.d(b,{O:()=>d});function d(a){return`Pi Desk 资料(仅在使用、管理 Pi Desk 或开发其插件时读取):
43
+ - 文档入口:${a.docsDirectory}/README.md
44
+ - SDK 公开类型声明:${a.sdkRoot}/dist/
45
+ 从入口选择并完整阅读对应文档及引用示例;原生 Pi 能力按入口引用查阅官方资料。相对路径从文档所在目录解析。`}},78143:(a,b,c)=>{c.d(b,{$E:()=>f,Rv:()=>g,m4:()=>e});var d=c(36153);let e=d.Yj().trim().min(1),f=d.Yj().trim().min(1),g=d.Yj().trim().min(1)},78180:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Ph:()=>q,xt:()=>r});var e=c(17691),f=c(77598),g=c(73024);c(51455);var h=c(76760);c(80481);var i=c(75430),j=c(36153),k=c(18200),l=a([e,i,k]);[e,i,k]=l.then?(await l)():l;let s=j.Ik({entryId:j.Yj().min(1),timestampMs:j.ai().int().nonnegative(),text:j.Yj()}).strict(),t=j.Ik({path:j.Yj().min(1),sessionId:j.Yj().min(1),cwd:j.Yj().min(1),name:j.Yj().nullable(),createdAt:j.ai().int().nonnegative(),updatedAt:j.ai().int().nonnegative(),messageCount:j.ai().int().nonnegative(),userMessageCount:j.ai().int().nonnegative(),firstMessage:j.Yj(),userMessages:j.YO(s),assistantMessages:j.YO(s),textBytes:j.ai().int().nonnegative()}).strict(),u=j.Ik({descriptor:j.Ik({path:j.Yj().min(1),size:j.ai().int().nonnegative(),modifiedAt:j.ai().int().nonnegative()}).strict(),record:t.nullable()}).strict(),v=j.Ik({cwd:j.Yj().min(1),files:j.YO(u)}).strict();v.extend({version:j.eu(2)});let w=j.Ik({version:j.eu(1),catalogs:j.YO(v)}).strict();function m(){return(0,h.join)((0,e.M)(),"pi-session-history")}function n(a){let b=(0,f.createHash)("sha256").update(a).digest("hex");return(0,h.join)(m(),`${b}.json`)}function o(){return globalThis.__piDeskPiSessionHistoryCatalogState||(!function(){let a=(0,h.join)((0,e.M)(),"pi-session-history.json");if((0,g.existsSync)(a))try{let b=w.parse(JSON.parse((0,g.readFileSync)(a,"utf8")));for(let a of b.catalogs){let b=function(a){let b=(0,h.resolve)(a.cwd),c=new Map;for(let d of a.files){let a=null;if(d.record&&d.record.path===d.descriptor.path&&(0,h.resolve)(d.record.cwd)===b){let b=d.record.assistantMessages.filter(a=>a.text.trim()),c=d.record.assistantMessages.reduce((a,b)=>a+(b.text.trim()?0:Buffer.byteLength(b.text,"utf8")),0);a={...d.record,assistantMessages:b,textBytes:d.record.textBytes-c}}c.set(d.descriptor.path,{descriptor:d.descriptor,record:a})}let d=Array.from(c.values()).flatMap(a=>a.record?[a.record]:[]).sort((a,b)=>b.updatedAt-a.updatedAt),e=Date.now();return{cwd:b,files:c,sessions:d,textBytes:d.reduce((a,b)=>a+b.textBytes,0),dirty:!1,validatedAt:0,lastAccessedAt:e}}(a);if(!(0,g.existsSync)(n(b.cwd))&&!function(a){let b=n(a.cwd),c=`${b}.${process.pid}.${(0,f.randomUUID)()}.tmp`;try{(0,g.mkdirSync)((0,h.dirname)(b),{recursive:!0}),(0,g.writeFileSync)(c,`${JSON.stringify({version:2,cwd:a.cwd,files:Array.from(a.files.values())})}
46
+ `,"utf8"),(0,g.renameSync)(c,b);let d=m(),e=(0,g.readdirSync)(d).filter(a=>/^[a-f0-9]{64}\.json$/u.test(a)).map(a=>{let b=(0,h.join)(d,a),c=(0,g.statSync)(b);return{path:b,size:c.size,modifiedAt:c.mtimeMs}}).sort((a,b)=>a.modifiedAt-b.modifiedAt),f=e.reduce((a,b)=>a+b.size,0);for(;e.length>1&&(e.length>8||f>0x4000000);){let a=e.shift();(0,g.unlinkSync)(a.path),f-=a.size}return!0}catch(a){return console.warn("[Pi Desk][PiSessionHistoryCatalog] 写入历史会话持久缓存失败",{path:b,errorName:a instanceof Error?a.name:"UnknownError"}),!1}finally{(0,g.existsSync)(c)&&(0,g.unlinkSync)(c)}}(b))return}(0,g.unlinkSync)(a),console.info("[Pi Desk][PiSessionHistoryCatalog] 已迁移历史会话缓存",{catalogCount:b.catalogs.length})}catch(b){console.warn("[Pi Desk][PiSessionHistoryCatalog] 迁移历史会话缓存失败",{path:a,errorName:b instanceof Error?b.name:"UnknownError"})}}(),globalThis.__piDeskPiSessionHistoryCatalogState={epochs:new Map,activeLoads:new Map,catalogs:new Map}),globalThis.__piDeskPiSessionHistoryCatalogState}function p(a){let b=(o().epochs.get(a)??0)+1;return o().epochs.set(a,b),b}function q(a,b){let c=o().catalogs.get((0,h.resolve)(a));if(c&&!c.dirty)return c.sessions.find(a=>a.sessionId===b)?.path}function r(a){let b=o();if(a){let c=(0,h.resolve)(a);p(c);let d=b.catalogs.get(c);d&&(d.dirty=!0);return}for(let a of new Set([...b.catalogs.keys(),...b.activeLoads.keys()])){p(a);let c=b.catalogs.get(a);c&&(c.dirty=!0)}}d()}catch(a){d(a)}})},78220:(a,b,c)=>{function d(a){if(!/^(0|[1-9]\d*)$/.test(a))return a;let b=Number(a);if(!Number.isSafeInteger(b))throw Error(`Increment array index is invalid: ${a}`);return b}function e(a){if(!a||a.length>1024)throw Error("Increment path length is invalid");let b=[],c="",e=!1;for(let d of a){if(e){if("."!==d&&"\\"!==d)throw Error(`Increment path contains an invalid escape: \\${d}`);c+=d,e=!1;continue}if("\\"===d){e=!0;continue}if("."===d){if(!c)throw Error("Increment path contains an empty segment");b.push(c),c="";continue}c+=d}if(e)throw Error("Increment path ends with an escape");if(!c)throw Error("Increment path contains an empty segment");b.push(c);let f=b.shift();if("summary"!==f&&"detail"!==f)throw Error("Increment path root must be summary or detail");return{root:f,segments:b.map(d)}}function f(a,b){return a.root===b.root&&!(a.segments.length>b.segments.length)&&a.segments.every((a,c)=>a===b.segments[c])}c.d(b,{U:()=>e,v:()=>f})},78555:(a,b,c)=>{c.d(b,{i:()=>n});var d=c(73024),e=c(51455),f=c(76760),g=c(88134);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}},80159:(a,b,c)=>{c.d(b,{Hj:()=>g,Nb:()=>f,O0:()=>h,Sl:()=>e,k0:()=>d}),c(77598),c(48180);let d="pi-desk:session-plugins",e="pi-desk:session-plugin-methods:v1",f="pi-desk:session-plugin-push:v1",g="pi-desk:session-capabilities",h="pi-desk:task-report:v1"},87048:(a,b,c)=>{c.d(b,{FR:()=>m,kn:()=>l,zR:()=>k});var d=c(56255),e=c(78220);function f(a){return`${a.location.index}:${a.location.entryId}`}let g={user:["viewKey","hasDetail"],assistant:["viewKey","status","hasDetail","usage"],tool:["viewKey","status","hasDetail","usage"],bash:["viewKey","status","hasDetail"],custom:["viewKey","hasDetail"]};function h(a,b,c){if(!b)return a;let e={...a,...b};return"summary"===c?d.Hf.parse(e):d.D8.parse(e)}function i(a,b){if(Array.isArray(a.parent)){if("number"!=typeof a.key)throw Error("Increment array key is invalid");a.parent[a.key]=b;return}if("string"!=typeof a.key)throw Error("Increment object key is invalid");a.parent[a.key]=b}function j(a,b,c){let e=structuredClone(a),f=function(a,b){if(0===b.length)throw Error("Increment cannot append to the message layer root");let c=a;for(let a of b.slice(0,-1)){if("number"==typeof a){if(!Array.isArray(c)||a>=c.length)throw Error(`Increment array path does not exist: ${a}`);c=c[a];continue}if(!c||"object"!=typeof c||Array.isArray(c))throw Error(`Increment object path does not exist: ${a}`);if(!Object.hasOwn(c,a))throw Error(`Increment object field does not exist: ${a}`);c=c[a]}let d=b.at(-1);if("number"==typeof d){if(!Array.isArray(c)||d>=c.length)throw Error(`Increment array target does not exist: ${d}`);return{parent:c,key:d,value:c[d]}}if(!c||"object"!=typeof c||Array.isArray(c))throw Error(`Increment object target does not exist: ${d}`);if(!Object.hasOwn(c,d))throw Error(`Increment target does not exist: ${d}`);return{parent:c,key:d,value:c[d]}}(e,b);if("string"==typeof c){if("string"!=typeof f.value)throw Error("Increment target is not a string");return i(f,`${f.value}${c}`),d.Hf.parse(e)}if(!Array.isArray(f.value))throw Error("Increment target is not an array");return i(f,[...f.value,...c]),d.Hf.parse(e)}function k(a,b,c){let e=new Map(a.messages.filter(a=>void 0!==a.detail).map(a=>[f(a),a]));return{messages:b.map(a=>{let b=e.get(f(a));return a.fixed.hasDetail&&b&&b.fixed.type===a.fixed.type&&b.fixed.viewKey===a.fixed.viewKey&&void 0!==b.detail?d.mj.parse({...a,detail:b.detail}):a}),temporaryMessages:[...c]}}function l(a,b){if("message_start"===b.type){if(a.temporaryMessages.some(a=>a.location.tempId===b.snapshot.location.tempId))throw Error(`Temporary conversation message already exists: ${b.snapshot.location.tempId}`);return{...a,temporaryMessages:[...a.temporaryMessages,b.snapshot]}}let c=a.temporaryMessages.findIndex(a=>a.location.tempId===b.location.tempId);if(c<0)throw Error(`Temporary conversation message was not found: ${b.location.tempId}`);if("message_update"===b.type){let f=[...a.temporaryMessages];return f[c]=function(a,b){var c,f;if(a.location.tempId!==b.location.tempId)throw Error(`Conversation update tempId mismatch: ${b.location.tempId}`);let i=(c=a.fixed,(f=b.fixed)?(!function(a,b,c){let d=Object.keys(a).filter(a=>!b.includes(a));if(d.length>0)throw Error(`${c} patch contains fields invalid for the current message: ${d}`)}(f,g[c.type],`${c.type} fixed`),d.q5.parse({...c,...f})):c),k=h(a.summary,b.summary,"summary"),l=a.detail;if(void 0!==b.detail||Object.keys(b.increments??{}).some(a=>"detail"===(0,e.U)(a).root)){if(b.fixed?.hasDetail===!1)throw Error("Realtime detail cannot be updated while explicitly clearing hasDetail");i.hasDetail||(i=d.q5.parse({...i,hasDetail:!0}))}for(let[a,c]of(b.detail&&(l=h(l??{},b.detail,"detail")),Object.entries(b.increments??{}))){let b=(0,e.U)(a);"summary"===b.root?k=j(k,b.segments,c):l=j(l??{},b.segments,c)}return i.hasDetail||(l=void 0),d.s4.parse({location:a.location,fixed:i,summary:k,...void 0===l?{}:{detail:l}})}(f[c],b),{...a,temporaryMessages:f}}if("message_discard"===b.type)return{...a,temporaryMessages:a.temporaryMessages.filter(a=>a.location.tempId!==b.location.tempId)};if(b.durable.index!==a.messages.length)throw Error(`Conversation commit index is not continuous: expected ${a.messages.length}, received ${b.durable.index}`);if(a.messages.some(a=>a.location.entryId===b.durable.entryId))throw Error(`Conversation commit entryId already exists: ${b.durable.entryId}`);let{detail:f,fixed:i,...k}=a.temporaryMessages[c],l=d.mj.parse({...k,location:b.durable,fixed:{...i,timestampMs:b.fixed.timestampMs},...i.hasDetail&&void 0!==f?{detail:f}:{}});return{messages:[...a.messages,l],temporaryMessages:a.temporaryMessages.filter(a=>a.location.tempId!==b.location.tempId)}}function m(a,b){return"durable_append"===b.type?function(a,b){let c=a.messages.length;if(b.messages[0]?.location.index!==c)throw Error(`Conversation append index is not continuous: expected ${c}, received ${b.messages[0]?.location.index}`);let d=new Set(a.messages.map(a=>a.location.entryId));for(let a of b.messages){if(d.has(a.location.entryId))throw Error(`Conversation append entryId already exists: ${a.location.entryId}`);d.add(a.location.entryId)}return{...a,messages:[...a.messages,...b.messages]}}(a,b):l(a,b)}},88134:(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)}},88277:(a,b,c)=>{c.d(b,{P:()=>h,WR:()=>g,YB:()=>i,Z$:()=>j,l3:()=>k});var d=c(36153);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:{}}}},92411:(a,b,c)=>{c.d(b,{IM:()=>k});var d=c(36153),e=c(41743),f=c(72415);let g=d.Yj().trim().min(1),h=d.Yj().trim().min(1),i=d.Ik({provider:g,modelId:h,name:d.Yj().trim().min(1),input:d.YO(d.k5(["text","image"])).min(1),kind:d.k5(["physical","virtual"]),contextWindow:d.ai().int().positive().max(Number.MAX_SAFE_INTEGER).nullable(),thinkingLevels:d.YO(f.$).min(1)}).strict(),j=d.Ik({provider:g,modelId:h,thinkingLevel:f.$,color:d.Yj().trim().min(1).nullable()}).strict();d.Ik({workId:e.eW}).strict();let k=d.Ik({models:d.YO(i),presets:d.YO(j)}).strict()},94074:(a,b,c)=>{c.d(b,{u:()=>e});let d="v1:main";class e{constructor(a){for(const b of(this.entryIds=new Set,this.branchIdByEntryId=new Map,this.childCountByParentId=new Map,a))this.appendEntry(b)}branchIdForEntry(a){let b=this.branchIdByEntryId.get(a);if(!b)throw Error(`Pi session entry has no branch identity: ${a}`);return b}branchIdForHead(a){return null===a?d:this.branchIdForEntry(a)}predictAppend(a){if(null!==a&&!this.entryIds.has(a))throw Error(`Cannot append to missing Pi session parent: ${a}`);let b=(this.childCountByParentId.get(a)??0)+1;return{parentEntryId:a,childOrdinal:b,branchId:this.branchIdForChild(a,b)}}appendEntry(a){this.assertEntry(a);let b=this.predictAppend(a.parentId);return this.entryIds.add(a.id),this.branchIdByEntryId.set(a.id,b.branchId),this.childCountByParentId.set(a.parentId,b.childOrdinal),b}confirmAppend(a,b){let c=this.predictAppend(b.parentId);if(a.parentEntryId!==c.parentEntryId||a.childOrdinal!==c.childOrdinal||a.branchId!==c.branchId)throw Error(`Pi branch append conflict: expected ${a.branchId}/${a.childOrdinal}, got ${c.branchId}/${c.childOrdinal}`);return this.appendEntry(b),c.branchId}branchIdForChild(a,b){return null===a?1===b?d:`v1:fork:r:${b}`:1===b?this.branchIdForEntry(a):`v1:fork:e:${encodeURIComponent(a)}:${b}`}assertEntry(a){if(!a.id)throw Error("Pi session entry is missing an id");if(this.entryIds.has(a.id))throw Error(`Pi session contains duplicate entry id: ${a.id}`);if(null!==a.parentId&&(!a.parentId||!this.entryIds.has(a.parentId)))throw Error(`Pi session entry ${a.id} has missing parent: ${a.parentId}`)}}},98761:(a,b,c)=>{c.d(b,{$C:()=>z,A8:()=>D,GR:()=>p,MQ:()=>C,Pq:()=>A,Wh:()=>q,Xo:()=>n,YT:()=>y});var d=c(36153),e=c(59214),f=c(13127),g=c(72497),h=c(75106);let i=d.Yj().uuid(),j=d.k5(["info","success","warning","error"]),k=d.Yj().trim().min(1).max(120),l=d.Yj().trim().max(320).nullable(),m=d.Ik({type:d.eu("plugin"),pluginName:g.tv,name:g.f7,data:g.Dz}).strict(),n=d.Ik({notificationId:i,level:j,title:k,description:l,createdAt:h.k,event:m.nullable()}).strict(),o=d.g1(g.tv,g.Dz),p=d.Ik({mode:d.k5(["normal","basic"]).default("normal"),notifications:d.YO(n),plugins:o,capabilityModes:f.Wu,settings:e.J.default({region:{locale:"en",timeZone:"UTC"}})}).strict(),q=d.Ik({level:j.optional(),title:k.optional(),description:l.optional()}).strict().refine(a=>Object.keys(a).length>0,{message:"notification changes cannot be empty"}),r=d.Ik({type:d.eu("add"),notification:n}).strict(),s=d.Ik({type:d.eu("update"),notificationId:i,changes:q}).strict(),t=d.Ik({type:d.eu("delete"),notificationId:i}).strict(),u=d.gM("type",[r,s,t]),v=d.Ik({pluginName:g.tv,state:g.Dz.nullable()}).strict(),w=d.Ik({key:d.eu("capabilityModes"),update:f.Wu}).strict(),x=d.Ik({key:d.eu("settings"),update:e.J}).strict();d.gM("key",[x,w,d.Ik({key:d.eu("notifications"),update:u}).strict(),d.Ik({key:d.eu("plugins"),update:v}).strict()]);let y=d.KC([x.extend({type:d.eu("update")}),w.extend({type:d.eu("update")}),d.Ik({type:d.eu("replace"),runtime:p}).strict(),d.Ik({type:d.eu("update"),key:d.eu("notifications"),update:u}).strict(),d.Ik({type:d.eu("update"),key:d.eu("plugins"),update:v}).strict()]),z=d.gM("key",[d.Ik({key:d.eu("notifications"),update:t}).strict(),d.Ik({key:d.eu("settings"),update:d.Ik({region:e.a.unwrap().partial().strict().refine(a=>Object.keys(a).length>0,"地区更新不能为空")}).strict()}).strict()]),A=d.Ik({}).strict(),B=d.Ik({name:g.f7,data:g.Dz}).strict(),C=d.Ik({level:j,title:k,description:d.Yj().trim().max(320).optional(),event:B.optional()}).strict(),D=d.Ik({level:j.optional(),title:k.optional(),description:l.optional()}).strict().refine(a=>Object.keys(a).length>0,{message:"plugin notification changes cannot be empty"})}};