@jetcrab/pi-desk 1.1.23-dev → 1.1.25
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.
- package/docs/commands.md +4 -2
- package/docs/plugins.md +2 -0
- package/package.json +2 -2
- package/src/app/project-preview/page.tsx +13 -0
- package/src/client/l1_entry/pages/l1-project-preview-page.tsx +1 -5
- package/src/client/l2_biz/project-preview/hooks/l2-use-project-preview.ts +25 -0
- package/src/client/l2_biz/project-preview/l2-project-preview-storage.ts +7 -7
- package/src/client/l2_biz/project-preview/l2-project-preview.tsx +8 -5
- package/src/client/l2_biz/project-preview/runtime/l2-project-history-runtime.ts +14 -11
- package/src/client/l2_biz/project-preview/views/l2-project-branch-select.tsx +347 -0
- package/src/client/l2_biz/project-preview/views/l2-project-change-tree.tsx +28 -11
- package/src/client/l2_biz/project-preview/views/l2-project-history-list.tsx +35 -8
- package/src/client/l2_biz/project-preview/views/l2-project-history-view.tsx +46 -48
- package/src/client/l2_biz/workbench/file-workspace/l2-file-workspace-runtime.ts +2 -1
- package/src/client/l2_biz/workbench/file-workspace/l2-file-workspace-view.tsx +6 -2
- package/src/client/l3_modules/conversation/l3-conversation-viewport.tsx +18 -8
- package/src/client/l3_modules/project-files/l3-project-document-view.tsx +7 -4
- package/src/client/l3_modules/project-files/l3-project-file-runtime.ts +181 -89
- package/src/client/l3_modules/project-files/l3-project-file-tabs.tsx +80 -28
- package/src/common/l2_biz/project-preview/l2-project-history-messages.ts +4 -2
- package/src/common/l2_biz/project-preview/l2-project-preview-navigation.ts +14 -0
- package/src/server/l1_entry/api/l1-plugin-management-route.ts +0 -4
- package/src/server/l2_biz/plugin-management/l2-plugin-management.ts +4 -37
- package/src/server/l2_biz/plugin-management/l2-plugin-updates.ts +1 -4
- package/src/server/l2_biz/work-session/l2-work-session-chat-runtime.ts +4 -2
- package/src/server/l4_foundation/pi/l4-pi-chat-worker.ts +16 -1
- package/src/server/l4_foundation/pi/l4-pi-package-root-consistency.ts +3 -6
- package/src/server/l4_foundation/pi/l4-pi-package-root-gate.ts +1 -1
- package/src/server/l4_foundation/pi/l4-pi-plugin-owner-runtime.ts +4 -0
- package/src/server/l4_foundation/pi/l4-pi-plugin-sources.ts +5 -1
- package/src/server/l4_foundation/pi/l4-pi-session-initialization.ts +30 -34
- package/src/server/l4_foundation/pi/l4-pi-session-resources.ts +15 -14
- package/src/server/l4_foundation/pi/l4-pi-work-session-runtime.ts +1 -1
- package/src/server/l4_foundation/skills/runtime/l4-skill-catalog.ts +159 -166
- package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
- package/temp/build/pi-desk/release/.next/build-manifest.json +3 -3
- package/temp/build/pi-desk/release/.next/prerender-manifest.json +3 -3
- package/temp/build/pi-desk/release/.next/react-loadable-manifest.json +1 -1
- package/temp/build/pi-desk/release/.next/required-server-files.js +3 -3
- package/temp/build/pi-desk/release/.next/required-server-files.json +3 -3
- package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/add/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/apply/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/batch/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/del/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/enabled-set/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/reload/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/update/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/page.js +2 -2
- package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/project-preview/page.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/project-preview/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/16438.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/18748.js +1 -0
- package/temp/build/pi-desk/release/.next/server/chunks/24557.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/25406.js +13 -14
- package/temp/build/pi-desk/release/.next/server/chunks/27344.js +15 -0
- package/temp/build/pi-desk/release/.next/server/chunks/35985.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/36361.js +2 -2
- package/temp/build/pi-desk/release/.next/server/chunks/50520.js +2 -2
- package/temp/build/pi-desk/release/.next/server/chunks/6917.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/80290.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/92386.js +15 -16
- package/temp/build/pi-desk/release/.next/server/instrumentation.js +1 -1
- package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
- package/temp/build/pi-desk/release/.next/server/server-reference-manifest.json +1 -1
- package/temp/build/pi-desk/release/.next/static/chunks/15302-6e070e13fa65c863.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/19991.bcca96d396b83030.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/65232-ef4e5a4174f62faf.js +15 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/{page-54040b9fd54ee8b3.js → page-18d63fd3920dfae0.js} +3 -3
- package/temp/build/pi-desk/release/.next/static/chunks/app/project-preview/page-038b6c14e03ed878.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/{webpack-48eecbb66781c006.js → webpack-c0b805df46fcf8b3.js} +1 -1
- package/temp/build/pi-desk/release/.next/static/css/c43b04c244a64fb4.css +1 -0
- package/temp/build/pi-desk/release/.next/trace-build +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/20460.js +0 -15
- package/temp/build/pi-desk/release/.next/server/chunks/93049.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/15302-9c807afc6c60de0c.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/19991.8aa2e4b6df15fad6.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/9038-05fd2688407b39c1.js +0 -15
- package/temp/build/pi-desk/release/.next/static/chunks/app/project-preview/page-bc18765121950e65.js +0 -1
- package/temp/build/pi-desk/release/.next/static/css/10e063cfb3cda7bd.css +0 -1
- /package/temp/build/pi-desk/release/.next/static/{gAYTx4KJJR3vTtGYexj4J → 6a4eIEjmpW5l8Qlgtzzzg}/_buildManifest.js +0 -0
- /package/temp/build/pi-desk/release/.next/static/{gAYTx4KJJR3vTtGYexj4J → 6a4eIEjmpW5l8Qlgtzzzg}/_ssgManifest.js +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use strict";exports.id=36361,exports.ids=[36361],exports.modules={4287:(a,b,c)=>{c.d(b,{LD:()=>k,SZ:()=>f,_C:()=>j,mR:()=>e,ug:()=>l,w3:()=>g,zj:()=>m});var d=c(36153);let e=d.Yj().trim().min(1).max(128).regex(/^[a-zA-Z][a-zA-Z0-9._-]*$/),f=d.Yj().trim().url().max(2048).refine(a=>{let b=new URL(a);return["https:","http:"].includes(b.protocol)&&!b.username&&!b.password&&!b.search&&!b.hash},"插件源必须是 HTTP 或 HTTPS 仓库地址"),g=d.gM("mode",[d.Ik({mode:d.eu("auto")}).strict(),d.Ik({mode:d.eu("local")}).strict(),d.Ik({mode:d.eu("official")}).strict(),d.Ik({mode:d.eu("domestic")}).strict(),d.Ik({mode:d.eu("custom"),registry:f}).strict()]),h=d.Ik({description:d.Yj().trim().min(1).max(4e3).optional(),readme:d.Yj().trim().min(1).max(1024).optional()}),i=d.Ik({description:d.Yj().optional(),piDesk:d.Ik({i18n:d.g1(d.Yj().min(1).max(35),h).optional()}).passthrough().optional()}).passthrough();function j(a){let b=i.safeParse(a);if(!b.success)return null;let c=b.data.description?.trim();if(!c)return null;let d=Object.fromEntries(Object.entries(b.data.piDesk?.i18n??{}).slice(0,16).flatMap(([a,b])=>b.description?[[a,b.description]]:[]));return Object.keys(d).length?{default:c,translations:d}:c}function k(a){let b=/^npm:((?:@[^/]+\/)?[^@]+)(?:@.+)?$/.exec(a);return b?`npm:${b[1]}`:a.replaceAll("\\","/")}function l(a){return/^npm:((?:@[^/]+\/)?[^@]+)(?:@.+)?$/.exec(a)?.[1]??null}function m(a,b){let c=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/,d=c.exec(a),e=c.exec(b);if(!d||!e)return!1;for(let a=1;a<=3;a++){let b=Number(d[a])-Number(e[a]);if(b)return b>0}if(!d[4]||!e[4])return!d[4]&&!!e[4];let f=d[4].split("."),g=e[4].split(".");for(let a=0;a<Math.max(f.length,g.length);a++){let b=f[a],c=g[a];if(b===c)continue;if(void 0===b||void 0===c)return void 0===c;let d=/^\d+$/.test(b),e=/^\d+$/.test(c);if(d&&e)return Number(b)>Number(c);if(d!==e)return e;return b>c}return!1}},5235:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{El:()=>n,Nx:()=>q,ey:()=>o,ks:()=>p,sv:()=>r,to:()=>l});var e=c(73024),f=c(76760),g=c(77598),h=c(75430),i=c(36153),j=c(4287),k=a([h]);h=(k.then?(await k)():k)[0];let q="https://registry.npmjs.org",r="https://mirrors.cloud.tencent.com/npm",s=i.Ik({downloadSource:j.w3.default({mode:"auto"}),disabled:i.YO(i.Yj()).max(2e3).default([]),registries:i.g1(i.Yj(),j.SZ).default({}),updateTags:i.g1(i.Yj(),j.mR).default({})}).strict();function l(a=(0,h.getAgentDir)()){let b=(0,f.join)(a,"pi-desk-plugins.json");return(0,e.existsSync)(b)?s.parse(JSON.parse((0,e.readFileSync)(b,"utf8"))):s.parse({})}function m(a,b){let c=(0,f.join)(a,"pi-desk-plugins.json"),d=s.parse(b(l(a)));(0,e.mkdirSync)((0,f.dirname)(c),{recursive:!0});let h=`${c}.${(0,g.randomUUID)()}.tmp`;try{(0,e.writeFileSync)(h,`${JSON.stringify(d,null,2)}
|
|
2
|
-
`,"utf8"),(0,e.renameSync)(h,c)}finally{(0,e.rmSync)(h,{force:!0})}}function n(a,b,c=(0,h.getAgentDir)()){let d=(0,j.LD)(a);m(c,a=>({...a,disabled:[...a.disabled.filter(a=>a!==d),...b?[]:[d]]}))}function o(a,b=(0,h.getAgentDir)()){let c=l(b).updateTags[(0,j.LD)(a)];if(c)return c;let d=/^npm:(?:@[^/]+\/)?[^@]+@([^@]+)$/.exec(a)?.[1];return d&&!/^v?\d+\./.test(d)&&j.mR.safeParse(d).success?d:"latest"}function p(a,b,c=(0,h.getAgentDir)()){let d=(0,j.LD)(a);m(c,a=>({...a,updateTags:{...a.updateTags,[d]:b}}))}d()}catch(a){d(a)}})},16056:(a,b,c)=>{c.d(b,{P:()=>e});let d=process.argv.includes("--safe-mode")||"1"===process.env.PI_DESK_SAFE_MODE;function e(){return d}},30987:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{n:()=>n});var e=c(51455),f=c(48161),g=c(76760),h=c(4287),i=c(5235),j=a([i]);async function k(a){let b=await (0,e.realpath)(a).catch(()=>(0,g.resolve)(a));return"win32"===process.platform?b.toLowerCase():b}function l(a,b){return/^(npm:|git:|https?:|ssh:|git@)/.test(a)?null:a.startsWith("~/")?(0,g.join)((0,f.homedir)(),a.slice(2)):(0,g.resolve)(b,a)}function m(a,b){let c=(0,g.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,g.isAbsolute)(c)}async function n(a,b,c){let d=new Set((0,i.to)(a).disabled.map(h.LD)),f=new Set;for(let b of d){let c=l(b,a);c&&f.add(await k(c))}for(let c of b.listConfiguredPackages()){if("user"!==c.scope||!c.installedPath)continue;let b=l(c.source,a),e=b&&f.has(await k(b));(d.has((0,h.LD)(c.source))||e)&&f.add(await k(c.installedPath))}if(f.size>0){let d=(0,g.join)(a,"extensions"),h=await (0,e.readdir)(d,{withFileTypes:!0}).catch(a=>{if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return[];throw a}),i=[...b.listConfiguredPackages().filter(a=>"user"===a.scope).flatMap(a=>a.installedPath??[]),...h.filter(a=>!a.name.startsWith(".")&&"node_modules"!==a.name&&(a.isDirectory()||a.isSymbolicLink())).map(a=>(0,g.join)(d,a.name)),...(c.getGlobalSettings().extensions??[]).filter(a=>!/^[!+-]|[?*{}]/.test(a)).flatMap(b=>l(b,a)??[])],j=[];for(let a of i)await (0,e.stat)(a).then(a=>a.isDirectory(),()=>!1)&&j.push(await k(a));for(let a of(j.sort((a,b)=>b.length-a.length),[...f])){if(!await (0,e.stat)(a).then(a=>a.isFile(),()=>!1))continue;let b=j.find(b=>m(b,a));b&&f.add(b)}}let j=new Map;return async(a,b,c)=>{if(c&&d.has((0,h.LD)(a)))return!0;if(!b||b.startsWith("builtin:")||0===f.size)return!1;let e=j.get(b);e||(e=k(b),j.set(b,e));let g=await e;return[...f].some(a=>m(a,g))}}i=(j.then?(await j)():j)[0],d()}catch(a){d(a)}})},36361:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.r(b),c.d(b,{L4PiGlobalPluginRuntime:()=>o,L4PiPluginOwnerRuntime:()=>g.K,L4PiPluginRuntimeBusyError:()=>g.y,disposeL4PiGlobalPluginRuntime:()=>n,getL4PiGlobalPluginRuntime:()=>m});var e=c(67841),f=c(75430),g=c(99667),h=c(16056),i=c(60719),j=c(66024),k=c(44493),l=a([e,f,g,i,k]);[e,f,g,i,k]=l.then?(await l)():l;class o extends g.K{constructor(a=process.cwd(),b=(0,f.getAgentDir)()){const c=new j.N,d=async()=>(0,h.P)()?{sources:[],errors:[]}:(0,i.o)(a,b,{DefaultPackageManager:f.DefaultPackageManager,SettingsManager:f.SettingsManager});super(async()=>{let a=await d();for(let b of a.errors)console.warn("[Pi Desk][GlobalPluginRuntime] 插件来源发现诊断",{message:b});return await c.initialize(a),a.sources.flatMap(a=>a.enabled&&!a.error&&a.piDeskRoot?[{source:a.source,installedPath:a.piDeskRoot}]:[])},(0,e.J)()),this.sourceChanges=c,this.discover=d}async scanSourceChanges(a){return await this.initialize(),this.sourceChanges.scan(await this.discover(),a)}async applySourceChange(a){let[b]=await this.scanSourceChanges([a.source]);if(!b||b.fingerprint!==a.fingerprint||b.current?.enabled&&b.current.error)throw Error(b?.current?.error??"插件源码在预检后发生变化,请重新加载");a.previous?.piDeskRoot||a.current?.piDeskRoot?await this.replaceSource(a.source,a.current?.enabled?a.current.piDeskRoot:null):(0,k.N)(),this.sourceChanges.commit(a)}}function m(){return globalThis.__piDeskGlobalPluginRuntime||(globalThis.__piDeskGlobalPluginRuntime=new o),globalThis.__piDeskGlobalPluginRuntime}async function n(){let a=globalThis.__piDeskGlobalPluginRuntime;globalThis.__piDeskGlobalPluginRuntime=void 0,await a?.dispose()}d()}catch(a){d(a)}})},44493:(a,b,c)=>{c.a(a,async(a,d)=>{try{let n;c.d(b,{G:()=>m,N:()=>k});var e=c(93736),f=c(73024),g=c(76760),h=a([e]);e=(h.then?(await h)():h)[0];let o=(0,g.join)(process.cwd(),"package.json"),{createRequire:p}=process.getBuiltinModule("module"),q=(0,e.createJiti)((0,g.join)(process.env.PI_DESK_PI_PACKAGE_DIR??process.cwd(),"package.json")),r=new Map,s=0;function i(a){let b=r.get(a);return b&&(r.delete(a),r.set(a,b)),b}function j(a,b){let c=r.get(a);if(c&&(r.delete(a),s-=c.bytes),!(b.bytes>0x2000000)){for(;r.size>=512||s+b.bytes>0x2000000;){let a=r.entries().next().value;r.delete(a[0]),s-=a[1].bytes}r.set(a,b),s+=b.bytes}}function k(){r.size>0&&console.info("[Pi Desk][PluginResources] 已清除插件代码缓存",{fileCount:r.size,bytes:s}),r.clear(),s=0}async function l(){let[a,b,c,d,f,h,k,l,m]=await Promise.all([q.import("@earendil-works/pi-coding-agent"),q.import("@earendil-works/pi-agent-core"),q.import("@earendil-works/pi-tui"),q.import("@earendil-works/pi-ai/compat"),q.import("@earendil-works/pi-ai/oauth"),q.import("@earendil-works/pi-ai/providers/all"),q.import("typebox"),q.import("typebox/compile"),q.import("typebox/value")]),n=(0,e.createJiti)(o,{moduleCache:!1,fsCache:!1,tryNative:!1,virtualModules:{"@earendil-works/pi-coding-agent":a,"@earendil-works/pi-agent-core":b,"@earendil-works/pi-tui":c,"@earendil-works/pi-ai/providers/all":h,"@earendil-works/pi-ai/compat":d,"@earendil-works/pi-ai/oauth":f,"@earendil-works/pi-ai":d,"@mariozechner/pi-coding-agent":a,"@mariozechner/pi-agent-core":b,"@mariozechner/pi-tui":c,"@mariozechner/pi-ai/providers/all":h,"@mariozechner/pi-ai/compat":d,"@mariozechner/pi-ai/oauth":f,"@mariozechner/pi-ai":d,typebox:k,"typebox/compile":l,"typebox/value":m,"@sinclair/typebox":k,"@sinclair/typebox/compile":l,"@sinclair/typebox/value":m}}),p=n.options.transform;return n.options.transform=a=>(function(a,b){if(!a.filename)return b(a);let c=(0,g.resolve)(a.filename),d=i(c),e=d?.source===a.source?d:void 0,f=!0===a.async,h=e?.transforms.get(f);if(h)return h;let k=a.source,l=b(a);return l.error||l.code.includes("__JITI_ERROR__")||j(c,{source:k,transforms:new Map(e?.transforms).set(f,l),bytes:(e?.bytes??Buffer.byteLength(k))+Buffer.byteLength(l.code)}),l})(a,p),n}async function m(a,b=(0,g.dirname)(a)){let c=await (n??=l()),d=p(o).cache,e=(0,g.resolve)(b);for(let a of Object.keys(d)){let b=(0,g.relative)(e,a);b.startsWith("..")||(0,g.isAbsolute)(b)||b.split(/[\\/]/).includes("node_modules")||delete d[a]}try{let b,d=(0,g.resolve)(a),e=c.evalModule((b=(0,f.readFileSync)(d,"utf8"),i(d)?.source!==b&&j(d,{source:b,transforms:new Map,bytes:Buffer.byteLength(b)}),b),{filename:d,async:!1});return{default:e?.default??e}}catch(a){if(k(),a instanceof Error&&/await is only valid|top.level await|ERR_REQUIRE_ASYNC_MODULE/i.test(a.message))throw Error("Pi Desk Node Entry 不支持模块顶层 await,请将异步初始化放入 async setup()",{cause:a});throw a}}d()}catch(a){d(a)}})},59214:(a,b,c)=>{c.d(b,{J:()=>f,a:()=>e});var d=c(36153);let e=d.Ik({locale:d.k5(["zh-CN","en"]),timeZone:d.Yj().trim().min(1).max(100).refine(a=>{try{return new Intl.DateTimeFormat("en",{timeZone:a}),!0}catch{return!1}},"无效的 IANA 时区")}).strict().readonly(),f=d.Ik({region:e}).strict().readonly()},60719:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{W:()=>p,o:()=>o});var e=c(51455),f=c(48161),g=c(76760),h=c(4287),i=c(30987),j=a([i]);function k(a,b){let c=(0,g.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,g.isAbsolute)(c)}async function l(a){try{return await (0,e.realpath)(a)}catch{return(0,g.resolve)(a)}}function m(a){return"win32"===process.platform?a.toLowerCase():a}async function n(a){try{if((await (0,e.stat)(a)).isFile())return{version:null,description:null,hasNodeEntry:!1,error:null};let b=JSON.parse(await (0,e.readFile)((0,g.join)(a,"package.json"),"utf8"));if(!b||"object"!=typeof b||Array.isArray(b))throw Error("package.json 必须是对象");return{version:"string"==typeof b.version?b.version:null,description:(0,h._C)(b),hasNodeEntry:b.piDesk?.entry!==void 0||b.piDesk?.global!==void 0,hasNativeEntries:Array.isArray(b.pi?.extensions)&&b.pi.extensions.length>0,error:null}}catch(a){if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return{version:null,description:null,hasNodeEntry:!1,error:null};return{version:null,description:null,hasNodeEntry:!1,error:a instanceof Error?a.message:String(a)}}}async function o(a,b,c){let d=c.SettingsManager.create(a,b,{projectTrusted:!1}),h=new c.DefaultPackageManager({cwd:a,agentDir:b,settingsManager:d}),j=d.drainErrors().map(({error:a})=>a.message),o=new Map,p=new Map;for(let a of h.listConfiguredPackages()){if("user"!==a.scope)continue;let b=a.installedPath?await l(a.installedPath):null,c=b?await n(b):null,d=b?p.get(m(b)):void 0;b&&!d&&p.set(m(b),a.source),o.set(a.source,{source:a.source,kind:"package",path:b,nativePaths:[],hasPiResources:!0,piDeskRoot:b&&c?.hasNodeEntry&&!d?b:null,version:c?.version??null,description:c?.description??null,enabled:!0,error:d?`此目录已由 ${d} 声明,不能重复加载`:b?c?.error??null:"插件包未安装或安装目录不存在"})}let q=(0,g.join)(b,"extensions"),r=new Set;try{for(let a of(await (0,e.readdir)(q,{withFileTypes:!0})))if(!a.name.startsWith(".")&&"node_modules"!==a.name&&(a.isDirectory()||a.isSymbolicLink()))try{let b=await l((0,g.join)(q,a.name));(await (0,e.stat)(b)).isDirectory()&&r.add(b)}catch(b){j.push(`${a.name}: ${b instanceof Error?b.message:String(b)}`)}}catch(a){a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code||j.push(a instanceof Error?a.message:String(a))}for(let a of d.getGlobalSettings().extensions??[]){if(/^[!+-]|[?*{}]/.test(a))continue;let c=await l(a.startsWith("~/")?(0,g.join)((0,f.homedir)(),a.slice(2)):(0,g.resolve)(b,a));try{(await (0,e.stat)(c)).isDirectory()&&r.add(c)}catch{}}let s=[...r].sort((a,b)=>b.length-a.length);try{let a=await h.resolve(async()=>"skip");for(let a of o.values())a.hasPiResources=!1;for(let b of[...a.extensions,...a.skills,...a.prompts,...a.themes])if(b.enabled&&"user"===b.metadata.scope&&"package"===b.metadata.origin){let a=o.get(b.metadata.source);a&&(a.hasPiResources=!0)}for(let b of a.extensions){if("user"!==b.metadata.scope)continue;let a=await l(b.path);if("package"===b.metadata.origin){let c=o.get(b.metadata.source);c&&b.enabled&&!c.nativePaths.includes(a)&&c.nativePaths.push(a);continue}let c=s.find(b=>k(b,a))??a,d=[...p].find(([b])=>k(b,m(a)));if(d){let c=o.get(d[1]);b.enabled&&c&&!c.nativePaths.includes(a)&&c.nativePaths.push(a),j.push(`扩展入口 ${a} 与已配置包 ${d[1]} 重复,保留包来源`);continue}let e=o.get(c);e||(e={source:c,kind:"extension",path:c,nativePaths:[],piDeskRoot:null,version:null,description:null,enabled:!1,error:null},o.set(c,e)),b.enabled&&(e.enabled=!0,e.nativePaths.includes(a)||e.nativePaths.push(a))}}catch(a){j.push(a instanceof Error?a.message:String(a))}for(let a of s){if([...p.keys()].some(b=>k(b,m(a))))continue;let b=await n(a),c=o.get(a);if(!c&&!b.hasNodeEntry&&!b.error)continue;let d=(await Promise.all(["index.ts","index.js"].map(b=>(0,e.stat)((0,g.join)(a,b)).then(a=>a.isFile(),()=>!1)))).some(Boolean),f=c??{source:a,kind:"extension",path:a,nativePaths:[],piDeskRoot:null,version:null,description:null,enabled:!b.hasNativeEntries&&!d,error:null};f.version=b.version,f.description=b.description,f.error=b.error,b.hasNodeEntry&&f.enabled&&(f.piDeskRoot=a),o.set(a,f)}let t=await (0,i.n)(b,h,d);for(let a of o.values())await t(a.source,a.path,"package"===a.kind)&&(a.enabled=!1);return{sources:[...o.values()].sort((a,b)=>a.source.localeCompare(b.source)),errors:j}}async function p(a){if(!a.path)return null;try{return(await (0,e.stat)(a.path)).isFile()?(0,g.dirname)(a.path):a.path}catch{return null}}i=(j.then?(await j)():j)[0],d()}catch(a){d(a)}})},63603:(a,b,c)=>{c.d(b,{Qg:()=>m,RC:()=>p,a4:()=>k,dO:()=>j,j0:()=>n});var d=c(36153);let e=d.Yj().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=d.Yj().trim().min(1).max(256),g=d.Ik({allow:d.YO(f).max(5e3).optional(),deny:d.YO(f).max(5e3).optional()}).strict(),h=d.Ik({value:d.Yj().trim().min(1).max(256),label:d.Yj().trim().min(1).max(120).optional(),description:d.Yj().trim().max(1e3).optional()}).strict(),i=d.Ik({label:d.Yj().trim().min(1).max(120),options:d.YO(h).max(5e3)}).strict(),j=d.g1(e,i),k=d.Yj().min(1).max(64),l=d.Ik({name:d.Yj().trim().min(1).max(64),tools:g.optional(),skills:g.optional(),plugins:d.g1(e,d.g1(e,g)).optional()}).strict(),m=d.g1(k,l).refine(a=>Object.keys(a).length<=100,"最多保存 100 个能力模式").refine(a=>new Set(Object.values(a).map(a=>a.name)).size===Object.keys(a).length,"模式名称不能重复"),n=d.g1(k,l.shape.name);function o(a,b){let c=0,d=0,e=-1,f=0;for(;d<b.length;)if("*"===a[c])e=c++,f=d;else if(a[c]===b[d])c+=1,d+=1;else{if(!(e>=0))return!1;c=e+1,d=++f}for(;"*"===a[c];)c+=1;return c===a.length}function p(a,b){return(a?.allow===void 0||a.allow.some(a=>o(a,b)))&&!a?.deny?.some(a=>o(a,b))}d.Ik({tools:d.YO(h),skills:d.YO(h),plugins:d.g1(e,j)}).strict(),d.Ik({tools:g,skills:g,capabilities:d.g1(e,g)}).strict()},66024:(a,b,c)=>{c.d(b,{N:()=>l});var d=c(77598),e=c(51455),f=c(76760);let g=new Set([".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs",".json",".md",".css",".yaml",".yml",".toml",".wasm",".node"]),h=new Set(["node_modules","temp","logs","coverage"]);class i extends Error{constructor(a){super(`插件来源不存在:${a}`),this.source=a,this.name="L4PiPluginSourceNotFoundError"}}async function j(a){let b=(0,d.createHash)("sha256").update(JSON.stringify({path:a.path,enabled:a.enabled,nativePaths:[...a.nativePaths].sort(),piDeskRoot:a.piDeskRoot,hasPiResources:a.hasPiResources}));if(!a.path||a.error||!a.enabled)return b.update(a.error??"").digest("hex");let c=await (0,e.realpath)(a.path),i=0,j=0,k=async(a,d,l)=>{if(++j>8192)throw Error("源码目录条目超过8192项,请使用独立插件目录");let m=await (0,e.realpath)(a),n=(0,f.relative)(c,m);if(n.startsWith("..")||(0,f.isAbsolute)(n))return;let o=await (0,e.stat)(m);if(o.isDirectory()){if(l.has(m))throw Error("源码目录存在符号链接循环");let a=new Set(l).add(m);for(let b of(await (0,e.readdir)(m,{withFileTypes:!0})).sort((a,b)=>a.name.localeCompare(b.name)))b.name.startsWith(".")||h.has(b.name)||await k((0,f.join)(m,b.name),`${d}/${b.name}`,a)}else if(o.isFile()&&(""===d||g.has((0,f.extname)(d)))){if(o.size>0x1000000||i+o.size>0x4000000)throw Error("源码指纹内容超过容量上限");let a=await (0,e.readFile)(m),c=await (0,e.stat)(m);if(c.size!==o.size||c.mtimeMs!==o.mtimeMs||a.length!==o.size)throw Error("插件源码正在变化,请保存或构建完成后重新加载");i+=a.length,b.update(d).update("\0").update(a).update("\0")}};return await k(c,"",new Set),b.digest("hex")}async function k(a){try{return{source:a,fingerprint:await j(a)}}catch(c){let b={...a,error:c instanceof Error?c.message:String(c)};return{source:b,fingerprint:`failed:${b.error}`}}}class l{async initialize(a){for(let b of(this.applied.clear(),a.sources))this.applied.set(b.source,await k(b))}async scan(a,b){let c=new Map(a.sources.map(a=>[a.source,a])),d=b?[...new Set(b)]:[...new Set([...this.applied.keys(),...c.keys()])],e=[];for(let f of d){let d=this.applied.get(f),g=c.get(f);if(!d&&!g)throw new i(f);if(!g&&a.errors.length>0){if(b)throw Error(`来源发现不完整,不能确认已删除:${f}`);continue}let h=g?await k(g):null;(b||d?.fingerprint!==h?.fingerprint)&&e.push({source:f,previous:d?.source??null,current:h?.source??null,fingerprint:h?.fingerprint??null})}return e}commit(a){a.current&&null!==a.fingerprint?this.applied.set(a.source,{source:a.current,fingerprint:a.fingerprint}):this.applied.delete(a.source)}constructor(){this.applied=new Map}}},67841:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{J:()=>l});var e=c(77598),f=c(73024),g=c(76760),h=c(75430),i=c(59214),j=a([h]);function k(){let a=Intl.DateTimeFormat().resolvedOptions();return i.J.parse({region:{locale:a.locale.toLowerCase().startsWith("zh")?"zh-CN":"en",timeZone:a.timeZone||"UTC"}})}h=(j.then?(await j)():j)[0];class m{constructor(a=(0,g.join)((0,h.getAgentDir)(),"pi-desk-settings.json"),b=k){this.path=a,this.defaults=b,this.snapshot=null,this.listeners=new Set,this.tail=Promise.resolve()}getSnapshot(){if(!this.snapshot)if((0,f.existsSync)(this.path))this.snapshot=i.J.parse(JSON.parse((0,f.readFileSync)(this.path,"utf8")));else{let a=i.J.parse(this.defaults());this.save(a),this.snapshot=a}return this.snapshot}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}update(a){let b=this.tail.then(()=>{let b=this.getSnapshot(),c=i.J.parse({region:{...b.region,...a}});if(JSON.stringify(b)!==JSON.stringify(c))for(let a of(this.save(c),this.snapshot=c,console.info("[Pi Desk][Settings] 共享地区设置已保存",c.region),this.listeners))try{a()}catch(a){console.error("[Pi Desk][Settings] 设置订阅回调失败",{message:a instanceof Error?a.message:String(a)})}});return this.tail=b.catch(()=>void 0),b}save(a){(0,f.mkdirSync)((0,g.dirname)(this.path),{recursive:!0});let b=`${this.path}.${process.pid}.${(0,e.randomUUID)()}.tmp`;try{(0,f.writeFileSync)(b,`${JSON.stringify(a,null,2)}
|
|
3
|
-
`,"utf8"),(0,f.renameSync)(b,this.path)}finally{(0,f.existsSync)(b)&&(0,f.unlinkSync)(b)}}}function l(){return globalThis.__piDeskHostSettingsStore??=new m}d()}catch(a){d(a)}})},73630:(a,b,c)=>{c.d(b,{f:()=>h});var d=c(77598),e=c(51455),f=c(76760);function g(a,b){let c=(0,f.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,f.isAbsolute)(c)}async function h(a){if("entry.js"!==(0,f.basename)(a))throw Error("Browser Entry 必须命名为 entry.js");let b=await (0,e.realpath)((0,f.dirname)(a)),c=new Map,h=0,i=0,j=[],k=async(a,l,m)=>{let n=await (0,e.realpath)(a);if(!g(b,n))return;if(m.has(n))throw Error("Browser 模块目录存在符号链接循环");let o=new Set(m).add(n);for(let a of(await (0,e.readdir)(n,{withFileTypes:!0})).sort((a,b)=>a.name.localeCompare(b.name))){if(++i>4096)throw Error("Browser 模块目录条目超过上限");if(a.name.startsWith(".")||"node_modules"===a.name)continue;let m=(0,f.join)(n,a.name),p=await (0,e.realpath)(m);if(!g(b,p))continue;let q=await (0,e.stat)(p),r=l?`${l}/${a.name}`:a.name;if(q.isDirectory()){await k(p,r,o);continue}if(!q.isFile()||!a.name.endsWith(".js"))continue;if("entry.js"===r&&"entry.js"!==(0,f.basename)(p))throw Error("Browser Entry 符号链接必须指向 entry.js");if(c.size>=2048||q.size>0x1000000||h+q.size>0x2000000)throw Error("Browser 模块快照超过数量或容量上限");let s=await (0,e.readFile)(p),t=await (0,e.stat)(p);if(s.length!==q.size||t.size!==q.size||t.mtimeMs!==q.mtimeMs)throw Error("Browser 模块在读取时发生变化,请构建完成后重新加载");h+=s.length,j.push({path:p,size:t.size,mtimeMs:t.mtimeMs,ino:t.ino}),c.set(r,{content:s,etag:`"${(0,d.createHash)("sha256").update(s).digest("hex")}"`})}};for(let a of(await k(b,"",new Set),j)){let b=await (0,e.stat)(a.path);if(b.size!==a.size||b.mtimeMs!==a.mtimeMs||b.ino!==a.ino)throw Error("Browser 模块组在读取时发生变化,请构建完成后重新加载")}if(!c.has("entry.js"))throw Error("Browser Entry 模块缺失或越出专用目录");return{size:h,modules:c}}},90733:(a,b,c)=>{c.d(b,{$m:()=>g,FX:()=>h,Pu:()=>m,QK:()=>i,Tk:()=>k,nJ:()=>j,qs:()=>l});var d=c(36153);let e=d.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=d.g1(d.Yj(),d.Pq());function g(a,b){return`${a}\u0000${b}`}function h(a){return e.parse(a)}function i(a){return e.parse(a)}function j(a,b){let c=f.parse(a);if(Buffer.byteLength(JSON.stringify(c),"utf8")>2097152)throw new m(b);return c}class k extends Error{constructor(a,b){super(`Plugin method was not found: ${a}/${b}`),this.name="L4PiPluginMethodNotFoundError"}}class l extends Error{constructor(a,b){super(`Plugin method is already registered: ${a}/${b}`),this.name="L4PiPluginMethodConflictError"}}class m extends Error{constructor(a){super(`Plugin method ${a} exceeds 2MB`),this.direction=a,this.name="L4PiPluginMethodPayloadTooLargeError"}}},99667:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{K:()=>z,y:()=>w});var e=c(77598),f=c(58500),g=c(51455),h=c(76760),i=c(36153),j=c(63603),k=c(44493),l=c(73630),m=c(90733),n=a([k]);k=(n.then?(await n)():n)[0];let r=i.g1(i.Yj(),i.Pq()),s=i.Ik({workId:i.Yj().trim().min(1),sessionId:i.Yj().trim().min(1),branchId:i.Yj().trim().min(1)}).strict(),t=i.Ik({source:s,cwd:i.Yj().trim().min(1),status:i.k5(["main_running","background_running","completed","idle"])}).strict(),u=i.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),v=i.ai().int().safe();class w extends Error{constructor(){super("插件运行时仍有调用正在执行"),this.name="L4PiPluginRuntimeBusyError"}}class x extends Error{constructor(a,b){super(b instanceof Error?b.message:String(b),{cause:b}),this.phase=a,this.name="L4PiPluginPhaseError"}}class y extends x{constructor(a,b){super(a,Error("插件加载超时,已停止本次加载")),this.execution=b,this.name="L4PiPluginLoadTimeoutError"}}function o(a,b,c){if("string"!=typeof b||!b.trim())throw Error(`package.json.${c} must be a non-empty string`);let d=(0,h.resolve)(a,b),e=(0,h.relative)(a,d);if(e.startsWith("..")||(0,h.isAbsolute)(e))throw Error(`package.json.${c} must stay inside the package root`);return d}function p(a){return a instanceof Error&&a.message?a.message:String(a)}async function q(a){let b=null,c=Promise.resolve().then(a.execute);a.owner.pendingCleanup.add(c);let d=()=>{a.owner.pendingCleanup.delete(c)};c.then(d,d);try{if(await Promise.race([c.then(()=>!0),new Promise(a=>{b=setTimeout(()=>a(!1),1500)})]))return;throw a.onTimeout?.(),Error(`插件 ${a.phase} 超时,关闭结果未确认`)}catch(b){console.warn("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 生命周期执行失败",{source:a.owner.source,packageName:a.owner.packageName,phase:a.phase,timeoutMs:1500,message:p(b)})}finally{b&&clearTimeout(b)}}class z{constructor(a,b){this.packageProvider=a,this.hostSettings=b,this.methods=new Map,this.pluginOwners=new Map,this.browserEntries=new Map,this.declarations=new Map,this.capabilityLoaders=new Map,this.owners=[],this.loadingOwners=new Set,this.changeListeners=new Set,this.changingSources=new Set,this.maintainingSources=new Set,this.lifetime=new AbortController,this.packageDiagnostics=new Map,this.recoveries=new Map,this.initializePromise=null,this.initialized=!1,this.disposed=!1,this.acceptingCalls=!0,this.loadError=null,this.workSessionProvider=null,this.pushSender=null,this.appRuntimeSink=null}initialize(){return this.disposed?Promise.reject(Error("Global plugin runtime has been disposed")):this.initialized?Promise.resolve():(this.initializePromise||(this.initializePromise=this.loadConfiguredPackages().catch(a=>{this.loadError=p(a),console.error("[Pi Desk][GlobalPluginRuntime] 读取插件配置失败,核心应用继续启动",{errorName:a instanceof Error?a.name:"UnknownError",message:this.loadError})}).finally(()=>{this.initializePromise=null,this.initialized=!0,this.publishChanges()})),this.initializePromise)}subscribeChanges(a){return this.changeListeners.add(a),()=>this.changeListeners.delete(a)}publishChanges(){if(!this.disposed)for(let a of this.changeListeners)try{a()}catch(a){console.warn("[Pi Desk][GlobalPluginRuntime] 状态监听失败",{message:p(a)})}}async withSourceIdle(a,b,c,d){let e,g=AbortSignal.any([c,this.lifetime.signal]);g.throwIfAborted();let h=new Promise((a,b)=>{e=()=>b(g.reason),g.addEventListener("abort",e,{once:!0})});try{await Promise.race([this.initialize(),h])}finally{g.removeEventListener("abort",e)}if(g.throwIfAborted(),!this.acceptingCalls||this.changingSources.has(a)||this.maintainingSources.has(a))throw new w;this.cancelRecovery(a),this.maintainingSources.add(a);try{for(;this.owners.some(b=>b.source===a&&b.activeCalls.size>0);)d(`插件 ${a} 仍有调用正在执行`),await (0,f.setTimeout)(250,void 0,{signal:g});return g.throwIfAborted(),await b()}finally{this.maintainingSources.delete(a)}}async replaceSource(a,b){if(await this.initialize(),this.disposed||!this.acceptingCalls||this.changingSources.has(a))throw new w;this.cancelRecovery(a);let c=this.owners.find(b=>b.source===a);this.changingSources.add(a);try{if(c&&this.releaseOwner(c),this.disposed)throw Error("Global plugin runtime has been disposed");if((0,k.N)(),this.packageDiagnostics.delete(a),null!==b){if(await this.loadPackage(a,b),this.disposed)throw Error("Global plugin runtime has been disposed");let c=this.packageDiagnostics.get(a);if(c?.status==="failed")throw Error(c.error?.message??"插件加载失败")}}finally{this.changingSources.delete(a),this.publishChanges()}}ownerPublished(a){return a.active&&!a.draining&&!this.changingSources.has(a.source)&&this.owners.includes(a)}readDiagnostics(){return{packages:[...this.packageDiagnostics.values()].sort((a,b)=>a.source.localeCompare(b.source)).map(a=>structuredClone(a)),loadError:this.loadError}}readCapabilityRegistrations(){return[...this.owners].filter(a=>this.ownerPublished(a)).sort((a,b)=>a.source.localeCompare(b.source)).map(a=>({source:a.source,methods:[...this.methods.values()].filter(b=>b.owner===a).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.method.localeCompare(b.method):c}).map(({pluginName:a,method:b})=>({pluginName:a,method:b})),browserEntries:[...this.browserEntries.values()].filter(b=>b.owner===a).sort((a,b)=>a.pluginName.localeCompare(b.pluginName)).map(({pluginName:a})=>({pluginName:a})),messageDeclarations:[...this.declarations.values()].filter(b=>b.owner===a).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.declarationName.localeCompare(b.declarationName):c}).map(({pluginName:a,declarationName:b,declaration:c})=>({pluginName:a,declarationName:b,priority:c.priority}))}))}async prepareReload(){if(await this.initialize(),this.disposed)throw Error("Global plugin runtime has been disposed");if(!this.acceptingCalls||this.changingSources.size>0||this.maintainingSources.size>0||this.owners.some(a=>a.activeCalls.size>0))throw new w;for(let a of(this.acceptingCalls=!1,this.recoveries.keys()))this.cancelRecovery(a);for(let a of this.owners)a.draining=!0;await Promise.all([...this.owners].reverse().map(async a=>{let b=a.beforeReload;if(!b)return;a.beforeReload=null;let c=new AbortController;await q({owner:a,phase:"beforeReload",execute:()=>b({signal:c.signal}),onTimeout:()=>c.abort()})}))}bindWorkSessionProvider(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.workSessionProvider=a,()=>{this.workSessionProvider===a&&(this.workSessionProvider=null)}}bindPushSender(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.pushSender=a,()=>{this.pushSender===a&&(this.pushSender=null)}}bindAppRuntimeSink(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.appRuntimeSink=a,()=>{this.appRuntimeSink===a&&(this.appRuntimeSink=null)}}async runOwnedCall(a,b){let c;if(this.ensureOwnerActive(a),this.maintainingSources.has(a.source))throw new w;let d=new AbortController,e=new Promise((a,b)=>{c=b}),f=()=>{c(Error("Pi Desk Plugin owner is no longer active"))};d.signal.addEventListener("abort",f,{once:!0}),a.activeCalls.add(d);try{let c=await Promise.race([Promise.resolve().then(()=>(this.ensureOwnerActive(a),b(d.signal))),e]);return this.ensureOwnerActive(a),c}finally{a.activeCalls.delete(d),d.signal.removeEventListener("abort",f)}}async invoke(a,b,c){if(await this.initialize(),this.disposed)throw Error("Global plugin runtime has been disposed");if(!this.acceptingCalls)throw new w;let d=(0,m.FX)(a),e=(0,m.QK)(b),f=this.methods.get((0,m.$m)(d,e));if(!f)throw new m.Tk(d,e);if(!this.ownerPublished(f.owner)||this.changingSources.has(f.owner.source))throw new w;let g=(0,m.nJ)(c,"input");return this.runOwnedCall(f.owner,async a=>{let b=await f.execute(g,{signal:a});return(0,m.nJ)(b,"output")})}async listCapabilityDeclarations(){if(await this.initialize(),this.disposed||!this.acceptingCalls)throw new w;let a=await Promise.all([...this.capabilityLoaders].filter(([,a])=>this.ownerPublished(a.owner)&&!this.changingSources.has(a.owner.source)).map(async([a,b])=>{try{return await this.runOwnedCall(b.owner,async c=>{let d=await b.load({signal:c});if(this.capabilityLoaders.get(a)!==b)throw Error(`能力声明已被替换:${a}`);return[a,j.dO.parse(d)]})}catch(b){throw Error(`读取 ${a} 能力选项失败:${p(b)}`,{cause:b})}}));return Object.fromEntries(a)}async listBrowserEntries(){return await this.initialize(),[...this.browserEntries.values()].filter(a=>this.ownerPublished(a.owner)).sort((a,b)=>a.pluginName.localeCompare(b.pluginName)).flatMap(({pluginName:a,entryPath:b,resourceKey:c,snapshot:d})=>d?[{pluginName:a,entryPath:b,resourceKey:c,snapshot:d}]:[])}async listMessageDeclarations(){return await this.initialize(),this.readMessageDeclarations()}readMessageDeclarations(){return[...this.declarations.values()].filter(a=>this.ownerPublished(a.owner)).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.declarationName.localeCompare(b.declarationName):c}).map(({pluginName:a,declarationName:b,declaration:c})=>({pluginName:a,declarationName:b,declaration:c}))}async dispose(){if(this.disposed)return;for(let a of(this.disposed=!0,this.lifetime.abort(),this.recoveries.keys()))this.cancelRecovery(a);this.acceptingCalls=!1,this.changeListeners.clear(),this.workSessionProvider=null,this.pushSender=null;let a=[...new Set([...this.owners,...this.loadingOwners])].reverse();this.owners.length=0,this.loadingOwners.clear(),await Promise.all(a.map(a=>this.releaseOwner(a))),this.methods.clear(),this.pluginOwners.clear(),this.browserEntries.clear(),this.declarations.clear(),this.capabilityLoaders.clear(),this.appRuntimeSink=null}async loadConfiguredPackages(){for(let a of(this.loadError=null,this.packageDiagnostics.clear(),await this.packageProvider())){if(this.disposed)return;let b=await this.loadPackage(a.source,a.installedPath);b&&!this.disposed&&this.recoveries.set(a.source,{installedPath:a.installedPath,settled:b.execution,controller:new AbortController})}for(let[a,b]of this.recoveries)this.recoverSource(a,b)}cancelRecovery(a){let b=this.recoveries.get(a);this.recoveries.delete(a),b?.controller.abort()}async recoverSource(a,b){let c,d=b.controller.signal,e=new Promise((a,b)=>{c=()=>b(d.reason),d.addEventListener("abort",c,{once:!0})});try{await Promise.race([b.settled,e]),d.throwIfAborted(),console.info("[Pi Desk][GlobalPluginRuntime] 插件加载超时,稍后自动重试一次",{source:a,delayMs:1e4}),await (0,f.setTimeout)(1e4,void 0,{signal:d}),d.throwIfAborted(),this.recoveries.delete(a),await this.replaceSource(a,b.installedPath),console.info("[Pi Desk][GlobalPluginRuntime] 插件自动重试成功",{source:a})}catch(b){d.aborted||console.warn("[Pi Desk][GlobalPluginRuntime] 插件自动重试失败,不再自动加载",{source:a,message:p(b)})}finally{d.removeEventListener("abort",c),this.recoveries.get(a)===b&&this.recoveries.delete(a)}}async loadOwnerWithinDeadline(a,b,c){let d,e="entry",f=performance.now(),g=()=>{let b=Math.round(performance.now()-f);b<1e3||console.info("[Pi Desk][GlobalPluginRuntime] 插件加载阶段耗时",{source:a.source,packageName:a.packageName,phase:e,durationMs:b})},h=a=>{g(),e=a,f=performance.now()},i=(async()=>{let d=()=>h("setup");void 0!==b?await this.loadEntryOwner(a,b,d):await this.loadLegacyOwner(a,c,d),h("resources");try{await this.validateOwnerResources(a)}catch(a){throw new x("resources",a)}this.ensureOwnerActive(a)})();try{await Promise.race([i,new Promise((a,b)=>{d=setTimeout(()=>{b(new y(e,i))},15e3)})])}finally{d&&clearTimeout(d),g()}}async loadPackage(a,b){let c,d=performance.now(),e=(0,h.resolve)(b);try{let a=(0,h.join)(e,"package.json");c=JSON.parse(await (0,g.readFile)(a,"utf8"))}catch(b){return this.packageDiagnostics.set(a,{source:a,packageName:null,version:null,pluginName:null,status:"failed",error:{phase:"package",message:p(b)}}),null}let f=c.piDesk?.entry,i=c.piDesk?.global;if(void 0===f&&void 0===i||this.disposed)return null;let j={source:a,packageName:"string"==typeof c.name?c.name:null,version:"string"==typeof c.version?c.version:null,packageRoot:e,active:!0,draining:!1,pluginNames:new Set,activeCalls:new Set,subscriptions:new Set,pendingCleanup:new Set,beforeReload:null,disposer:null};console.info("[Pi Desk][GlobalPluginRuntime] 开始加载 Pi Desk Plugin",{source:a,packageName:j.packageName}),this.loadingOwners.add(j);try{await this.loadOwnerWithinDeadline(j,f,i),this.owners.push(j),this.recordOwnerDiagnostic(j),console.info("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 已加载",{source:a,packageName:j.packageName,pluginNames:[...j.pluginNames],methodCount:[...this.methods.values()].filter(a=>a.owner===j).length,browserEntryCount:[...this.browserEntries.values()].filter(a=>a.owner===j).length,declarationCount:[...this.declarations.values()].filter(a=>a.owner===j).length,durationMs:Math.round(performance.now()-d)})}catch(f){let b=f instanceof x?f.phase:"entry",c=[...j.pluginNames][0]??null;await this.releaseOwner(j);let e=p(f);if(this.packageDiagnostics.set(a,{source:a,packageName:j.packageName,version:j.version,pluginName:c,status:"failed",error:{phase:b,message:e}}),console.warn("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 加载失败",{source:a,packageName:j.packageName,phase:b,errorName:f instanceof Error?f.name:"UnknownError",message:e,durationMs:Math.round(performance.now()-d)}),f instanceof y)return{execution:f.execution.catch(()=>{}).then(async()=>{await Promise.allSettled([...j.pendingCleanup])})}}finally{this.loadingOwners.delete(j)}return null}async loadEntryOwner(a,b,c){let d=o(a.packageRoot,b,"piDesk.entry");if(!(await (0,g.stat)(d)).isFile())throw Error("Pi Desk Plugin entry is not a file");let e=(await (0,k.G)(d,a.packageRoot)).default;if(!e||"object"!=typeof e||"string"!=typeof e.name||"function"!=typeof e.setup)throw Error("Pi Desk Plugin entry must default-export definePiDeskPlugin(...)");let f=(0,m.FX)(e.name);this.claimPluginName(a,f),c();try{let b=function(a){if(void 0===a)return{beforeReload:null,disposer:null};if("function"==typeof a)return{beforeReload:null,disposer:a};if(!a||"object"!=typeof a)throw Error("Pi Desk Plugin setup must return void, a disposer, or a lifecycle object");if(void 0!==a.beforeReload&&"function"!=typeof a.beforeReload)throw Error("Pi Desk Plugin lifecycle.beforeReload must be a function");if(void 0!==a.dispose&&"function"!=typeof a.dispose)throw Error("Pi Desk Plugin lifecycle.dispose must be a function");return{beforeReload:a.beforeReload??null,disposer:a.dispose??null}}(await e.setup(this.createPiDeskFacade(a,f,a.packageRoot)));if(a.beforeReload=b.beforeReload,a.disposer=b.disposer,!a.active||this.disposed)throw await this.releaseOwner(a),Error("插件初始化完成时 Owner 已失效")}catch(a){throw new x("setup",a)}}async loadLegacyOwner(a,b,c){let d=o(a.packageRoot,b,"piDesk.global");if(!(await (0,g.stat)(d)).isFile())throw Error("Global Plugin entry is not a file");let e=await (0,k.G)(d,a.packageRoot);if("function"!=typeof e.default)throw Error("Global Plugin entry must default-export a factory function");let f=e.default;c();try{let b=await f(this.createLegacyApi(a));if(void 0!==b&&"function"!=typeof b)throw Error("Global Plugin factory must return void or a disposer function");if(a.disposer=b??null,!a.active||this.disposed)throw await this.releaseOwner(a),Error("插件初始化完成时 Owner 已失效")}catch(a){throw new x("setup",a)}}claimPluginName(a,b){this.ensureOwnerActive(a);let c=this.pluginOwners.get(b);if(c&&c!==a)throw Error(`Pi Desk pluginName is already registered: ${b}`);this.pluginOwners.set(b,a),a.pluginNames.add(b)}createLegacyApi(a){return{bindPlugin:b=>{let c=(0,m.FX)(b);return this.claimPluginName(a,c),{name:c,registerMethod:(b,d)=>this.registerMethod(a,c,b,d)}}}}createPiDeskFacade(a,b,c){return{name:b,host:{settings:{getSnapshot:()=>{if(this.ensureOwnerActive(a),!this.hostSettings)throw Error("宿主共享设置尚未就绪");return this.hostSettings.getSnapshot()},subscribe:b=>{if(this.ensureOwnerActive(a),!this.hostSettings)throw Error("宿主共享设置尚未就绪");let c=this.hostSettings.subscribe(()=>{a.active&&!a.draining&&b()});return a.subscriptions.add(c),()=>{if(a.subscriptions.delete(c))return c()}}},workSessions:{listWorkSessions:async()=>{this.ensureOwnerActive(a);let b=await this.readWorkSessions();return this.ensureOwnerActive(a),b}}},notifications:{publish:c=>(this.ensureOwnerActive(a),this.requireAppRuntimeSink().publishNotification(b,c)),update:(c,d)=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().updateNotification(b,c,d)},delete:c=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().deleteNotification(b,c)}},setState:c=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().setState(b,c)},registerMethod:(c,d)=>this.registerMethod(a,b,c,d),registerBrowserEntry:d=>{if(this.ensureOwnerActive(a),this.browserEntries.has(b))throw Error(`Browser Entry is already registered: ${b}`);let f=o(c,d,"browserEntry"),g={pluginName:b,entryPath:f,resourceKey:(0,e.randomUUID)(),snapshot:null,owner:a};return this.browserEntries.set(b,g),this.registrationDisposer(a,()=>{this.browserEntries.get(b)===g&&this.browserEntries.delete(b)})},declareCapabilities:c=>{if(this.ensureOwnerActive(a),"function"!=typeof c)throw Error("能力声明必须是按需查询函数");if(this.capabilityLoaders.has(b))throw Error(`能力声明已注册:${b}`);let d={load:c,owner:a};return this.capabilityLoaders.set(b,d),this.registrationDisposer(a,()=>{this.capabilityLoaders.get(b)===d&&this.capabilityLoaders.delete(b)})},declareMessage:(c,d)=>this.registerDeclaration(a,b,c,d),pushGlobal:(c,d)=>{a.active&&!a.draining&&this.sendPush(b,{scope:"global"},c,d)},pushSession:(c,d,e)=>{a.active&&!a.draining&&this.sendPush(b,{scope:"session",source:s.parse(c)},d,e)}}}registerMethod(a,b,c,d){this.ensureOwnerActive(a);let e=(0,m.QK)(c),f=(0,m.$m)(b,e);if(this.methods.has(f))throw new m.qs(b,e);let g={pluginName:b,method:e,execute:d,owner:a};return this.methods.set(f,g),this.registrationDisposer(a,()=>{this.methods.get(f)===g&&this.methods.delete(f)})}registerDeclaration(a,b,c,d){var e;this.ensureOwnerActive(a);let f=u.parse(c);if(!d||"object"!=typeof d||"function"!=typeof d.match||"function"!=typeof d.project)throw Error("Message Declaration must provide match and project functions");let g={priority:(e=d.priority,v.parse(e)),match:d.match,project:d.project},h=`${b}\u0000${f}`;if(this.declarations.has(h))throw Error(`Message Declaration is already registered: ${b}/${f}`);let i={pluginName:b,declarationName:f,declaration:g,owner:a};return this.declarations.set(h,i),this.registrationDisposer(a,()=>{this.declarations.get(h)===i&&this.declarations.delete(h)})}registrationDisposer(a,b){let c=!0;return()=>{c&&(c=!1,a.active&&b())}}requireAppRuntimeSink(){if(!this.appRuntimeSink)throw Error("App Runtime sink has not been bound");return this.appRuntimeSink}sendPush(a,b,c,d){if(this.disposed)return;let e=(0,m.QK)(c),f=function(a){let b=r.parse(a);if(Buffer.byteLength(JSON.stringify(b),"utf8")>65536)throw Error("Plugin Push data exceeds 64KB");return b}(d);this.pushSender?.({pluginName:a,target:b,event:e,data:structuredClone(f)})}async readWorkSessions(){if(!this.workSessionProvider||this.disposed)return[];let a=await this.workSessionProvider();return i.YO(t).parse(a).map(a=>structuredClone(a))}async validateOwnerResources(a){for(let b of[...this.browserEntries.values()].filter(b=>b.owner===a)){if(!(await (0,g.stat)(b.entryPath)).isFile())throw Error("Browser Entry resource is not a file");if("entry.js"!==(0,h.basename)(b.entryPath))throw Error("Browser Entry resource file must be named entry.js");let c=await (0,l.f)(b.entryPath);if(this.ensureOwnerActive(a),[...this.browserEntries.values()].reduce((a,b)=>a+(b.snapshot?.size??0),0)+c.size>0x8000000)throw Error("Browser 模块快照总量超过128MB,拒绝加载此插件");b.snapshot=c}}recordOwnerDiagnostic(a){this.packageDiagnostics.set(a.source,{source:a.source,packageName:a.packageName,version:a.version,pluginName:[...a.pluginNames][0]??null,status:"ready",error:null})}ensureOwnerActive(a){if(!a.active||a.draining||this.disposed)throw Error("Pi Desk Plugin owner is no longer active")}async releaseOwner(a){let b=[...a.subscriptions];if(a.subscriptions.clear(),a.active){for(let b of(a.active=!1,a.activeCalls))b.abort();a.activeCalls.clear();let b=this.owners.indexOf(a);for(let[c,d]of(b>=0&&this.owners.splice(b,1),this.methods))d.owner===a&&this.methods.delete(c);for(let[b,c]of this.browserEntries)c.owner===a&&this.browserEntries.delete(b);for(let[b,c]of this.declarations)c.owner===a&&this.declarations.delete(b);for(let[b,c]of this.capabilityLoaders)c.owner===a&&this.capabilityLoaders.delete(b);for(let b of a.pluginNames)if(this.pluginOwners.get(b)===a){this.pluginOwners.delete(b);try{this.appRuntimeSink?.releasePlugin(b)}catch(a){console.warn("[Pi Desk][GlobalPluginRuntime] 清理插件 App Runtime 失败",{pluginName:b,errorName:a instanceof Error?a.name:"UnknownError",message:p(a)})}}a.pluginNames.clear()}let c=a.beforeReload,d=a.disposer;a.beforeReload=null,a.disposer=null;let e=new AbortController;await Promise.all([...b.map(b=>q({owner:a,phase:"dispose",execute:b})),c?q({owner:a,phase:"beforeReload",execute:()=>c({signal:e.signal}),onTimeout:()=>e.abort()}):Promise.resolve(),d?q({owner:a,phase:"dispose",execute:d}):Promise.resolve()])}}d()}catch(a){d(a)}})}};
|
|
2
|
+
`,"utf8"),(0,e.renameSync)(h,c)}finally{(0,e.rmSync)(h,{force:!0})}}function n(a,b,c=(0,h.getAgentDir)()){let d=(0,j.LD)(a);m(c,a=>({...a,disabled:[...a.disabled.filter(a=>a!==d),...b?[]:[d]]}))}function o(a,b=(0,h.getAgentDir)()){let c=l(b).updateTags[(0,j.LD)(a)];if(c)return c;let d=/^npm:(?:@[^/]+\/)?[^@]+@([^@]+)$/.exec(a)?.[1];return d&&!/^v?\d+\./.test(d)&&j.mR.safeParse(d).success?d:"latest"}function p(a,b,c=(0,h.getAgentDir)()){let d=(0,j.LD)(a);m(c,a=>({...a,updateTags:{...a.updateTags,[d]:b}}))}d()}catch(a){d(a)}})},16056:(a,b,c)=>{c.d(b,{P:()=>e});let d=process.argv.includes("--safe-mode")||"1"===process.env.PI_DESK_SAFE_MODE;function e(){return d}},30987:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{n:()=>n});var e=c(51455),f=c(48161),g=c(76760),h=c(4287),i=c(5235),j=a([i]);async function k(a){let b=await (0,e.realpath)(a).catch(()=>(0,g.resolve)(a));return"win32"===process.platform?b.toLowerCase():b}function l(a,b){return/^(npm:|git:|https?:|ssh:|git@)/.test(a)?null:a.startsWith("~/")?(0,g.join)((0,f.homedir)(),a.slice(2)):(0,g.resolve)(b,a)}function m(a,b){let c=(0,g.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,g.isAbsolute)(c)}async function n(a,b,c){let d=new Set((0,i.to)(a).disabled.map(h.LD)),f=new Set;for(let b of d){let c=l(b,a);c&&f.add(await k(c))}for(let c of b.listConfiguredPackages()){if("user"!==c.scope||!c.installedPath)continue;let b=l(c.source,a),e=b&&f.has(await k(b));(d.has((0,h.LD)(c.source))||e)&&f.add(await k(c.installedPath))}if(f.size>0){let d=(0,g.join)(a,"extensions"),h=await (0,e.readdir)(d,{withFileTypes:!0}).catch(a=>{if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return[];throw a}),i=[...b.listConfiguredPackages().filter(a=>"user"===a.scope).flatMap(a=>a.installedPath??[]),...h.filter(a=>!a.name.startsWith(".")&&"node_modules"!==a.name&&(a.isDirectory()||a.isSymbolicLink())).map(a=>(0,g.join)(d,a.name)),...(c.getGlobalSettings().extensions??[]).filter(a=>!/^[!+-]|[?*{}]/.test(a)).flatMap(b=>l(b,a)??[])],j=[];for(let a of i)await (0,e.stat)(a).then(a=>a.isDirectory(),()=>!1)&&j.push(await k(a));for(let a of(j.sort((a,b)=>b.length-a.length),[...f])){if(!await (0,e.stat)(a).then(a=>a.isFile(),()=>!1))continue;let b=j.find(b=>m(b,a));b&&f.add(b)}}let j=new Map;return async(a,b,c)=>{if(c&&d.has((0,h.LD)(a)))return!0;if(!b||b.startsWith("builtin:")||0===f.size)return!1;let e=j.get(b);e||(e=k(b),j.set(b,e));let g=await e;return[...f].some(a=>m(a,g))}}i=(j.then?(await j)():j)[0],d()}catch(a){d(a)}})},36361:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.r(b),c.d(b,{L4PiGlobalPluginRuntime:()=>o,L4PiPluginOwnerRuntime:()=>g.K,L4PiPluginRuntimeBusyError:()=>g.y,disposeL4PiGlobalPluginRuntime:()=>n,getL4PiGlobalPluginRuntime:()=>m});var e=c(67841),f=c(75430),g=c(99667),h=c(16056),i=c(60719),j=c(66024),k=c(44493),l=a([e,f,g,i,k]);[e,f,g,i,k]=l.then?(await l)():l;class o extends g.K{constructor(a=process.cwd(),b=(0,f.getAgentDir)()){const c=new j.N,d=async()=>(0,h.P)()?{sources:[],errors:[]}:(0,i.o)(a,b,{DefaultPackageManager:f.DefaultPackageManager,SettingsManager:f.SettingsManager});super(async()=>{let a=await d();for(let b of a.errors)console.warn("[Pi Desk][GlobalPluginRuntime] 插件来源发现诊断",{message:b});return await c.initialize(a),a.sources.flatMap(a=>a.enabled&&!a.error&&a.piDeskRoot?[{source:a.source,installedPath:a.piDeskRoot}]:[])},(0,e.J)()),this.sourceChanges=c,this.discover=d}async scanSourceChanges(a){return await this.initialize(),this.sourceChanges.scan(await this.discover(),a)}async applySourceChange(a){let[b]=await this.scanSourceChanges([a.source]);if(!b||b.fingerprint!==a.fingerprint||b.current?.enabled&&b.current.error)throw Error(b?.current?.error??"插件源码在预检后发生变化,请重新加载");a.previous?.piDeskRoot||a.current?.piDeskRoot?await this.replaceSource(a.source,a.current?.enabled?a.current.piDeskRoot:null):(0,k.N)(),this.sourceChanges.commit(a)}}function m(){return globalThis.__piDeskGlobalPluginRuntime||(globalThis.__piDeskGlobalPluginRuntime=new o),globalThis.__piDeskGlobalPluginRuntime}async function n(){let a=globalThis.__piDeskGlobalPluginRuntime;globalThis.__piDeskGlobalPluginRuntime=void 0,await a?.dispose()}d()}catch(a){d(a)}})},44493:(a,b,c)=>{c.a(a,async(a,d)=>{try{let n;c.d(b,{G:()=>m,N:()=>k});var e=c(93736),f=c(73024),g=c(76760),h=a([e]);e=(h.then?(await h)():h)[0];let o=(0,g.join)(process.cwd(),"package.json"),{createRequire:p}=process.getBuiltinModule("module"),q=(0,e.createJiti)((0,g.join)(process.env.PI_DESK_PI_PACKAGE_DIR??process.cwd(),"package.json")),r=new Map,s=0;function i(a){let b=r.get(a);return b&&(r.delete(a),r.set(a,b)),b}function j(a,b){let c=r.get(a);if(c&&(r.delete(a),s-=c.bytes),!(b.bytes>0x2000000)){for(;r.size>=512||s+b.bytes>0x2000000;){let a=r.entries().next().value;r.delete(a[0]),s-=a[1].bytes}r.set(a,b),s+=b.bytes}}function k(){r.size>0&&console.info("[Pi Desk][PluginResources] 已清除插件代码缓存",{fileCount:r.size,bytes:s}),r.clear(),s=0}async function l(){let[a,b,c,d,f,h,k,l,m]=await Promise.all([q.import("@earendil-works/pi-coding-agent"),q.import("@earendil-works/pi-agent-core"),q.import("@earendil-works/pi-tui"),q.import("@earendil-works/pi-ai/compat"),q.import("@earendil-works/pi-ai/oauth"),q.import("@earendil-works/pi-ai/providers/all"),q.import("typebox"),q.import("typebox/compile"),q.import("typebox/value")]),n=(0,e.createJiti)(o,{moduleCache:!1,fsCache:!1,tryNative:!1,virtualModules:{"@earendil-works/pi-coding-agent":a,"@earendil-works/pi-agent-core":b,"@earendil-works/pi-tui":c,"@earendil-works/pi-ai/providers/all":h,"@earendil-works/pi-ai/compat":d,"@earendil-works/pi-ai/oauth":f,"@earendil-works/pi-ai":d,"@mariozechner/pi-coding-agent":a,"@mariozechner/pi-agent-core":b,"@mariozechner/pi-tui":c,"@mariozechner/pi-ai/providers/all":h,"@mariozechner/pi-ai/compat":d,"@mariozechner/pi-ai/oauth":f,"@mariozechner/pi-ai":d,typebox:k,"typebox/compile":l,"typebox/value":m,"@sinclair/typebox":k,"@sinclair/typebox/compile":l,"@sinclair/typebox/value":m}}),p=n.options.transform;return n.options.transform=a=>(function(a,b){if(!a.filename)return b(a);let c=(0,g.resolve)(a.filename),d=i(c),e=d?.source===a.source?d:void 0,f=!0===a.async,h=e?.transforms.get(f);if(h)return h;let k=a.source,l=b(a);return l.error||l.code.includes("__JITI_ERROR__")||j(c,{source:k,transforms:new Map(e?.transforms).set(f,l),bytes:(e?.bytes??Buffer.byteLength(k))+Buffer.byteLength(l.code)}),l})(a,p),n}async function m(a,b=(0,g.dirname)(a)){let c=await (n??=l()),d=p(o).cache,e=(0,g.resolve)(b);for(let a of Object.keys(d)){let b=(0,g.relative)(e,a);b.startsWith("..")||(0,g.isAbsolute)(b)||b.split(/[\\/]/).includes("node_modules")||delete d[a]}try{let b,d=(0,g.resolve)(a),e=c.evalModule((b=(0,f.readFileSync)(d,"utf8"),i(d)?.source!==b&&j(d,{source:b,transforms:new Map,bytes:Buffer.byteLength(b)}),b),{filename:d,async:!1});return{default:e?.default??e}}catch(a){if(k(),a instanceof Error&&/await is only valid|top.level await|ERR_REQUIRE_ASYNC_MODULE/i.test(a.message))throw Error("Pi Desk Node Entry 不支持模块顶层 await,请将异步初始化放入 async setup()",{cause:a});throw a}}d()}catch(a){d(a)}})},59214:(a,b,c)=>{c.d(b,{J:()=>f,a:()=>e});var d=c(36153);let e=d.Ik({locale:d.k5(["zh-CN","en"]),timeZone:d.Yj().trim().min(1).max(100).refine(a=>{try{return new Intl.DateTimeFormat("en",{timeZone:a}),!0}catch{return!1}},"无效的 IANA 时区")}).strict().readonly(),f=d.Ik({region:e}).strict().readonly()},60719:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{W:()=>p,o:()=>o});var e=c(51455),f=c(48161),g=c(76760),h=c(4287),i=c(30987),j=a([i]);function k(a,b){let c=(0,g.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,g.isAbsolute)(c)}async function l(a){try{return await (0,e.realpath)(a)}catch{return(0,g.resolve)(a)}}function m(a){return"win32"===process.platform?a.toLowerCase():a}async function n(a){try{if((await (0,e.stat)(a)).isFile())return{version:null,description:null,hasNodeEntry:!1,error:null};let b=JSON.parse(await (0,e.readFile)((0,g.join)(a,"package.json"),"utf8"));if(!b||"object"!=typeof b||Array.isArray(b))throw Error("package.json 必须是对象");return{version:"string"==typeof b.version?b.version:null,description:(0,h._C)(b),hasNodeEntry:b.piDesk?.entry!==void 0||b.piDesk?.global!==void 0,hasNativeEntries:Array.isArray(b.pi?.extensions)&&b.pi.extensions.length>0,error:null}}catch(a){if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return{version:null,description:null,hasNodeEntry:!1,error:null};return{version:null,description:null,hasNodeEntry:!1,error:a instanceof Error?a.message:String(a)}}}async function o(a,b,c){let d=c.SettingsManager.create(a,b,{projectTrusted:!1}),h=new c.DefaultPackageManager({cwd:a,agentDir:b,settingsManager:d}),j=d.drainErrors().map(({error:a})=>a.message),o=new Map,p=new Map;for(let a of h.listConfiguredPackages()){if("user"!==a.scope)continue;let b=a.installedPath?await l(a.installedPath):null,c=b?await n(b):null,d=b?p.get(m(b)):void 0;b&&!d&&p.set(m(b),a.source),o.set(a.source,{source:a.source,kind:"package",path:b,nativePaths:[],hasPiResources:!0,piDeskRoot:b&&c?.hasNodeEntry&&!d?b:null,version:c?.version??null,description:c?.description??null,enabled:!0,error:d?`此目录已由 ${d} 声明,不能重复加载`:b?c?.error??null:"插件包未安装或安装目录不存在"})}let q=(0,g.join)(b,"extensions"),r=new Set;try{for(let a of(await (0,e.readdir)(q,{withFileTypes:!0})))if(!a.name.startsWith(".")&&"node_modules"!==a.name&&(a.isDirectory()||a.isSymbolicLink()))try{let b=await l((0,g.join)(q,a.name));(await (0,e.stat)(b)).isDirectory()&&r.add(b)}catch(b){j.push(`${a.name}: ${b instanceof Error?b.message:String(b)}`)}}catch(a){a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code||j.push(a instanceof Error?a.message:String(a))}for(let a of d.getGlobalSettings().extensions??[]){if(/^[!+-]|[?*{}]/.test(a))continue;let c=await l(a.startsWith("~/")?(0,g.join)((0,f.homedir)(),a.slice(2)):(0,g.resolve)(b,a));try{(await (0,e.stat)(c)).isDirectory()&&r.add(c)}catch{}}let s=[...r].sort((a,b)=>b.length-a.length);try{let a=await h.resolve(async a=>{let b=o.get(a);return b&&(b.error??="插件包未安装或版本不匹配"),"skip"});for(let a of o.values())a.hasPiResources=!1;for(let b of[...a.extensions,...a.skills,...a.prompts,...a.themes])if(b.enabled&&"user"===b.metadata.scope&&"package"===b.metadata.origin){let a=o.get(b.metadata.source);a&&(a.hasPiResources=!0)}for(let b of a.extensions){if("user"!==b.metadata.scope)continue;let a=await l(b.path);if("package"===b.metadata.origin){let c=o.get(b.metadata.source);c&&b.enabled&&!c.nativePaths.includes(a)&&c.nativePaths.push(a);continue}let c=s.find(b=>k(b,a))??a,d=[...p].find(([b])=>k(b,m(a)));if(d){let c=o.get(d[1]);b.enabled&&c&&!c.nativePaths.includes(a)&&c.nativePaths.push(a),j.push(`扩展入口 ${a} 与已配置包 ${d[1]} 重复,保留包来源`);continue}let e=o.get(c);e||(e={source:c,kind:"extension",path:c,nativePaths:[],piDeskRoot:null,version:null,description:null,enabled:!1,error:null},o.set(c,e)),b.enabled&&(e.enabled=!0,e.nativePaths.includes(a)||e.nativePaths.push(a))}}catch(a){j.push(a instanceof Error?a.message:String(a))}for(let a of s){if([...p.keys()].some(b=>k(b,m(a))))continue;let b=await n(a),c=o.get(a);if(!c&&!b.hasNodeEntry&&!b.error)continue;let d=(await Promise.all(["index.ts","index.js"].map(b=>(0,e.stat)((0,g.join)(a,b)).then(a=>a.isFile(),()=>!1)))).some(Boolean),f=c??{source:a,kind:"extension",path:a,nativePaths:[],piDeskRoot:null,version:null,description:null,enabled:!b.hasNativeEntries&&!d,error:null};f.version=b.version,f.description=b.description,f.error=b.error,b.hasNodeEntry&&f.enabled&&(f.piDeskRoot=a),o.set(a,f)}let t=await (0,i.n)(b,h,d);for(let a of o.values())await t(a.source,a.path,"package"===a.kind)&&(a.enabled=!1);return{sources:[...o.values()].sort((a,b)=>a.source.localeCompare(b.source)),errors:j}}async function p(a){if(!a.path)return null;try{return(await (0,e.stat)(a.path)).isFile()?(0,g.dirname)(a.path):a.path}catch{return null}}i=(j.then?(await j)():j)[0],d()}catch(a){d(a)}})},63603:(a,b,c)=>{c.d(b,{Qg:()=>m,RC:()=>p,a4:()=>k,dO:()=>j,j0:()=>n});var d=c(36153);let e=d.Yj().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=d.Yj().trim().min(1).max(256),g=d.Ik({allow:d.YO(f).max(5e3).optional(),deny:d.YO(f).max(5e3).optional()}).strict(),h=d.Ik({value:d.Yj().trim().min(1).max(256),label:d.Yj().trim().min(1).max(120).optional(),description:d.Yj().trim().max(1e3).optional()}).strict(),i=d.Ik({label:d.Yj().trim().min(1).max(120),options:d.YO(h).max(5e3)}).strict(),j=d.g1(e,i),k=d.Yj().min(1).max(64),l=d.Ik({name:d.Yj().trim().min(1).max(64),tools:g.optional(),skills:g.optional(),plugins:d.g1(e,d.g1(e,g)).optional()}).strict(),m=d.g1(k,l).refine(a=>Object.keys(a).length<=100,"最多保存 100 个能力模式").refine(a=>new Set(Object.values(a).map(a=>a.name)).size===Object.keys(a).length,"模式名称不能重复"),n=d.g1(k,l.shape.name);function o(a,b){let c=0,d=0,e=-1,f=0;for(;d<b.length;)if("*"===a[c])e=c++,f=d;else if(a[c]===b[d])c+=1,d+=1;else{if(!(e>=0))return!1;c=e+1,d=++f}for(;"*"===a[c];)c+=1;return c===a.length}function p(a,b){return(a?.allow===void 0||a.allow.some(a=>o(a,b)))&&!a?.deny?.some(a=>o(a,b))}d.Ik({tools:d.YO(h),skills:d.YO(h),plugins:d.g1(e,j)}).strict(),d.Ik({tools:g,skills:g,capabilities:d.g1(e,g)}).strict()},66024:(a,b,c)=>{c.d(b,{N:()=>l});var d=c(77598),e=c(51455),f=c(76760);let g=new Set([".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs",".json",".md",".css",".yaml",".yml",".toml",".wasm",".node"]),h=new Set(["node_modules","temp","logs","coverage"]);class i extends Error{constructor(a){super(`插件来源不存在:${a}`),this.source=a,this.name="L4PiPluginSourceNotFoundError"}}async function j(a){let b=(0,d.createHash)("sha256").update(JSON.stringify({path:a.path,enabled:a.enabled,nativePaths:[...a.nativePaths].sort(),piDeskRoot:a.piDeskRoot,hasPiResources:a.hasPiResources}));if(!a.path||a.error||!a.enabled)return b.update(a.error??"").digest("hex");let c=await (0,e.realpath)(a.path),i=0,j=0,k=async(a,d,l)=>{if(++j>8192)throw Error("源码目录条目超过8192项,请使用独立插件目录");let m=await (0,e.realpath)(a),n=(0,f.relative)(c,m);if(n.startsWith("..")||(0,f.isAbsolute)(n))return;let o=await (0,e.stat)(m);if(o.isDirectory()){if(l.has(m))throw Error("源码目录存在符号链接循环");let a=new Set(l).add(m);for(let b of(await (0,e.readdir)(m,{withFileTypes:!0})).sort((a,b)=>a.name.localeCompare(b.name)))b.name.startsWith(".")||h.has(b.name)||await k((0,f.join)(m,b.name),`${d}/${b.name}`,a)}else if(o.isFile()&&(""===d||g.has((0,f.extname)(d)))){if(o.size>0x1000000||i+o.size>0x4000000)throw Error("源码指纹内容超过容量上限");let a=await (0,e.readFile)(m),c=await (0,e.stat)(m);if(c.size!==o.size||c.mtimeMs!==o.mtimeMs||a.length!==o.size)throw Error("插件源码正在变化,请保存或构建完成后重新加载");i+=a.length,b.update(d).update("\0").update(a).update("\0")}};return await k(c,"",new Set),b.digest("hex")}async function k(a){try{return{source:a,fingerprint:await j(a)}}catch(c){let b={...a,error:c instanceof Error?c.message:String(c)};return{source:b,fingerprint:`failed:${b.error}`}}}class l{async initialize(a){for(let b of(this.applied.clear(),a.sources))this.applied.set(b.source,await k(b))}async scan(a,b){let c=new Map(a.sources.map(a=>[a.source,a])),d=b?[...new Set(b)]:[...new Set([...this.applied.keys(),...c.keys()])],e=[];for(let f of d){let d=this.applied.get(f),g=c.get(f);if(!d&&!g)throw new i(f);if(!g&&a.errors.length>0){if(b)throw Error(`来源发现不完整,不能确认已删除:${f}`);continue}let h=g?await k(g):null;(b||d?.fingerprint!==h?.fingerprint)&&e.push({source:f,previous:d?.source??null,current:h?.source??null,fingerprint:h?.fingerprint??null})}return e}commit(a){a.current&&null!==a.fingerprint?this.applied.set(a.source,{source:a.current,fingerprint:a.fingerprint}):this.applied.delete(a.source)}constructor(){this.applied=new Map}}},67841:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{J:()=>l});var e=c(77598),f=c(73024),g=c(76760),h=c(75430),i=c(59214),j=a([h]);function k(){let a=Intl.DateTimeFormat().resolvedOptions();return i.J.parse({region:{locale:a.locale.toLowerCase().startsWith("zh")?"zh-CN":"en",timeZone:a.timeZone||"UTC"}})}h=(j.then?(await j)():j)[0];class m{constructor(a=(0,g.join)((0,h.getAgentDir)(),"pi-desk-settings.json"),b=k){this.path=a,this.defaults=b,this.snapshot=null,this.listeners=new Set,this.tail=Promise.resolve()}getSnapshot(){if(!this.snapshot)if((0,f.existsSync)(this.path))this.snapshot=i.J.parse(JSON.parse((0,f.readFileSync)(this.path,"utf8")));else{let a=i.J.parse(this.defaults());this.save(a),this.snapshot=a}return this.snapshot}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}update(a){let b=this.tail.then(()=>{let b=this.getSnapshot(),c=i.J.parse({region:{...b.region,...a}});if(JSON.stringify(b)!==JSON.stringify(c))for(let a of(this.save(c),this.snapshot=c,console.info("[Pi Desk][Settings] 共享地区设置已保存",c.region),this.listeners))try{a()}catch(a){console.error("[Pi Desk][Settings] 设置订阅回调失败",{message:a instanceof Error?a.message:String(a)})}});return this.tail=b.catch(()=>void 0),b}save(a){(0,f.mkdirSync)((0,g.dirname)(this.path),{recursive:!0});let b=`${this.path}.${process.pid}.${(0,e.randomUUID)()}.tmp`;try{(0,f.writeFileSync)(b,`${JSON.stringify(a,null,2)}
|
|
3
|
+
`,"utf8"),(0,f.renameSync)(b,this.path)}finally{(0,f.existsSync)(b)&&(0,f.unlinkSync)(b)}}}function l(){return globalThis.__piDeskHostSettingsStore??=new m}d()}catch(a){d(a)}})},73630:(a,b,c)=>{c.d(b,{f:()=>h});var d=c(77598),e=c(51455),f=c(76760);function g(a,b){let c=(0,f.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,f.isAbsolute)(c)}async function h(a){if("entry.js"!==(0,f.basename)(a))throw Error("Browser Entry 必须命名为 entry.js");let b=await (0,e.realpath)((0,f.dirname)(a)),c=new Map,h=0,i=0,j=[],k=async(a,l,m)=>{let n=await (0,e.realpath)(a);if(!g(b,n))return;if(m.has(n))throw Error("Browser 模块目录存在符号链接循环");let o=new Set(m).add(n);for(let a of(await (0,e.readdir)(n,{withFileTypes:!0})).sort((a,b)=>a.name.localeCompare(b.name))){if(++i>4096)throw Error("Browser 模块目录条目超过上限");if(a.name.startsWith(".")||"node_modules"===a.name)continue;let m=(0,f.join)(n,a.name),p=await (0,e.realpath)(m);if(!g(b,p))continue;let q=await (0,e.stat)(p),r=l?`${l}/${a.name}`:a.name;if(q.isDirectory()){await k(p,r,o);continue}if(!q.isFile()||!a.name.endsWith(".js"))continue;if("entry.js"===r&&"entry.js"!==(0,f.basename)(p))throw Error("Browser Entry 符号链接必须指向 entry.js");if(c.size>=2048||q.size>0x1000000||h+q.size>0x2000000)throw Error("Browser 模块快照超过数量或容量上限");let s=await (0,e.readFile)(p),t=await (0,e.stat)(p);if(s.length!==q.size||t.size!==q.size||t.mtimeMs!==q.mtimeMs)throw Error("Browser 模块在读取时发生变化,请构建完成后重新加载");h+=s.length,j.push({path:p,size:t.size,mtimeMs:t.mtimeMs,ino:t.ino}),c.set(r,{content:s,etag:`"${(0,d.createHash)("sha256").update(s).digest("hex")}"`})}};for(let a of(await k(b,"",new Set),j)){let b=await (0,e.stat)(a.path);if(b.size!==a.size||b.mtimeMs!==a.mtimeMs||b.ino!==a.ino)throw Error("Browser 模块组在读取时发生变化,请构建完成后重新加载")}if(!c.has("entry.js"))throw Error("Browser Entry 模块缺失或越出专用目录");return{size:h,modules:c}}},90733:(a,b,c)=>{c.d(b,{$m:()=>g,FX:()=>h,Pu:()=>m,QK:()=>i,Tk:()=>k,nJ:()=>j,qs:()=>l});var d=c(36153);let e=d.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=d.g1(d.Yj(),d.Pq());function g(a,b){return`${a}\u0000${b}`}function h(a){return e.parse(a)}function i(a){return e.parse(a)}function j(a,b){let c=f.parse(a);if(Buffer.byteLength(JSON.stringify(c),"utf8")>2097152)throw new m(b);return c}class k extends Error{constructor(a,b){super(`Plugin method was not found: ${a}/${b}`),this.name="L4PiPluginMethodNotFoundError"}}class l extends Error{constructor(a,b){super(`Plugin method is already registered: ${a}/${b}`),this.name="L4PiPluginMethodConflictError"}}class m extends Error{constructor(a){super(`Plugin method ${a} exceeds 2MB`),this.direction=a,this.name="L4PiPluginMethodPayloadTooLargeError"}}},99667:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{K:()=>z,y:()=>w});var e=c(77598),f=c(58500),g=c(51455),h=c(76760),i=c(36153),j=c(63603),k=c(44493),l=c(73630),m=c(90733),n=a([k]);k=(n.then?(await n)():n)[0];let r=i.g1(i.Yj(),i.Pq()),s=i.Ik({workId:i.Yj().trim().min(1),sessionId:i.Yj().trim().min(1),branchId:i.Yj().trim().min(1)}).strict(),t=i.Ik({source:s,cwd:i.Yj().trim().min(1),status:i.k5(["main_running","background_running","completed","idle"])}).strict(),u=i.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),v=i.ai().int().safe();class w extends Error{constructor(){super("插件运行时仍有调用正在执行"),this.name="L4PiPluginRuntimeBusyError"}}class x extends Error{constructor(a,b){super(b instanceof Error?b.message:String(b),{cause:b}),this.phase=a,this.name="L4PiPluginPhaseError"}}class y extends x{constructor(a,b){super(a,Error("插件加载超时,已停止本次加载")),this.execution=b,this.name="L4PiPluginLoadTimeoutError"}}function o(a,b,c){if("string"!=typeof b||!b.trim())throw Error(`package.json.${c} must be a non-empty string`);let d=(0,h.resolve)(a,b),e=(0,h.relative)(a,d);if(e.startsWith("..")||(0,h.isAbsolute)(e))throw Error(`package.json.${c} must stay inside the package root`);return d}function p(a){return a instanceof Error&&a.message?a.message:String(a)}async function q(a){let b=null,c=Promise.resolve().then(a.execute);a.owner.pendingCleanup.add(c);let d=()=>{a.owner.pendingCleanup.delete(c)};c.then(d,d);try{if(await Promise.race([c.then(()=>!0),new Promise(a=>{b=setTimeout(()=>a(!1),1500)})]))return;throw a.onTimeout?.(),Error(`插件 ${a.phase} 超时,关闭结果未确认`)}catch(b){console.warn("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 生命周期执行失败",{source:a.owner.source,packageName:a.owner.packageName,phase:a.phase,timeoutMs:1500,message:p(b)})}finally{b&&clearTimeout(b)}}class z{constructor(a,b){this.packageProvider=a,this.hostSettings=b,this.methods=new Map,this.pluginOwners=new Map,this.browserEntries=new Map,this.declarations=new Map,this.capabilityLoaders=new Map,this.owners=[],this.loadingOwners=new Set,this.changeListeners=new Set,this.changingSources=new Set,this.maintainingSources=new Set,this.lifetime=new AbortController,this.packageDiagnostics=new Map,this.recoveries=new Map,this.initializePromise=null,this.initialized=!1,this.disposed=!1,this.acceptingCalls=!0,this.loadError=null,this.workSessionProvider=null,this.pushSender=null,this.appRuntimeSink=null}initialize(){return this.disposed?Promise.reject(Error("Global plugin runtime has been disposed")):this.initialized?Promise.resolve():(this.initializePromise||(this.initializePromise=this.loadConfiguredPackages().catch(a=>{this.loadError=p(a),console.error("[Pi Desk][GlobalPluginRuntime] 读取插件配置失败,核心应用继续启动",{errorName:a instanceof Error?a.name:"UnknownError",message:this.loadError})}).finally(()=>{this.initializePromise=null,this.initialized=!0,this.publishChanges()})),this.initializePromise)}subscribeChanges(a){return this.changeListeners.add(a),()=>this.changeListeners.delete(a)}publishChanges(){if(!this.disposed)for(let a of this.changeListeners)try{a()}catch(a){console.warn("[Pi Desk][GlobalPluginRuntime] 状态监听失败",{message:p(a)})}}async withSourceIdle(a,b,c,d){let e,g=AbortSignal.any([c,this.lifetime.signal]);g.throwIfAborted();let h=new Promise((a,b)=>{e=()=>b(g.reason),g.addEventListener("abort",e,{once:!0})});try{await Promise.race([this.initialize(),h])}finally{g.removeEventListener("abort",e)}if(g.throwIfAborted(),!this.acceptingCalls||this.changingSources.has(a)||this.maintainingSources.has(a))throw new w;this.cancelRecovery(a),this.maintainingSources.add(a);let i=performance.now()+15e3;try{for(;this.owners.some(b=>b.source===a&&b.activeCalls.size>0);){if(performance.now()>=i)throw Error(`插件 ${a} 的在途调用未在15秒内结束,本次维护失败,可稍后手动重试`);d(`插件 ${a} 仍有调用正在执行`),await (0,f.setTimeout)(250,void 0,{signal:g})}return g.throwIfAborted(),await b()}finally{this.maintainingSources.delete(a)}}async replaceSource(a,b){if(await this.initialize(),this.disposed||!this.acceptingCalls||this.changingSources.has(a))throw new w;this.cancelRecovery(a);let c=this.owners.find(b=>b.source===a);this.changingSources.add(a);try{if(c&&this.releaseOwner(c),this.disposed)throw Error("Global plugin runtime has been disposed");if((0,k.N)(),this.packageDiagnostics.delete(a),null!==b){if(await this.loadPackage(a,b),this.disposed)throw Error("Global plugin runtime has been disposed");let c=this.packageDiagnostics.get(a);if(c?.status==="failed")throw Error(c.error?.message??"插件加载失败")}}finally{this.changingSources.delete(a),this.publishChanges()}}ownerPublished(a){return a.active&&!a.draining&&!this.changingSources.has(a.source)&&this.owners.includes(a)}readDiagnostics(){return{packages:[...this.packageDiagnostics.values()].sort((a,b)=>a.source.localeCompare(b.source)).map(a=>structuredClone(a)),loadError:this.loadError}}readCapabilityRegistrations(){return[...this.owners].filter(a=>this.ownerPublished(a)).sort((a,b)=>a.source.localeCompare(b.source)).map(a=>({source:a.source,methods:[...this.methods.values()].filter(b=>b.owner===a).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.method.localeCompare(b.method):c}).map(({pluginName:a,method:b})=>({pluginName:a,method:b})),browserEntries:[...this.browserEntries.values()].filter(b=>b.owner===a).sort((a,b)=>a.pluginName.localeCompare(b.pluginName)).map(({pluginName:a})=>({pluginName:a})),messageDeclarations:[...this.declarations.values()].filter(b=>b.owner===a).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.declarationName.localeCompare(b.declarationName):c}).map(({pluginName:a,declarationName:b,declaration:c})=>({pluginName:a,declarationName:b,priority:c.priority}))}))}async prepareReload(){if(await this.initialize(),this.disposed)throw Error("Global plugin runtime has been disposed");if(!this.acceptingCalls||this.changingSources.size>0||this.maintainingSources.size>0||this.owners.some(a=>a.activeCalls.size>0))throw new w;for(let a of(this.acceptingCalls=!1,this.recoveries.keys()))this.cancelRecovery(a);for(let a of this.owners)a.draining=!0;await Promise.all([...this.owners].reverse().map(async a=>{let b=a.beforeReload;if(!b)return;a.beforeReload=null;let c=new AbortController;await q({owner:a,phase:"beforeReload",execute:()=>b({signal:c.signal}),onTimeout:()=>c.abort()})}))}bindWorkSessionProvider(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.workSessionProvider=a,()=>{this.workSessionProvider===a&&(this.workSessionProvider=null)}}bindPushSender(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.pushSender=a,()=>{this.pushSender===a&&(this.pushSender=null)}}bindAppRuntimeSink(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.appRuntimeSink=a,()=>{this.appRuntimeSink===a&&(this.appRuntimeSink=null)}}async runOwnedCall(a,b){let c;if(this.ensureOwnerActive(a),this.maintainingSources.has(a.source))throw new w;let d=new AbortController,e=new Promise((a,b)=>{c=b}),f=()=>{c(Error("Pi Desk Plugin owner is no longer active"))};d.signal.addEventListener("abort",f,{once:!0}),a.activeCalls.add(d);try{let c=await Promise.race([Promise.resolve().then(()=>(this.ensureOwnerActive(a),b(d.signal))),e]);return this.ensureOwnerActive(a),c}finally{a.activeCalls.delete(d),d.signal.removeEventListener("abort",f)}}async invoke(a,b,c){if(await this.initialize(),this.disposed)throw Error("Global plugin runtime has been disposed");if(!this.acceptingCalls)throw new w;let d=(0,m.FX)(a),e=(0,m.QK)(b),f=this.methods.get((0,m.$m)(d,e));if(!f)throw new m.Tk(d,e);if(!this.ownerPublished(f.owner)||this.changingSources.has(f.owner.source))throw new w;let g=(0,m.nJ)(c,"input");return this.runOwnedCall(f.owner,async a=>{let b=await f.execute(g,{signal:a});return(0,m.nJ)(b,"output")})}async listCapabilityDeclarations(){if(await this.initialize(),this.disposed||!this.acceptingCalls)throw new w;let a=await Promise.all([...this.capabilityLoaders].filter(([,a])=>this.ownerPublished(a.owner)&&!this.changingSources.has(a.owner.source)).map(async([a,b])=>{try{return await this.runOwnedCall(b.owner,async c=>{let d=await b.load({signal:c});if(this.capabilityLoaders.get(a)!==b)throw Error(`能力声明已被替换:${a}`);return[a,j.dO.parse(d)]})}catch(b){throw Error(`读取 ${a} 能力选项失败:${p(b)}`,{cause:b})}}));return Object.fromEntries(a)}async listBrowserEntries(){return await this.initialize(),[...this.browserEntries.values()].filter(a=>this.ownerPublished(a.owner)).sort((a,b)=>a.pluginName.localeCompare(b.pluginName)).flatMap(({pluginName:a,entryPath:b,resourceKey:c,snapshot:d})=>d?[{pluginName:a,entryPath:b,resourceKey:c,snapshot:d}]:[])}async listMessageDeclarations(){return await this.initialize(),this.readMessageDeclarations()}readMessageDeclarations(){return[...this.declarations.values()].filter(a=>this.ownerPublished(a.owner)).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.declarationName.localeCompare(b.declarationName):c}).map(({pluginName:a,declarationName:b,declaration:c})=>({pluginName:a,declarationName:b,declaration:c}))}async dispose(){if(this.disposed)return;for(let a of(this.disposed=!0,this.lifetime.abort(),this.recoveries.keys()))this.cancelRecovery(a);this.acceptingCalls=!1,this.changeListeners.clear(),this.workSessionProvider=null,this.pushSender=null;let a=[...new Set([...this.owners,...this.loadingOwners])].reverse();this.owners.length=0,this.loadingOwners.clear(),await Promise.all(a.map(a=>this.releaseOwner(a))),this.methods.clear(),this.pluginOwners.clear(),this.browserEntries.clear(),this.declarations.clear(),this.capabilityLoaders.clear(),this.appRuntimeSink=null}async loadConfiguredPackages(){for(let a of(this.loadError=null,this.packageDiagnostics.clear(),await this.packageProvider())){if(this.disposed)return;let b=await this.loadPackage(a.source,a.installedPath);b&&!this.disposed&&this.recoveries.set(a.source,{installedPath:a.installedPath,settled:b.execution,controller:new AbortController})}for(let[a,b]of this.recoveries)this.recoverSource(a,b)}cancelRecovery(a){let b=this.recoveries.get(a);this.recoveries.delete(a),b?.controller.abort()}async recoverSource(a,b){let c,d=b.controller.signal,e=new Promise((a,b)=>{c=()=>b(d.reason),d.addEventListener("abort",c,{once:!0})});try{await Promise.race([b.settled,e]),d.throwIfAborted(),console.info("[Pi Desk][GlobalPluginRuntime] 插件加载超时,稍后自动重试一次",{source:a,delayMs:1e4}),await (0,f.setTimeout)(1e4,void 0,{signal:d}),d.throwIfAborted(),this.recoveries.delete(a),await this.replaceSource(a,b.installedPath),console.info("[Pi Desk][GlobalPluginRuntime] 插件自动重试成功",{source:a})}catch(b){d.aborted||console.warn("[Pi Desk][GlobalPluginRuntime] 插件自动重试失败,不再自动加载",{source:a,message:p(b)})}finally{d.removeEventListener("abort",c),this.recoveries.get(a)===b&&this.recoveries.delete(a)}}async loadOwnerWithinDeadline(a,b,c){let d,e="entry",f=performance.now(),g=()=>{let b=Math.round(performance.now()-f);b<1e3||console.info("[Pi Desk][GlobalPluginRuntime] 插件加载阶段耗时",{source:a.source,packageName:a.packageName,phase:e,durationMs:b})},h=a=>{g(),e=a,f=performance.now()},i=(async()=>{let d=()=>h("setup");void 0!==b?await this.loadEntryOwner(a,b,d):await this.loadLegacyOwner(a,c,d),h("resources");try{await this.validateOwnerResources(a)}catch(a){throw new x("resources",a)}this.ensureOwnerActive(a)})();try{await Promise.race([i,new Promise((a,b)=>{d=setTimeout(()=>{b(new y(e,i))},15e3)})])}finally{d&&clearTimeout(d),g()}}async loadPackage(a,b){let c,d=performance.now(),e=(0,h.resolve)(b);try{let a=(0,h.join)(e,"package.json");c=JSON.parse(await (0,g.readFile)(a,"utf8"))}catch(b){return this.packageDiagnostics.set(a,{source:a,packageName:null,version:null,pluginName:null,status:"failed",error:{phase:"package",message:p(b)}}),null}let f=c.piDesk?.entry,i=c.piDesk?.global;if(void 0===f&&void 0===i||this.disposed)return null;let j={source:a,packageName:"string"==typeof c.name?c.name:null,version:"string"==typeof c.version?c.version:null,packageRoot:e,active:!0,draining:!1,pluginNames:new Set,activeCalls:new Set,subscriptions:new Set,pendingCleanup:new Set,beforeReload:null,disposer:null};console.info("[Pi Desk][GlobalPluginRuntime] 开始加载 Pi Desk Plugin",{source:a,packageName:j.packageName}),this.loadingOwners.add(j);try{await this.loadOwnerWithinDeadline(j,f,i),this.owners.push(j),this.recordOwnerDiagnostic(j),console.info("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 已加载",{source:a,packageName:j.packageName,pluginNames:[...j.pluginNames],methodCount:[...this.methods.values()].filter(a=>a.owner===j).length,browserEntryCount:[...this.browserEntries.values()].filter(a=>a.owner===j).length,declarationCount:[...this.declarations.values()].filter(a=>a.owner===j).length,durationMs:Math.round(performance.now()-d)})}catch(f){let b=f instanceof x?f.phase:"entry",c=[...j.pluginNames][0]??null;await this.releaseOwner(j);let e=p(f);if(this.packageDiagnostics.set(a,{source:a,packageName:j.packageName,version:j.version,pluginName:c,status:"failed",error:{phase:b,message:e}}),console.warn("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 加载失败",{source:a,packageName:j.packageName,phase:b,errorName:f instanceof Error?f.name:"UnknownError",message:e,durationMs:Math.round(performance.now()-d)}),f instanceof y)return{execution:f.execution.catch(()=>{}).then(async()=>{await Promise.allSettled([...j.pendingCleanup])})}}finally{this.loadingOwners.delete(j)}return null}async loadEntryOwner(a,b,c){let d=o(a.packageRoot,b,"piDesk.entry");if(!(await (0,g.stat)(d)).isFile())throw Error("Pi Desk Plugin entry is not a file");let e=(await (0,k.G)(d,a.packageRoot)).default;if(!e||"object"!=typeof e||"string"!=typeof e.name||"function"!=typeof e.setup)throw Error("Pi Desk Plugin entry must default-export definePiDeskPlugin(...)");let f=(0,m.FX)(e.name);this.claimPluginName(a,f),c();try{let b=function(a){if(void 0===a)return{beforeReload:null,disposer:null};if("function"==typeof a)return{beforeReload:null,disposer:a};if(!a||"object"!=typeof a)throw Error("Pi Desk Plugin setup must return void, a disposer, or a lifecycle object");if(void 0!==a.beforeReload&&"function"!=typeof a.beforeReload)throw Error("Pi Desk Plugin lifecycle.beforeReload must be a function");if(void 0!==a.dispose&&"function"!=typeof a.dispose)throw Error("Pi Desk Plugin lifecycle.dispose must be a function");return{beforeReload:a.beforeReload??null,disposer:a.dispose??null}}(await e.setup(this.createPiDeskFacade(a,f,a.packageRoot)));if(a.beforeReload=b.beforeReload,a.disposer=b.disposer,!a.active||this.disposed)throw await this.releaseOwner(a),Error("插件初始化完成时 Owner 已失效")}catch(a){throw new x("setup",a)}}async loadLegacyOwner(a,b,c){let d=o(a.packageRoot,b,"piDesk.global");if(!(await (0,g.stat)(d)).isFile())throw Error("Global Plugin entry is not a file");let e=await (0,k.G)(d,a.packageRoot);if("function"!=typeof e.default)throw Error("Global Plugin entry must default-export a factory function");let f=e.default;c();try{let b=await f(this.createLegacyApi(a));if(void 0!==b&&"function"!=typeof b)throw Error("Global Plugin factory must return void or a disposer function");if(a.disposer=b??null,!a.active||this.disposed)throw await this.releaseOwner(a),Error("插件初始化完成时 Owner 已失效")}catch(a){throw new x("setup",a)}}claimPluginName(a,b){this.ensureOwnerActive(a);let c=this.pluginOwners.get(b);if(c&&c!==a)throw Error(`Pi Desk pluginName is already registered: ${b}`);this.pluginOwners.set(b,a),a.pluginNames.add(b)}createLegacyApi(a){return{bindPlugin:b=>{let c=(0,m.FX)(b);return this.claimPluginName(a,c),{name:c,registerMethod:(b,d)=>this.registerMethod(a,c,b,d)}}}}createPiDeskFacade(a,b,c){return{name:b,host:{settings:{getSnapshot:()=>{if(this.ensureOwnerActive(a),!this.hostSettings)throw Error("宿主共享设置尚未就绪");return this.hostSettings.getSnapshot()},subscribe:b=>{if(this.ensureOwnerActive(a),!this.hostSettings)throw Error("宿主共享设置尚未就绪");let c=this.hostSettings.subscribe(()=>{a.active&&!a.draining&&b()});return a.subscriptions.add(c),()=>{if(a.subscriptions.delete(c))return c()}}},workSessions:{listWorkSessions:async()=>{this.ensureOwnerActive(a);let b=await this.readWorkSessions();return this.ensureOwnerActive(a),b}}},notifications:{publish:c=>(this.ensureOwnerActive(a),this.requireAppRuntimeSink().publishNotification(b,c)),update:(c,d)=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().updateNotification(b,c,d)},delete:c=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().deleteNotification(b,c)}},setState:c=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().setState(b,c)},registerMethod:(c,d)=>this.registerMethod(a,b,c,d),registerBrowserEntry:d=>{if(this.ensureOwnerActive(a),this.browserEntries.has(b))throw Error(`Browser Entry is already registered: ${b}`);let f=o(c,d,"browserEntry"),g={pluginName:b,entryPath:f,resourceKey:(0,e.randomUUID)(),snapshot:null,owner:a};return this.browserEntries.set(b,g),this.registrationDisposer(a,()=>{this.browserEntries.get(b)===g&&this.browserEntries.delete(b)})},declareCapabilities:c=>{if(this.ensureOwnerActive(a),"function"!=typeof c)throw Error("能力声明必须是按需查询函数");if(this.capabilityLoaders.has(b))throw Error(`能力声明已注册:${b}`);let d={load:c,owner:a};return this.capabilityLoaders.set(b,d),this.registrationDisposer(a,()=>{this.capabilityLoaders.get(b)===d&&this.capabilityLoaders.delete(b)})},declareMessage:(c,d)=>this.registerDeclaration(a,b,c,d),pushGlobal:(c,d)=>{a.active&&!a.draining&&this.sendPush(b,{scope:"global"},c,d)},pushSession:(c,d,e)=>{a.active&&!a.draining&&this.sendPush(b,{scope:"session",source:s.parse(c)},d,e)}}}registerMethod(a,b,c,d){this.ensureOwnerActive(a);let e=(0,m.QK)(c),f=(0,m.$m)(b,e);if(this.methods.has(f))throw new m.qs(b,e);let g={pluginName:b,method:e,execute:d,owner:a};return this.methods.set(f,g),this.registrationDisposer(a,()=>{this.methods.get(f)===g&&this.methods.delete(f)})}registerDeclaration(a,b,c,d){var e;this.ensureOwnerActive(a);let f=u.parse(c);if(!d||"object"!=typeof d||"function"!=typeof d.match||"function"!=typeof d.project)throw Error("Message Declaration must provide match and project functions");let g={priority:(e=d.priority,v.parse(e)),match:d.match,project:d.project},h=`${b}\u0000${f}`;if(this.declarations.has(h))throw Error(`Message Declaration is already registered: ${b}/${f}`);let i={pluginName:b,declarationName:f,declaration:g,owner:a};return this.declarations.set(h,i),this.registrationDisposer(a,()=>{this.declarations.get(h)===i&&this.declarations.delete(h)})}registrationDisposer(a,b){let c=!0;return()=>{c&&(c=!1,a.active&&b())}}requireAppRuntimeSink(){if(!this.appRuntimeSink)throw Error("App Runtime sink has not been bound");return this.appRuntimeSink}sendPush(a,b,c,d){if(this.disposed)return;let e=(0,m.QK)(c),f=function(a){let b=r.parse(a);if(Buffer.byteLength(JSON.stringify(b),"utf8")>65536)throw Error("Plugin Push data exceeds 64KB");return b}(d);this.pushSender?.({pluginName:a,target:b,event:e,data:structuredClone(f)})}async readWorkSessions(){if(!this.workSessionProvider||this.disposed)return[];let a=await this.workSessionProvider();return i.YO(t).parse(a).map(a=>structuredClone(a))}async validateOwnerResources(a){for(let b of[...this.browserEntries.values()].filter(b=>b.owner===a)){if(!(await (0,g.stat)(b.entryPath)).isFile())throw Error("Browser Entry resource is not a file");if("entry.js"!==(0,h.basename)(b.entryPath))throw Error("Browser Entry resource file must be named entry.js");let c=await (0,l.f)(b.entryPath);if(this.ensureOwnerActive(a),[...this.browserEntries.values()].reduce((a,b)=>a+(b.snapshot?.size??0),0)+c.size>0x8000000)throw Error("Browser 模块快照总量超过128MB,拒绝加载此插件");b.snapshot=c}}recordOwnerDiagnostic(a){this.packageDiagnostics.set(a.source,{source:a.source,packageName:a.packageName,version:a.version,pluginName:[...a.pluginNames][0]??null,status:"ready",error:null})}ensureOwnerActive(a){if(!a.active||a.draining||this.disposed)throw Error("Pi Desk Plugin owner is no longer active")}async releaseOwner(a){let b=[...a.subscriptions];if(a.subscriptions.clear(),a.active){for(let b of(a.active=!1,a.activeCalls))b.abort();a.activeCalls.clear();let b=this.owners.indexOf(a);for(let[c,d]of(b>=0&&this.owners.splice(b,1),this.methods))d.owner===a&&this.methods.delete(c);for(let[b,c]of this.browserEntries)c.owner===a&&this.browserEntries.delete(b);for(let[b,c]of this.declarations)c.owner===a&&this.declarations.delete(b);for(let[b,c]of this.capabilityLoaders)c.owner===a&&this.capabilityLoaders.delete(b);for(let b of a.pluginNames)if(this.pluginOwners.get(b)===a){this.pluginOwners.delete(b);try{this.appRuntimeSink?.releasePlugin(b)}catch(a){console.warn("[Pi Desk][GlobalPluginRuntime] 清理插件 App Runtime 失败",{pluginName:b,errorName:a instanceof Error?a.name:"UnknownError",message:p(a)})}}a.pluginNames.clear()}let c=a.beforeReload,d=a.disposer;a.beforeReload=null,a.disposer=null;let e=new AbortController;await Promise.all([...b.map(b=>q({owner:a,phase:"dispose",execute:b})),c?q({owner:a,phase:"beforeReload",execute:()=>c({signal:e.signal}),onTimeout:()=>e.abort()}):Promise.resolve(),d?q({owner:a,phase:"dispose",execute:d}):Promise.resolve()])}}d()}catch(a){d(a)}})}};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";exports.id=50520,exports.ids=[50520],exports.modules={621:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{JM:()=>k,w$:()=>m});var e=c(51455),f=c(76760),g=c(38522),h=c(57975);c(77598);var i=c(73159),j=a([i]);function k(a){return a&&"object"==typeof a&&!Array.isArray(a)?a:{}}async function l(a,b){let c;if(!(c=b.replaceAll("\\","/").replace(/^\.\//,""))||(0,f.isAbsolute)(b)||f.win32.isAbsolute(b)||c.includes("\0")||c.split("/").some(a=>".."===a)||!c)return null;try{let c=await (0,e.realpath)((0,f.resolve)(a,b)),d=(0,f.relative)(a,c);if((0,f.isAbsolute)(d)||".."===d||d.startsWith(`..${"win32"===process.platform?"\\":"/"}`))return null;let g=await (0,e.open)(c,"r");try{let a=await g.stat();if(!a.isFile()||a.size>65536)return null;let b=Buffer.alloc(65537),c=0;for(;c<b.length;){let{bytesRead:a}=await g.read(b,c,b.length-c,c);if(!a)break;c+=a}return c<=65536?b.subarray(0,c).toString("utf8"):null}finally{await g.close()}}catch(a){if(["ENOENT","ENOTDIR"].includes(a.code??""))return null;throw a}}async function m(a){let b,c=await (0,e.realpath)(a),d=await l(c,"package.json"),f=d?k(JSON.parse(d)):{},g={};for(let[a,d]of(b=k(k(f.piDesk).i18n),Object.entries(b).slice(0,16).flatMap(([a,b])=>{let c=k(b).readme;return a.length>0&&a.length<=35&&"string"==typeof c&&c.length<=1024?[[a,c]]:[]}))){let b=await l(c,d);null!==b&&(g[a]=b)}var h=await l(c,"README.md");if(null===h&&!Object.keys(g).length)return null;let i=h??Object.values(g)[0];return Object.keys(g).length?{default:i,translations:g}:i}i=(j.then?(await j)():j)[0],(0,h.promisify)(g.gunzip),d()}catch(a){d(a)}})},2472:(a,b,c)=>{c.d(b,{i:()=>i});var d=c(31421),e=c(76760),f=c(73136);let{createRequire:g}=process.getBuiltinModule("module"),h=g((0,e.join)(process.cwd(),"package.json"))("./src/server/l4_foundation/process/l4-process-tree.js");function i(a){return new Promise((b,c)=>{if(a.signal?.aborted)return void c(Error("操作已取消"));let g=(0,f.pathToFileURL)((0,e.join)(process.cwd(),"src/server/l4_foundation/pi/l4-pi-runtime-register.mjs")).href,i=(0,d.spawn)(process.execPath,["--import",g,...a.args],{cwd:process.cwd(),env:{...process.env,PI_CODING_AGENT_DIR:a.agentDir,PI_CODING_AGENT_SESSION_DIR:(0,e.join)(a.agentDir,"sessions"),TSX_TSCONFIG_PATH:(0,e.join)(process.cwd(),"tsconfig.json"),...a.env},stdio:["ignore","pipe","pipe"],windowsHide:!0,detached:"win32"!==process.platform}),j="",k="",l=!1,m=null,n=b=>{!l&&(l=!0,m&&clearTimeout(m),a.signal?.removeEventListener("abort",o),h.terminateManagedTree(i).then(b,a=>{let c=a instanceof Error?a:Error(String(a));console.error("[Pi Desk][Runner] 子进程清理未完成",{pid:i.pid,exitCode:i.exitCode,reason:c.message}),b()}))},o=()=>n(()=>c(Error("操作已取消"))),p=(b,c)=>`${b}${c.toString("utf8")}`.slice(-a.maxOutputBytes);i.stdout.on("data",a=>{j=p(j,a)}),i.stderr.on("data",a=>{k=p(k,a)}),i.once("error",a=>n(()=>c(a))),i.once("close",a=>n(()=>b({stdout:j,stderr:k,code:a}))),(m=setTimeout(()=>{let b=a.timeoutError(),d=`${k}
|
|
2
2
|
${j}`.trim().slice(-4e3);d&&(b.message+=`
|
|
3
|
-
${d}`),n(()=>c(b))},a.timeoutMs)).unref(),a.signal?.addEventListener("abort",o,{once:!0}),a.signal?.aborted&&o()})}},17691:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{M:()=>j});var e=c(77598),f=c(73024),g=c(76760),h=c(75430),i=a([h]);function j(){let a=(0,h.getAgentDir)(),b=(0,g.join)(a,"pi-desk"),c=(0,g.join)(a,"pi-super");if((0,f.existsSync)(b)||!(0,f.existsSync)(c))return b;let d=(0,g.join)(a,`.pi-desk-migration-${(0,e.randomUUID)()}`);try{(0,f.cpSync)(c,d,{recursive:!0,errorOnExist:!0,force:!1}),(0,f.renameSync)(d,b),console.info("[Pi Desk] 已复制旧版应用数据到新目录")}finally{(0,f.rmSync)(d,{recursive:!0,force:!0})}return b}h=(i.then?(await i)():i)[0],d()}catch(a){d(a)}})},20700:(a,b,c)=>{function d(){return globalThis.__piDeskRestartHandler??null}function e(){return null!==d()}function f(a,b){let c=d();if(!c)throw Error("当前启动方式不支持自动重启 Pi Desk");setTimeout(()=>c(a,b),150).unref()}c.d(b,{Z:()=>f,k:()=>e})},33290:(a,b,c)=>{function d(){return globalThis.__piDeskNativePluginDiagnostics||(globalThis.__piDeskNativePluginDiagnostics=[]),globalThis.__piDeskNativePluginDiagnostics}function e(a,b){let c=d();!c.some(c=>c.cwd===a&&c.message===b)&&(c.push({cwd:a,message:b}),c.length>100&&c.splice(0,c.length-100))}function f(a){let b=a=>{let b=a.replaceAll("\\","/");return"win32"===process.platform?b.toLowerCase():b},c=b(a).replace(/\/$/,""),e=d();for(let a=e.length-1;a>=0;a-=1){let d=b(e[a].message);(d.includes(`${c}:`)||d.includes(`${c}/`))&&e.splice(a,1)}}function g(){return d().map(a=>({...a}))}c.d(b,{pL:()=>e,tt:()=>f,u7:()=>g})},34458:(a,b,c)=>{c.a(a,async(a,d)=>{try{let r;c.d(b,{dz:()=>o,qX:()=>n,w$:()=>i.w$});var e=c(4287),f=c(5235),g=c(64253),h=c(73159),i=c(621),j=a([f,g,h,i]);function k(a){return new URL(e.SZ.parse(a)).href.replace(/\/+$/,"")}function l(a,b,c){return new URL(`${k(a)}/${encodeURIComponent(b)}${c?`/${encodeURIComponent(c)}`:""}`)}function m(a,b){let c=(0,i.JM)(a.versions),d=(0,i.JM)(a["dist-tags"]),e="string"==typeof d[b]?d[b]:b.replace(/^v(?=\d+\.)/,"");if("string"!=typeof e||!Object.hasOwn(c,e))throw new h.XH("插件源不存在指定版本或标签",404,"missing");if(!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(e))throw new h.XH("插件源返回的版本无效");return e}async function n(a,b){let c=(0,f.to)(b.agentDir),d=b.downloadSource??c.downloadSource;if("local"===d.mode){let c=await (0,g.B)(b.agentDir),d=a.startsWith("@")?c[`${a.split("/")[0]}:registry`]:void 0;return{registry:k(d||c.registry||f.Nx),fallback:!1}}if(b.registry){let a=k(b.registry);if(![f.Nx,f.sv].includes(a))return{registry:a,fallback:!1}}let e=c.registries[`npm:${a}`];if(e)return{registry:k(e),fallback:!1};if(a.startsWith("@")){let c=(await (0,g.B)(b.agentDir))[`${a.split("/")[0]}:registry`];if(c){let a=k(c);if(![f.Nx,f.sv].includes(a))return{registry:a,fallback:!1}}}return"custom"===d.mode?{registry:k(d.registry),fallback:!1}:"official"===d.mode?{registry:f.Nx,fallback:!1}:"domestic"===d.mode?{registry:f.sv,fallback:!1}:{registry:await function(){if(!r||r.expires<=Date.now()){let a=(async()=>{try{let a=await (0,h.NL)(new URL("https://ipwho.is/?fields=success,country_code"),{limit:1024,timeout:3e3,cache:!1,auth:!1}),b=(0,i.JM)(JSON.parse(a.toString("utf8")));if(!0!==b.success)throw Error("出口地区检测失败");return"CN"===b.country_code?f.sv:f.Nx}catch{return r&&(r.expires=Date.now()+6e4),f.Nx}})();r={expires:Date.now()+18e5,value:a}}return r.value}(),fallback:!0}}async function o(a,b={}){let c;if(!a.startsWith("npm:"))return{source:a};let d=/^npm:((?:@[^/]+\/)?[^@]+)(?:@([^@]+))?$/.exec(a);if(!d)throw new h.XH("npm 插件来源无效",400);let e=d[1];if(e.length>214||!/^(?:@[a-z0-9_.-]+\/)?[a-z0-9][a-z0-9_.-]*$/i.test(e))throw new h.XH("npm 插件包名无效",400);let g=d[2]??"latest";if(g.length>128||!/^[a-zA-Z0-9._+-]+$/.test(g))throw new h.XH("npm 插件版本或标签无效",400);let j=b.downloadSource??(0,f.to)(b.agentDir).downloadSource,k=await n(e,{...b,downloadSource:j}),r=k.registry,s=g;try{let a=await p(l(r,e),b),d=(0,i.JM)(a["dist-tags"])[g];"string"==typeof d&&(s=d),c=m(a,s),q((0,i.JM)(a.versions)[c],e,c)}catch(d){if(!k.fallback||r===f.Nx||!(d instanceof h.XH)||!["network","missing"].includes(d.reason))throw d;console.warn("[Pi Desk][PluginRegistry] 自动下载源不可用,回退 npm 官方源",{name:e,reason:d.reason}),r=f.Nx;let a=await p(l(r,e),b);c=m(a,s),q((0,i.JM)(a.versions)[c],e,c)}return{source:`npm:${e}@${c}`,..."local"===j.mode?{}:{registry:r}}}async function p(a,b){if(!1!==b.cache)return(0,h.Yq)(a,b.signal,b.agentDir);let c=await (0,h.NL)(a,{limit:8388608,signal:b.signal,cache:!1,agentDir:b.agentDir});try{let a=JSON.parse(c.toString("utf8"));if(!a||"object"!=typeof a||Array.isArray(a))throw Error("invalid");return a}catch{throw new h.XH("插件源返回的元数据格式无效")}}function q(a,b,c){let d=(0,i.JM)(a);if(d.name!==b||"string"!=typeof d.version||c&&d.version!==c)throw new h.XH("插件源返回的包名或版本不匹配");return d}[f,g,h,i]=j.then?(await j)():j,d()}catch(a){d(a)}})},47154:(a,b,c)=>{c.d(b,{V:()=>d});function d(a){let b=(globalThis.__piDeskPackageRootTail??Promise.resolve()).then(a,a);return globalThis.__piDeskPackageRootTail=b.then(()=>void 0,()=>void 0),b}},50520:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.r(b),c.d(b,{L2PluginManagement:()=>
|
|
3
|
+
${d}`),n(()=>c(b))},a.timeoutMs)).unref(),a.signal?.addEventListener("abort",o,{once:!0}),a.signal?.aborted&&o()})}},17691:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{M:()=>j});var e=c(77598),f=c(73024),g=c(76760),h=c(75430),i=a([h]);function j(){let a=(0,h.getAgentDir)(),b=(0,g.join)(a,"pi-desk"),c=(0,g.join)(a,"pi-super");if((0,f.existsSync)(b)||!(0,f.existsSync)(c))return b;let d=(0,g.join)(a,`.pi-desk-migration-${(0,e.randomUUID)()}`);try{(0,f.cpSync)(c,d,{recursive:!0,errorOnExist:!0,force:!1}),(0,f.renameSync)(d,b),console.info("[Pi Desk] 已复制旧版应用数据到新目录")}finally{(0,f.rmSync)(d,{recursive:!0,force:!0})}return b}h=(i.then?(await i)():i)[0],d()}catch(a){d(a)}})},20700:(a,b,c)=>{function d(){return globalThis.__piDeskRestartHandler??null}function e(){return null!==d()}function f(a,b){let c=d();if(!c)throw Error("当前启动方式不支持自动重启 Pi Desk");setTimeout(()=>c(a,b),150).unref()}c.d(b,{Z:()=>f,k:()=>e})},33290:(a,b,c)=>{function d(){return globalThis.__piDeskNativePluginDiagnostics||(globalThis.__piDeskNativePluginDiagnostics=[]),globalThis.__piDeskNativePluginDiagnostics}function e(a,b){let c=d();!c.some(c=>c.cwd===a&&c.message===b)&&(c.push({cwd:a,message:b}),c.length>100&&c.splice(0,c.length-100))}function f(a){let b=a=>{let b=a.replaceAll("\\","/");return"win32"===process.platform?b.toLowerCase():b},c=b(a).replace(/\/$/,""),e=d();for(let a=e.length-1;a>=0;a-=1){let d=b(e[a].message);(d.includes(`${c}:`)||d.includes(`${c}/`))&&e.splice(a,1)}}function g(){return d().map(a=>({...a}))}c.d(b,{pL:()=>e,tt:()=>f,u7:()=>g})},34458:(a,b,c)=>{c.a(a,async(a,d)=>{try{let r;c.d(b,{dz:()=>o,qX:()=>n,w$:()=>i.w$});var e=c(4287),f=c(5235),g=c(64253),h=c(73159),i=c(621),j=a([f,g,h,i]);function k(a){return new URL(e.SZ.parse(a)).href.replace(/\/+$/,"")}function l(a,b,c){return new URL(`${k(a)}/${encodeURIComponent(b)}${c?`/${encodeURIComponent(c)}`:""}`)}function m(a,b){let c=(0,i.JM)(a.versions),d=(0,i.JM)(a["dist-tags"]),e="string"==typeof d[b]?d[b]:b.replace(/^v(?=\d+\.)/,"");if("string"!=typeof e||!Object.hasOwn(c,e))throw new h.XH("插件源不存在指定版本或标签",404,"missing");if(!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(e))throw new h.XH("插件源返回的版本无效");return e}async function n(a,b){let c=(0,f.to)(b.agentDir),d=b.downloadSource??c.downloadSource;if("local"===d.mode){let c=await (0,g.B)(b.agentDir),d=a.startsWith("@")?c[`${a.split("/")[0]}:registry`]:void 0;return{registry:k(d||c.registry||f.Nx),fallback:!1}}if(b.registry){let a=k(b.registry);if(![f.Nx,f.sv].includes(a))return{registry:a,fallback:!1}}let e=c.registries[`npm:${a}`];if(e)return{registry:k(e),fallback:!1};if(a.startsWith("@")){let c=(await (0,g.B)(b.agentDir))[`${a.split("/")[0]}:registry`];if(c){let a=k(c);if(![f.Nx,f.sv].includes(a))return{registry:a,fallback:!1}}}return"custom"===d.mode?{registry:k(d.registry),fallback:!1}:"official"===d.mode?{registry:f.Nx,fallback:!1}:"domestic"===d.mode?{registry:f.sv,fallback:!1}:{registry:await function(){if(!r||r.expires<=Date.now()){let a=(async()=>{try{let a=await (0,h.NL)(new URL("https://ipwho.is/?fields=success,country_code"),{limit:1024,timeout:3e3,cache:!1,auth:!1}),b=(0,i.JM)(JSON.parse(a.toString("utf8")));if(!0!==b.success)throw Error("出口地区检测失败");return"CN"===b.country_code?f.sv:f.Nx}catch{return r&&(r.expires=Date.now()+6e4),f.Nx}})();r={expires:Date.now()+18e5,value:a}}return r.value}(),fallback:!0}}async function o(a,b={}){let c;if(!a.startsWith("npm:"))return{source:a};let d=/^npm:((?:@[^/]+\/)?[^@]+)(?:@([^@]+))?$/.exec(a);if(!d)throw new h.XH("npm 插件来源无效",400);let e=d[1];if(e.length>214||!/^(?:@[a-z0-9_.-]+\/)?[a-z0-9][a-z0-9_.-]*$/i.test(e))throw new h.XH("npm 插件包名无效",400);let g=d[2]??"latest";if(g.length>128||!/^[a-zA-Z0-9._+-]+$/.test(g))throw new h.XH("npm 插件版本或标签无效",400);let j=b.downloadSource??(0,f.to)(b.agentDir).downloadSource,k=await n(e,{...b,downloadSource:j}),r=k.registry,s=g;try{let a=await p(l(r,e),b),d=(0,i.JM)(a["dist-tags"])[g];"string"==typeof d&&(s=d),c=m(a,s),q((0,i.JM)(a.versions)[c],e,c)}catch(d){if(!k.fallback||r===f.Nx||!(d instanceof h.XH)||!["network","missing"].includes(d.reason))throw d;console.warn("[Pi Desk][PluginRegistry] 自动下载源不可用,回退 npm 官方源",{name:e,reason:d.reason}),r=f.Nx;let a=await p(l(r,e),b);c=m(a,s),q((0,i.JM)(a.versions)[c],e,c)}return{source:`npm:${e}@${c}`,..."local"===j.mode?{}:{registry:r}}}async function p(a,b){if(!1!==b.cache)return(0,h.Yq)(a,b.signal,b.agentDir);let c=await (0,h.NL)(a,{limit:8388608,signal:b.signal,cache:!1,agentDir:b.agentDir});try{let a=JSON.parse(c.toString("utf8"));if(!a||"object"!=typeof a||Array.isArray(a))throw Error("invalid");return a}catch{throw new h.XH("插件源返回的元数据格式无效")}}function q(a,b,c){let d=(0,i.JM)(a);if(d.name!==b||"string"!=typeof d.version||c&&d.version!==c)throw new h.XH("插件源返回的包名或版本不匹配");return d}[f,g,h,i]=j.then?(await j)():j,d()}catch(a){d(a)}})},47154:(a,b,c)=>{c.d(b,{V:()=>d});function d(a){let b=(globalThis.__piDeskPackageRootTail??Promise.resolve()).then(a,a);return globalThis.__piDeskPackageRootTail=b.then(()=>void 0,()=>void 0),b}},50520:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.r(b),c.d(b,{L2PluginManagement:()=>O,L2PluginManagementInvalidPackageError:()=>L,L2PluginManagementNotFoundError:()=>J,L2PluginManagementOperationConflictError:()=>K,L2PluginManagementRestartPendingError:()=>M,L2PluginManagementRestartUnavailableError:()=>N,disposeL2PluginManagement:()=>G,getL2PluginManagement:()=>I,initializeL2PluginManagement:()=>H});var e=c(16056),f=c(17691),g=c(76019),h=c(77598),i=c(51455),j=c(76760),k=c(75430),l=c(93951),m=c(4287),n=c(34458),o=c(5235),p=c(36361),q=c(69371),r=c(75157),s=c(47154),t=c(60719),u=c(33290),v=c(53584),w=c(96783),x=c(20700),y=c(78597),z=a([f,k,n,o,p,t,y]);[f,k,n,o,p,t,y]=z.then?(await z)():z;class J extends Error{constructor(a){super(`插件不存在:${a}`),this.source=a,this.name="L2PluginManagementNotFoundError"}}class K extends Error{constructor(a){super(a),this.name="L2PluginManagementOperationConflictError"}}class L extends Error{constructor(a){super(a),this.name="L2PluginManagementInvalidPackageError"}}class M extends Error{constructor(){super("已有插件操作需要重启完成"),this.name="L2PluginManagementRestartPendingError"}}class N extends Error{constructor(){super("当前启动方式不支持自动重启 Pi Desk"),this.name="L2PluginManagementRestartUnavailableError"}}function A(a,b,c){let d=(0,j.resolve)(a,b),e=(0,j.relative)(a,d);if(e.startsWith("..")||(0,j.isAbsolute)(e))throw Error(`${c} 必须位于插件包目录内`);return d}async function B(a){try{return(await (0,i.stat)(a)).isFile()}catch{return!1}}function C(a){return a instanceof Error&&a.message?a.message:String(a)}async function D(a){let b;if((await (0,i.stat)(a)).isFile())return{version:null,error:null};try{b=JSON.parse(await (0,i.readFile)((0,j.join)(a,"package.json"),"utf8"))}catch(a){if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return{version:null,error:null};return{version:null,error:{phase:"package",message:C(a)}}}let c="string"==typeof b.version&&b.version.trim()?b.version.trim():null;try{let d=b.piDesk?.entry??b.piDesk?.global;if(void 0!==d){if("string"!=typeof d||!d.trim())throw Error("piDesk.entry 必须是非空字符串");let b=A(a,d,"piDesk.entry");if(!await B(b))throw Error("Pi Desk Entry 文件不存在")}let e=b.pi?.extensions;if(void 0!==e&&!Array.isArray(e))throw Error("pi.extensions 必须是数组");for(let b of e??[]){if("string"!=typeof b||!b.trim())throw Error("pi.extensions 只允许非空字符串");if(/[*?[\]{}]/.test(b))continue;let c=A(a,b,"pi.extensions");if(!await B(c))throw Error(`Native Extension 文件不存在:${b}`)}return{version:c,error:null}}catch(a){return{version:c,error:{phase:"entry",message:C(a)}}}}async function E(a,b){let[c,d]=await Promise.all([(0,i.realpath)(a),(0,i.realpath)(b)]),e=(0,j.relative)(c,d);if(e.startsWith("..")||(0,j.isAbsolute)(e))throw Error("插件能力资源必须位于 Package 目录内");let f=await (0,i.open)(d,"r");try{let a=Buffer.alloc(65537),{bytesRead:b}=await f.read(a,0,a.length,0);return{content:a.subarray(0,Math.min(b,65536)).toString("utf8"),truncated:b>65536}}finally{await f.close()}}function F(a,b,c){return{error:function(a){if(!a)return null;if(a.length<=32768)return a;let b=a.slice(0,32752);return(0,g.J8)(`${b}
|
|
4
4
|
…(已截断)`,`${b}
|
|
5
|
-
… (truncated)`)}(a?.error??c),extensions:a?.extensions??[],tools:a?.tools.map(a=>({name:a.name,label:a.label,state:a.state,description:a.description,promptSnippet:a.promptSnippet,promptGuidelineCount:a.promptGuidelineCount,promptGuidelinePreview:a.promptGuidelinePreview}))??[],skills:a?.skills.map(a=>({name:a.name,description:a.description,path:a.path,modelVisible:a.modelVisible}))??[],prompts:a?.prompts.map(a=>({name:a.name,description:a.description,path:a.path}))??[],themes:a?.themes??[],providers:a?.providers??[],piDesk:{methods:b?[...b.methods]:[],browserEntries:b?[...b.browserEntries]:[],messageDeclarations:b?[...b.messageDeclarations]:[]}}}class P{get restartRequired(){return this.deferredMaintenance.size>0}constructor(a,b=process.cwd(),c=(0,k.getAgentDir)()){this.workSessions=a,this.cwd=b,this.agentDir=c,this.operationTail=Promise.resolve(),this.operations=new Map,this.listeners=new Set,this.lifetime=new AbortController,this.disposed=!1,this.activeSource=null,this.sourceCache=null,this.capabilityCache=null,this.deferredMaintenance=new Map;const d=(0,h.createHash)("sha256").update(this.agentDir).digest("hex").slice(0,16);this.stagingRoot=(0,j.join)(this.cwd,"temp","pi",`plugin-management-${d}`),this.packageManagerCwd=(0,j.join)((0,f.M)(),"plugin-package-manager"),this.updates=new y.E(this.agentDir,this.packageManagerCwd,this.lifetime.signal),this.maintenanceError=process.env.PI_DESK_PLUGIN_MAINTENANCE_ERROR?.trim()||null,this.unsubscribeRuntime=(0,p.getL4PiGlobalPluginRuntime)().subscribeChanges(()=>this.publish()),this.staleStagingCleanup=(0,i.rm)(this.stagingRoot,{recursive:!0,force:!0}).catch(a=>{console.warn("[Pi Desk][PluginManagement] 清理上次中断的候选目录失败",{path:this.stagingRoot,errorName:a instanceof Error?a.name:"UnknownError"})})}list(a=!1){return this.assertOpen(),this.readSnapshot(a)}async batch(a){this.assertOpen();let b=[],c=new Set,d="add"===a.action||"update"===a.action?await this.readSources():null,e=[];for(let f of"add"===a.action?a.items:a.sources.map(a=>({source:a})))try{let g="add"===a.action?this.normalizeAddedSource(f.source):f.source,h=(0,m.LD)(g);if(c.has(h))throw new K("批量请求中包含重复来源");if(c.add(h),"add"===a.action){let{source:a,...b}=f;e.push(this.acceptMutation("add",g,d,!0,void 0,b))}else"update"===a.action?e.push(this.acceptMutation("update",g,d)):"del"===a.action?await this.del(g):await this.setUpdateTag(g,a.tag);b.push({source:f.source,error:null})}catch(a){b.push({source:f.source,error:C(a).slice(0,4e3)})}return e.length>0&&this.enqueueMutations(e),{snapshot:await this.readSnapshot(!1),results:b}}subscribe(a){return this.assertOpen(),this.listeners.add(a),()=>this.listeners.delete(a)}get(a){return this.assertOpen(),this.readDetail(a)}add(a,b={}){return this.mutate("add",this.normalizeAddedSource(a),!1,void 0,b)}setEnabled(a,b){return this.mutate(b?"enable":"disable",a)}async update(a){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护");this.assertSourceIdle(a);let b=(await this.readSources()).sources.find(b=>(0,m.LD)(b.source)===(0,m.LD)(a));if(!b)throw new J(a);if((0,m.ug)(b.source)){let a=await this.readSnapshot({checkUpdates:!0,sources:[b.source]}),c=a.plugins.find(a=>a.source===b.source);if(c.updateError)throw new L(c.updateError);if(!0!==c.updateAvailable)return a}return this.mutate("update",b.source)}reinstall(a,b,c={}){return this.mutate("add",this.normalizeAddedSource(a),!0,b,c)}async setUpdateTag(a,b){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护");let c=(await this.readSources()).sources.find(b=>(0,m.LD)(b.source)===(0,m.LD)(a));if(!c)throw new J(a);if("package"!==c.kind||!(0,m.ug)(c.source))throw new L("只有 npm 插件包支持更新渠道");this.assertSourceIdle(c.source),(0,o.ks)(c.source,m.mR.parse(b),this.agentDir),this.updates.clear(c.source),this.publish()}assertSourceIdle(a){let b=(0,m.LD)(a);if(this.activeSource&&(0,m.LD)(this.activeSource)===b||[...this.operations].some(([a,c])=>(0,m.LD)(a)===b&&"failed"!==c.phase))throw new K("该来源已有未完成的维护操作")}waitForOperations(a,b){return b=AbortSignal.any([b,this.lifetime.signal]),new Promise((c,d)=>{let e=()=>void 0,f=a=>{e(),b.removeEventListener("abort",g),a?d(a):c()},g=()=>f(Error(this.disposed?"插件管理已关闭":"发起命令的会话已关闭")),h=()=>{if(this.disposed)return f(Error("插件管理已关闭"));for(let b of a){let a=this.operations.get(b);if(a?.phase==="failed")return f(Error(a.message??"插件操作失败"));if(a?.phase==="waiting"&&this.activeSource!==b&&this.restartRequired)return f(Error(`插件尚未生效,需要在设置的插件管理中重启 Pi Desk。${a.message??""}`))}a.some(a=>this.operations.has(a)||this.activeSource===a)||f()};if(b.aborted)return g();e=this.subscribe(h),b.addEventListener("abort",g,{once:!0}),h()})}del(a){return this.mutate("del",a)}async apply(a){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不加载外部插件");if(a?.some(a=>this.deferredMaintenance.has(a)))throw new N;let b=await (0,p.getL4PiGlobalPluginRuntime)().scanSourceChanges(a);this.assertOpen();let c=b.filter(b=>{if(this.deferredMaintenance.has(b.source))return!1;let c=this.operations.get(b.source);if(!c||"failed"===c.phase)return!0;if(a)throw new K("该来源已有未完成操作");return!1}),d=new Set([...this.operations].filter(([,a])=>"failed"!==a.phase).map(([a])=>a));for(let a of c)d.add(a.source);if(d.size>32)throw new K("加载变更超过队列上限,请选择部分来源");for(let a of c){if(!this.operations.has(a.source)&&this.operations.size>=64){let a=[...this.operations].find(([,a])=>"failed"===a.phase);a&&this.operations.delete(a[0])}this.operations.set(a.source,{action:"apply",phase:"queued",message:null}),this.enqueueApply(a)}return this.publish(),this.readSnapshot(!1)}enqueueApply(a){this.runExclusive(async()=>{this.activeSource=a.source;try{this.setOperation(a.source,"checking",null),await this.probeSourceChange(a),this.assertOpen(),this.setOperation(a.source,"applying",null),await (0,p.getL4PiGlobalPluginRuntime)().applySourceChange(a),a.current?.path&&(0,u.tt)(a.current.path),a.previous?.path&&(0,u.tt)(a.previous.path),this.capabilityCache=null,this.operations.delete(a.source)}catch(b){this.setOperation(a.source,"failed",C(b))}finally{this.activeSource=null,this.sourceCache=null,this.publish()}}).catch(b=>{this.disposed||this.setOperation(a.source,"failed",C(b))})}async probeSourceChange(a){let b=a.current;if(!b||!b.enabled)return;if(b.error)throw new L(b.error);if(!b.path)throw new L("插件来源目录不存在");let c=performance.now();console.info("[Pi Desk][PluginManagement] 源码候选预检开始",{source:a.source});let d=(0,j.join)(this.stagingRoot,(0,h.randomUUID)()),e=(0,j.join)(d,"agent"),f=(0,j.join)(d,"workspace");await (0,i.mkdir)(e,{recursive:!0}),await (0,i.mkdir)(f,{recursive:!0});try{if(await (0,i.writeFile)((0,j.join)(e,"settings.json"),JSON.stringify({extensions:[b.path]}),"utf8"),b.piDeskRoot||b.nativePaths.length>0){let c=await (0,w.Y)(f,e,b.nativePaths.length>0),d=c.loadError??c.packages.find(a=>"failed"===a.status)?.error?.message;if(d)throw new L(d);if(b.piDeskRoot&&!c.packages.some(a=>"ready"===a.status))throw new L("预检未加载到候选 Node Entry,放弃本次变更");for(let b of c.packages)if(b.pluginName&&(0,p.getL4PiGlobalPluginRuntime)().readDiagnostics().packages.some(c=>c.source!==a.source&&"ready"===c.status&&c.pluginName===b.pluginName))throw new L(`插件名冲突:${b.pluginName}`)}this.assertOpen()}finally{await (0,i.rm)(d,{recursive:!0,force:!0}),console.info("[Pi Desk][PluginManagement] 源码候选预检结束",{source:a.source,durationMs:Math.round(performance.now()-c)})}}reload(a){return this.activeSource||[...this.operations].some(([a,b])=>"failed"!==b.phase&&!this.deferredMaintenance.has(a))?Promise.reject(new K("维护仍在执行或等待,请先完成当前操作")):this.runExclusive(async()=>(this.assertRestartAvailable(),this.restartWhenQuiet(a)))}async mutate(a,b,c=!1,d,e={}){this.assertOpen();let f=await this.readSources(),g=this.acceptMutation(a,b,f,c,d,e);return this.enqueueMutations([g]),this.readSnapshot(!1)}acceptMutation(a,b,c,d=!1,f,g={}){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护,请通过基础聊天修复或正常启动后维护");let h=c.sources.find(a=>(0,m.LD)(a.source)===(0,m.LD)(b));if("add"!==a){if(!h)throw new J(b);if("package"!==h.kind&&"enable"!==a&&"disable"!==a)throw new L("裸扩展不是已安装包,请编辑源码后加载变更;此操作不会删除源码")}let i=(f??=h?.source)??b;if(g.tag&&!(0,m.ug)(b))throw new L("只有 npm 插件包支持更新渠道");for(let a of[b,i])this.assertSourceIdle(a);if([...this.operations.values()].filter(a=>"failed"!==a.phase).length>=32)throw new K("插件维护队列已满,请等待当前操作完成");if(this.operations.size>=64){let a=[...this.operations].find(([,a])=>"failed"===a.phase);a&&this.operations.delete(a[0])}return f&&f!==b&&this.operations.get(f)?.phase==="failed"&&this.operations.delete(f),this.operations.set(i,{action:a,phase:"queued",message:null}),this.updates.clear(i),this.updates.clear(b),{mutation:a,source:b,operationSource:i,reinstall:d,options:g}}enqueueMutations(a){this.runExclusive(async()=>{let b=performance.now(),c=await Promise.all(a.map(async a=>{try{let b=await this.prepareMutation(a);return this.assertOpen(),this.setOperation(a.operationSource,"queued","候选检查完成,等待应用"),{input:a,prepared:b}}catch(b){return this.setOperation(a.operationSource,"failed",C(b)),null}}));for(let d of(a.length>1&&console.info("[Pi Desk][PluginManagement] 批量并行准备收尾",{count:a.length,failedCount:c.filter(a=>null===a).length,durationMs:Math.round(performance.now()-b)}),c)){if(!d)continue;let{input:a,prepared:b}=d,{source:c,operationSource:e}=a;this.activeSource=e;try{this.assertOpen(),b&&await this.executeMutation(a,b),this.deferredMaintenance.has(e)||this.operations.delete(e)}catch(a){this.setOperation(e,"failed",C(a))}finally{this.updates.clear(e),this.updates.clear(c),this.sourceCache=null,this.activeSource=null,this.publish()}}}).catch(b=>{if(!this.disposed)for(let c of a)this.setOperation(c.operationSource,"failed",C(b))}),this.publish()}async prepareMutation(a){let{mutation:b,source:c,operationSource:d,reinstall:e,options:f}=a;this.assertOpen();let g=this.createPackageManager();this.throwSettingsErrors(g.settingsManager);let h=g.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope),i=h.find(a=>a.source===d),j=null,k=null,l=null;if("enable"!==b&&"disable"!==b){var n;let a=await (0,r.c)({agentDir:this.agentDir,configured:h,repairSource:"add"===b&&e?d:void 0});if(a)throw new M(a);if("add"!==b&&!i)throw new J(c);this.setOperation(d,"checking","正在确认插件版本和下载源");let g=this.candidateSource(c,i?.installedPath),o=(0,m.ug)(g),p="del"===b?{source:g,updateTag:null}:await this.updates.resolveInstall(g,d,f,"update"===b);if(k=p.updateTag,"update"===b&&o&&i?.installedPath){let a=await D(i.installedPath),b=p.source.slice(p.source.lastIndexOf("@")+1);if(!a.version)throw new L("无法读取插件已安装版本");if(!(0,m.zj)(b,a.version))return null}j={...o&&"del"!==b&&(e||i||"update"===b)?{action:"reinstall",source:p.source}:(n=p.source,{action:"add"===b?"install":"update"===b?"update":"remove",source:n}),..."registry"in p&&p.registry?{registry:p.registry}:{}},"del"!==b&&(l=await this.probeCandidate(p.source,j.registry))}return{request:j,updateTag:k,pluginName:l}}async executeMutation(a,b){let{mutation:c,source:d,operationSource:e}=a,{request:f,updateTag:g,pluginName:h}=b,i=(0,p.getL4PiGlobalPluginRuntime)(),j=a=>this.setOperation(e,"waiting",a);if(f&&(this.assertPluginNameAvailable(h,e),g&&((0,o.ks)(e,g,this.agentDir),this.updates.clear(e)),this.deferredMaintenance.size>0)){this.deferredMaintenance.set(e,f),j("等待重启后完成安装维护");return}this.assertOpen(),await i.withSourceIdle(e,async()=>{if(f){let b=this.createPackageManager();this.throwSettingsErrors(b.settingsManager);let d=b.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope),f=await (0,r.c)({agentDir:this.agentDir,configured:d,repairSource:"add"===c&&a.reinstall?e:void 0});if(f)throw new M(f)}if(this.assertOpen(),this.setOperation(e,"applying",f?.registry?`下载源:${f.registry}`:null),"enable"===c||"disable"===c){let a=(0,o.to)(this.agentDir).disabled.includes((0,m.LD)(d));(0,o.El)(d,"enable"===c,this.agentDir),this.sourceCache=null;try{if(await this.applyMutationSources([d],!0),"enable"===c&&!(await this.readSources()).sources.find(a=>a.source===d)?.enabled)throw new L("此插件仍被 Pi 配置排除,请先调整原有资源配置")}catch(b){throw(0,o.El)(d,!a,this.agentDir),this.sourceCache=null,b}}else if(f)try{await i.replaceSource(e,null),await (0,s.V)(async()=>{await (0,q.wC)({maintenance:f,agentDir:this.agentDir,cwd:this.packageManagerCwd}),"del"!==c&&await this.verifyInstalledPackage(f.source)}),this.sourceCache=null,await this.applyMutationSources([e,f.source],!1)}catch(a){if(a instanceof q.rZ&&"locked"===a.kind&&(0,x.k)())this.deferredMaintenance.set(e,f),j("文件正在被使用,需要重启后完成操作");else throw a}this.updates.clear(e),this.updates.clear(d),this.capabilityCache=null},this.lifetime.signal,j)}async verifyInstalledPackage(a){let b=this.createPackageManager();this.throwSettingsErrors(b.settingsManager);let c=(0,m.LD)(a),d=b.packageManager.listConfiguredPackages().find(a=>"user"===a.scope&&(0,m.LD)(a.source)===c);if(!d?.installedPath)throw new L("插件安装后没有有效目录");await this.verifyPackageVersion(a,d.installedPath)}async verifyPackageVersion(a,b){let c=await D(b);if(c.error)throw new L("string"==typeof c.error.message?c.error.message:c.error.message.default);if((0,m.ug)(a)){let b=a.slice(a.lastIndexOf("@")+1);if(c.version!==b)throw new L(`插件实际安装版本与目标不一致:${c.version??"未知"},目标 ${b}`)}}async applyMutationSources(a,b){let c=new Set(a.map(m.LD)),d=(0,p.getL4PiGlobalPluginRuntime)(),e=await d.scanSourceChanges(),f=await this.readSources(),g=[...new Set([...e.filter(a=>c.has((0,m.LD)(a.source))).map(a=>a.source),...f.sources.filter(a=>c.has((0,m.LD)(a.source))).map(a=>a.source)])];for(let a of g.length?await d.scanSourceChanges(g):[])b&&await this.probeSourceChange(a),await d.applySourceChange(a),a.current?.path&&(0,u.tt)(a.current.path),a.previous?.path&&(0,u.tt)(a.previous.path)}dispose(){this.disposed||(this.disposed=!0,this.lifetime.abort(),this.unsubscribeRuntime(),this.listeners.clear())}assertOpen(){if(this.disposed)throw new K("插件管理已关闭")}setOperation(a,b,c){let d=this.operations.get(a);if(!d)return;let e=c?.slice(0,4e3)??null;(d.phase!==b||d.message!==e)&&(this.operations.set(a,{...d,phase:b,message:e}),"failed"===b&&console.warn("[Pi Desk][PluginManagement] 插件操作失败",{source:a,action:d.action,message:e}),this.publish())}publish(){if(!this.disposed)for(let a of this.listeners)try{a()}catch(a){console.warn("[Pi Desk][PluginManagement] 状态监听失败",{message:C(a)})}}async readSources(){let a=()=>null!==this.activeSource&&this.operations.get(this.activeSource)?.phase==="applying";if(a()&&this.sourceCache)return this.sourceCache;let b=await (0,t.o)(this.packageManagerCwd,this.agentDir,{DefaultPackageManager:k.DefaultPackageManager,SettingsManager:k.SettingsManager});return a()&&this.sourceCache||(this.sourceCache=b),a()&&this.sourceCache?this.sourceCache:b}async probeCandidate(a,b){let c=(0,j.join)(this.stagingRoot,(0,h.randomUUID)()),d=(0,j.join)(c,"agent"),e=(0,j.join)(c,"workspace");await (0,i.mkdir)(e,{recursive:!0}),console.info("[Pi Desk][PluginManagement] 开始在隔离 AgentDir 预检候选插件",{source:a});try{if(!b&&(0,m.ug)(a))for(let b of[".npmrc",(0,j.join)("etc","npmrc")]){let c=(0,j.join)(d,"npm",b);await (0,i.mkdir)((0,j.dirname)(c),{recursive:!0});try{await (0,i.copyFile)((0,j.join)(this.agentDir,"npm",b),c),console.info("[Pi Desk][PluginManagement] 已为隔离预检继承本机 npm 配置",{source:a,configPath:b})}catch(a){if("ENOENT"!==a.code)throw new L(`无法继承本机 npm 配置(${b}):${C(a)}`)}}await (0,q.wC)({maintenance:{action:"install",source:a,...b?{registry:b}:{}},agentDir:d,cwd:e,signal:this.lifetime.signal}),this.assertOpen();let c=this.createPackageManager(d,e);this.throwSettingsErrors(c.settingsManager);let f=c.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope)[0];if(!f?.installedPath)throw new L("候选插件安装后没有有效目录");await this.verifyPackageVersion(a,f.installedPath);let g=await (0,w.Y)(e,d,!0,this.lifetime.signal);if(g.loadError)throw new L(g.loadError);let h=g.packages.find(a=>"failed"===a.status);if(h?.error)throw new L(h.error.message);let k=g.packages[0]?.pluginName??null;return this.assertOpen(),console.info("[Pi Desk][PluginManagement] 候选插件隔离预检通过",{source:a}),k}catch(a){if(a instanceof L)throw a;throw new L(C(a))}finally{await (0,i.rm)(c,{recursive:!0,force:!0}).catch(a=>{console.warn("[Pi Desk][PluginManagement] 清理候选插件目录失败",{path:c,errorName:a instanceof Error?a.name:"UnknownError"})})}}assertPluginNameAvailable(a,b){if(a&&(0,p.getL4PiGlobalPluginRuntime)().readDiagnostics().packages.some(c=>c.source!==b&&c.pluginName===a))throw new L(`pluginName 已由其他 Package 注册:${a}`)}restartWhenQuiet(a){return this.workSessions.runPluginRestart(async()=>{let b=(0,p.getL4PiGlobalPluginRuntime)(),c=await this.readSnapshot(!1);return await b.prepareReload(),console.info("[Pi Desk][PluginManagement] 插件 Runtime 已通过静默检查,准备重启",{deferredCount:this.deferredMaintenance.size}),(0,x.Z)("basic"===a||0===this.deferredMaintenance.size?void 0:[...this.deferredMaintenance.values()],a),c})}async readDetail(a){if((0,e.P)())throw new K("基础模式不执行插件能力盘点");let b=(await this.readSources()).sources.find(b=>b.source===a),c=b?await (0,t.W)(b):null;if(!c)throw new J(a);let d=await this.readCapabilities(!1),f=d.packages.find(b=>b.source===a);if(!f)throw Error(d.loadError??`插件能力详情不可用:${a}`);let[g,h]=await Promise.all([Promise.all(f.skills.map(async a=>({name:a.name,description:a.description,path:a.path,modelVisible:a.modelVisible,...await E(c,a.filePath)}))),Promise.all(f.prompts.map(async a=>({name:a.name,description:a.description,path:a.path,...await E(c,a.filePath)})))]);return l.tA.parse({source:a,readme:await (0,n.w$)(c),tools:f.tools.map(a=>({name:a.name,label:a.label,state:a.state,description:a.description,parameters:a.parameters,promptSnippet:a.promptSnippetDetail,promptGuidelines:a.promptGuidelines})),skills:g,prompts:h})}async readSnapshot(a){if((0,e.P)())return{plugins:[],restartRequired:!1,loadError:this.maintenanceError};let b=this.createPackageManager(),c=b.settingsManager.drainErrors().map(a=>a.error.message),d=b.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope),f=await (0,r.c)({agentDir:this.agentDir,configured:d}),h=await this.readSources(),i=await this.updates.read(h.sources,"boolean"==typeof a?{checkUpdates:a}:a),j=(0,p.getL4PiGlobalPluginRuntime)(),k=j.readDiagnostics(),n=new Map(k.packages.map(a=>[a.source,a])),q=(0,u.u7)(),s=this.capabilityCache??{packages:[],loadError:null},t=new Map(s.packages.map(a=>[a.source,a])),v=new Map(j.readCapabilityRegistrations().map(a=>[a.source,a])),w=await Promise.all(h.sources.map(async a=>{let b=n.get(a.source),c=a.path?this.findNativeDiagnostic(a.path,q):null,d=(a.error?{phase:"package"===a.kind?"package":"entry",message:a.error}:null)??(b?.status==="failed"?b.error:null)??(c?{phase:"native",message:c}:null);return{source:a.source,kind:a.kind,operation:this.operationFor(a.source),pluginName:b?.pluginName??null,description:a.description,version:a.version??b?.version??null,updateAvailable:i.get(a.source)?.updateAvailable??null,updateTag:i.get(a.source)?.updateTag??null,availableVersion:i.get(a.source)?.availableVersion??null,updateError:i.get(a.source)?.updateError??null,status:a.enabled?d?"failed":b?.status==="ready"?"ready":"available":"disabled",error:d,capabilities:F(t.get(a.source),v.get(a.source),s.loadError)}}));for(let[a,b]of this.operations)w.some(b=>(0,m.LD)(b.source)===(0,m.LD)(a))||w.push({source:a,kind:"package",operation:b,pluginName:null,description:null,version:null,updateAvailable:null,updateTag:(0,m.ug)(a)?(0,o.ey)(a,this.agentDir):null,availableVersion:null,updateError:null,status:"failed"===b.phase?"failed":"available",error:null,capabilities:F(void 0,void 0,null)});return l.oP.parse({plugins:w.sort((a,b)=>a.source.localeCompare(b.source)),restartRequired:this.restartRequired,loadError:function(a){let b=[...new Map(a.flatMap(a=>{let b=("string"==typeof a?a:a.message).trim();return b?[[b,{defaultText:b,englishText:"string"==typeof a?b:a.englishMessage.trim()}]]:[]})).values()];if(0===b.length)return null;let c=b.map(a=>a.defaultText).join("; ");return b.every(a=>a.defaultText===a.englishText)?c:(0,g.J8)(c,b.map(a=>a.englishText).join("; "))}([...c,...h.errors,...k.loadError?[k.loadError]:[],...this.maintenanceError?[this.maintenanceError]:[],...f?[f]:[]])})}async readCapabilities(a){if(!a&&this.capabilityCache)return this.capabilityCache;try{return this.capabilityCache=await (0,s.V)(()=>(this.assertOpen(),!a&&this.capabilityCache)?Promise.resolve(this.capabilityCache):(0,v.a)(this.cwd,this.agentDir)),this.publish(),console.info("[Pi Desk][PluginManagement] 插件能力盘点完成",{packageCount:this.capabilityCache.packages.length,hasLoadError:null!==this.capabilityCache.loadError}),this.capabilityCache}catch(b){let a=C(b);return console.warn("[Pi Desk][PluginManagement] 插件能力盘点失败",{errorName:b instanceof Error?b.name:"UnknownError",message:a}),this.capabilityCache={packages:[],loadError:a},this.publish(),this.capabilityCache}}findNativeDiagnostic(a,b){let c,d=(c=(0,j.resolve)(a).replaceAll("\\","/"),"win32"===process.platform?c.toLowerCase():c),e=b.find(a=>("win32"===process.platform?a.message.replaceAll("\\","/").toLowerCase():a.message.replaceAll("\\","/")).includes(d));return e?.message??null}createPackageManager(a=this.agentDir,b=this.packageManagerCwd){let c=k.SettingsManager.create(b,a,{projectTrusted:!1});return{settingsManager:c,packageManager:new k.DefaultPackageManager({cwd:b,agentDir:a,settingsManager:c})}}candidateSource(a,b){return(0,j.isAbsolute)(a)||/^(?:[a-z][a-z0-9+.-]*:|git@)/i.test(a)?a:b?(0,j.resolve)(b):(0,j.resolve)(this.agentDir,a)}operationFor(a){let b=(0,m.LD)(a);return[...this.operations].find(([a])=>(0,m.LD)(a)===b)?.[1]??null}normalizeAddedSource(a){return/^(?:@[a-z0-9_.-]+\/)?[a-z0-9][a-z0-9_.-]*(?:@[^\s/]+)?$/i.test(a)?`npm:${a}`:(0,j.isAbsolute)(a)||/^(?:[a-z][a-z0-9+.-]*:|git@)/i.test(a)?a:(0,j.resolve)(this.cwd,a)}throwSettingsErrors(a){let b=a.drainErrors();if(0!==b.length)throw Error(b.map(a=>a.error.message).join("; "))}assertRestartAvailable(){if(!(0,x.k)())throw new O}runExclusive(a){let b=()=>this.staleStagingCleanup.then(()=>(this.assertOpen(),a())),c=this.operationTail.then(b,b);return this.operationTail=c.then(()=>void 0,()=>void 0),c}}function G(){globalThis.__piDeskPluginManagement?.dispose()}function H(a){globalThis.__piDeskPluginManagement||(globalThis.__piDeskPluginManagement=new P(a))}function I(){if(!globalThis.__piDeskPluginManagement)throw Error("插件管理尚未完成进程级装配");return globalThis.__piDeskPluginManagement}d()}catch(a){d(a)}})},53584:(a,b,c)=>{c.d(b,{a:()=>l});var d=c(76760),e=c(36153),f=c(86148),g=c(2472);let h="__PI_DESK_PLUGIN_CAPABILITIES__",i=e.Yj(),j=e.Ik({name:e.Yj(),description:e.Yj().nullable()}).strict(),k=e.Ik({packages:e.YO(e.Ik({source:e.Yj(),error:e.Yj().nullable(),extensions:e.YO(e.Ik({path:e.Yj(),events:e.YO(e.Ik({name:e.Yj(),count:e.ai().int().positive()}).strict()),commands:e.YO(j),shortcuts:e.YO(e.Ik({shortcut:e.Yj(),description:e.Yj().nullable()}).strict()),flags:e.YO(e.Ik({name:e.Yj(),type:e.k5(["boolean","string"]),description:e.Yj().nullable(),default:e.KC([e.zM(),e.Yj(),e.ch()])}).strict()),messageRenderers:e.YO(e.Yj()),entryRenderers:e.YO(e.Yj())}).strict()),tools:e.YO(e.Ik({name:e.Yj(),label:i,state:e.k5(["active","inactive","shadowed"]),description:i,parameters:e.g1(e.Yj(),e.Pq()),promptSnippet:i.nullable(),promptSnippetDetail:i.nullable(),promptGuidelines:e.YO(i),promptGuidelineCount:e.ai().int().nonnegative(),promptGuidelinePreview:i.nullable()}).strict()),skills:e.YO(e.Ik({name:e.Yj(),description:e.Yj(),path:e.Yj(),filePath:e.Yj(),modelVisible:e.zM()}).strict()),prompts:e.YO(e.Ik({name:e.Yj(),description:e.Yj(),path:e.Yj(),filePath:e.Yj()}).strict()),themes:e.YO(e.Ik({name:e.Yj(),path:e.Yj()}).strict()),providers:e.YO(e.Ik({name:e.Yj(),kind:e.k5(["config","native"])}).strict())}).strict()),loadError:e.Yj().nullable()}).strict();async function l(a,b){let c=(0,f.I)(),e=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-plugin-capability-probe-runner.mts"),{stdout:i,stderr:j,code:l}=await (0,g.i)({args:["--conditions=react-server","--import",c,e],agentDir:b,env:{PI_DESK_PLUGIN_CAPABILITY_AGENT_DIR:b,PI_DESK_PLUGIN_CAPABILITY_CWD:a},maxOutputBytes:4194304,timeoutMs:3e4,timeoutError:()=>Error("插件能力盘点超时")});if(0!==l)throw Error(j.trim()||`插件能力盘点进程退出码 ${l??"null"}`);let m=i.lastIndexOf(h);if(m<0)throw Error("插件能力盘点没有返回有效结果");let n=i.slice(m+h.length).split(/\r?\n/,1)[0];return k.parse(JSON.parse(n))}},64253:(a,b,c)=>{c.a(a,async(a,d)=>{try{let s;c.d(b,{B:()=>q,I:()=>r});var e=c(31421),f=c(73024),g=c(51455),h=c(76760),i=c(48161),j=c(57975),k=c(75430),l=a([k]);k=(l.then?(await l)():l)[0];let t=(0,j.promisify)(e.execFile);function m(a){return a.replace(/\$\{([^}]+)\}/g,(a,b)=>process.env[b]??a)}async function n(a,b){let c;try{let b=await (0,g.readFile)(a);if(b.length>262144)throw Error("npm 配置文件过大");c=b.toString("utf8")}catch(a){if("ENOENT"===a.code)return;throw a}for(let a of c.split(/\r?\n/)){let c=/^\s*([^;#][^=]*?)\s*=\s*(.*?)\s*$/.exec(a);if(!c)continue;let d=c[2].replace(/\s+[;#].*$/,"").replace(/^(['"])(.*)\1$/,"$2");b[c[1].trim()]=m(d)}}function o(a,b){return("win32"===process.platform?/^~[\\/]/:/^~\//).test(a)?(0,h.resolve)((0,i.homedir)(),a.slice(2)):(0,h.resolve)(b,a)}async function p(a,b){let c={};for(let[a,b]of Object.entries(process.env))if(void 0!==b&&""!==b&&/^npm_config_/i.test(a)){let d=a.slice(11);c[d.startsWith("//")?d:d.replace(/(?!^)_/g,"-").toLowerCase()]=m(b)}let d=function(){for(let a of[(0,h.dirname)(process.execPath),...(process.env.PATH??"").split("win32"===process.platform?";":":")])for(let b of[(0,h.join)(a,"node_modules/npm/bin/npm-cli.js"),(0,h.resolve)(a,"../lib/node_modules/npm/bin/npm-cli.js")])if((0,f.existsSync)(b))return b}(),e={};if(d)try{await (0,g.mkdir)(a,{recursive:!0});let c=await t(process.execPath,[d,"config","list","--json","--prefix",b],{cwd:a,timeout:4e3,maxBuffer:524288,windowsHide:!0});e=JSON.parse(c.stdout)}catch{console.warn("[Pi Desk][PluginRegistry] npm 有效配置读取失败,改用 npmrc 和环境配置")}let j={};d&&await n((0,h.resolve)((0,h.dirname)(d),"../npmrc"),j);let k="string"==typeof e.globalconfig?e.globalconfig:c.globalconfig??(0,h.join)(b,"etc/npmrc"),l="string"==typeof e.userconfig?e.userconfig:c.userconfig??(0,h.join)((0,i.homedir)(),".npmrc");for(let[d,f]of(await n(o(k,a),j),await n(o(l,a),j),!0!==e.global&&"true"!==c.global&&"global"!==e.location&&"global"!==c.location&&await n((0,h.join)(b,".npmrc"),j),Object.entries(e)))"string"!=typeof f||"(protected)"===f||/auth|password|username/i.test(d)||(j[d]=f);return{...j,...c}}function q(a=(0,k.getAgentDir)()){let b=process.env.PI_DESK_PACKAGE_MAINTENANCE_CWD??(0,h.join)(a,"pi-desk","plugin-package-manager"),c=(0,h.join)(a,"npm");if(!s||s.cwd!==b||s.prefix!==c||s.expires<=Date.now()){let a=p(b,c);s={cwd:b,prefix:c,expires:Date.now()+3e4,value:a},a.catch(()=>{s?.value===a&&(s=void 0)})}return s.value}function r(a,b){let c=`//${a.host}${a.pathname}`;for(let a of Object.keys(b).flatMap(a=>{let b=/^(\/\/.*\/):(?:_authToken|_auth|username|_password)$/i.exec(a);return b&&c.startsWith(b[1])?[b[1]]:[]}).sort((a,b)=>b.length-a.length)){let c=b[`${a}:_authToken`]??b[`${a}:_authtoken`];if(c&&!c.includes("${"))return`Bearer ${c}`;let d=b[`${a}:_auth`];if(d&&!d.includes("${"))return`Basic ${d}`;let e=b[`${a}:username`],f=b[`${a}:_password`];if(e&&f&&!f.includes("${"))return`Basic ${Buffer.from(`${e}:${Buffer.from(f,"base64").toString("utf8")}`).toString("base64")}`}let d=b.registry;if(d){let c=new URL(d);if(a.origin===c.origin&&a.pathname.startsWith(`${c.pathname.replace(/\/+$/,"")}/`)){let a=b._authToken??b._authtoken;if(a&&!a.includes("${"))return`Bearer ${a}`;if(b._auth&&!b._auth.includes("${"))return`Basic ${b._auth}`}}}d()}catch(a){d(a)}})},69371:(a,b,c)=>{c.d(b,{rZ:()=>g,wC:()=>h});var d=c(76760),e=c(86148),f=c(2472);class g extends Error{constructor(a,b,c){super(b.slice(-4e3)||`Pi Package 命令退出码 ${c??"null"}`),this.kind=a,this.output=b,this.exitCode=c,this.name="L4PiPackageMaintenanceError"}}async function h(a){let b=(0,e.I)(),c=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-package-maintenance-runner.mts"),{stdout:h,stderr:i,code:j}=await (0,f.i)({args:["--import",b,c,a.maintenance.action,a.maintenance.source,...a.maintenance.registry?[a.maintenance.registry]:[]],agentDir:a.agentDir,env:{PI_DESK_PACKAGE_MAINTENANCE_CWD:a.cwd},maxOutputBytes:1048576,timeoutMs:12e4,signal:a.signal,timeoutError:()=>new g("failed","包维护超过120秒,已停止;结果未确认,请检查配置后手动处理",null)});if(0===j)return;let k=(i||h).trim();throw new g(function(a){let b=a.toLowerCase();if(b.includes("ebusy")||b.includes("etxtbsy")||b.includes("resource busy")||b.includes("being used by another process")||b.includes("used by another process")||b.includes("process cannot access the file because it is being used"))return"locked";let c=b.includes("eperm")||b.includes("eacces")||b.includes("operation not permitted"),d=/\b(unlink|rename|rmdir|rimraf|remove|cleanup)\b/.test(b);return c&&d?"locked":"failed"}(k),k,j)}},69375:(a,b,c)=>{c.d(b,{Od:()=>r,tU:()=>n,hE:()=>q,P9:()=>f,_G:()=>j,Vc:()=>i});var d=c(36153);d.Yj().uuid();let e=d.Ik({key:d.Yj().min(1).max(160),params:d.g1(d.Yj().min(1).max(80),d.KC([d.Yj().max(1e3),d.ai().finite()])).optional()}).strict(),f=4001,g=d.Yj().trim().min(1),h=d.Yj().uuid();function i(a){return Object.freeze({op:"req",path:g.parse(a.path),inputSchema:a.inputSchema,outputSchema:a.outputSchema,...void 0===a.timeoutMs?{}:{timeoutMs:d.ai().int().positive().parse(a.timeoutMs)}})}function j(a){return Object.freeze({op:"push",path:g.parse(a.path),bodySchema:a.bodySchema})}let k=d.Ik({op:d.eu("req"),path:g,requestId:h}).strict(),l=d.Ik({op:d.eu("resp"),path:g,requestId:h}).strict(),m=d.Ik({op:d.eu("push"),path:g}).strict(),n=d.Ik({head:k,body:d.Pq()}).strict(),o=d.Ik({head:l,body:d.Ik({code:d.eu(0),msg:d.eu(""),data:d.Pq()}).strict()}).strict(),p=d.Ik({head:l,body:d.Ik({code:d.ai().int().positive(),msg:d.Yj().min(1),data:d.ch(),i18n:e.optional()}).strict()}).strict(),q=d.KC([o,p]),r=d.Ik({head:m,body:d.Pq()}).strict()},72497:(a,b,c)=>{c.d(b,{Dz:()=>h,f7:()=>g,tv:()=>f});var d=c(36153);let e=d.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=e,g=e,h=d.g1(d.Yj(),d.Pq());d.Yj().trim().min(3).max(129).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*\/[a-z0-9]+(?:-[a-z0-9]+)*$/);let i=d.k5(["plugin","server","rocket","settings","panel","message","terminal","file","folder","bot","wrench","database","globe"]);d.gM("type",[d.Ik({type:d.eu("builtin"),name:i}).strict(),d.Ik({type:d.eu("svg"),content:d.Yj().trim().min(1).max(16384)}).strict()])},73159:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{NL:()=>h,XH:()=>j,Yq:()=>i});var e=c(77598),f=c(64253),g=a([f]);f=(g.then?(await g)():g)[0];class j extends Error{constructor(a,b=502,c="invalid"){super(a),this.status=b,this.reason=c,this.name="L4PluginRegistryError"}}let k=new Map,l=0;async function h(a,b){b.signal?.throwIfAborted();let c=!1===b.auth?{}:await (0,f.B)(b.agentDir),d=(0,f.I)(a,c),g=`${a.href}:${b.limit}:${(0,e.createHash)("sha256").update(d??"").digest("hex")}`,h=k.get(g);if(!1!==b.cache&&h&&h.expires>Date.now())return h.body;let i=AbortSignal.any([AbortSignal.timeout(b.timeout??1e4),...b.signal?[b.signal]:[]]),m=a;try{for(let a=0;a<=3;a++){let d=(0,f.I)(m,c),e=await fetch(m,{signal:i,redirect:"manual",headers:d?{Authorization:d}:{}});if([301,302,303,307,308].includes(e.status)){await e.body?.cancel();let b=e.headers.get("location");if(!b||3===a)throw new j("插件源重定向无效");let c=new URL(b,m);if(!["http:","https:"].includes(c.protocol)||c.username||c.password||"https:"===m.protocol&&"https:"!==c.protocol)throw new j("插件源重定向不安全");m=c;continue}if(!e.ok){await e.body?.cancel();let a=404===e.status?"missing":[401,403].includes(e.status)?"denied":e.status>=500?"network":"invalid";throw new j(`插件源请求失败(HTTP ${e.status})`,e.status,a)}if(Number(e.headers.get("content-length")??0)>b.limit)throw await e.body?.cancel(),new j("插件源响应超过大小限制");let h=e.body?.getReader(),n=[],o=0;if(h)try{for(;;){let a=await h.read();if(a.done)break;if((o+=a.value.byteLength)>b.limit)throw new j("插件源响应超过大小限制");n.push(a.value)}}finally{await h.cancel().catch(()=>void 0),h.releaseLock()}let p=Buffer.concat(n);if(!1!==b.cache){for(let[a,b]of k)(b.expires<=Date.now()||a===g)&&(k.delete(a),l-=b.body.length);for(;k.size>=96||l+p.length>0x1800000;){let a=k.entries().next().value;if(!a)break;k.delete(a[0]),l-=a[1].body.length}p.length<=0x1800000&&(k.set(g,{body:p,expires:Date.now()+12e4}),l+=p.length)}return p}throw new j("插件源重定向过多")}catch(a){if(b.signal?.aborted)throw b.signal.reason;if(a instanceof j)throw a;throw new j("插件源网络连接失败或超时",502,"network")}}async function i(a,b,c){let d=await h(a,{limit:8388608,signal:b,agentDir:c});try{let a=JSON.parse(d.toString("utf8"));if(!a||"object"!=typeof a||Array.isArray(a))throw Error("invalid");return a}catch{throw new j("插件源返回的元数据格式无效")}}d()}catch(a){d(a)}})},75157:(a,b,c)=>{c.d(b,{c:()=>h});var d=c(51455),e=c(76760);function f(a){if(!a.startsWith("npm:"))return null;let b=a.slice(4).trim(),c=b.match(/^(@?[^@]+(?:\/[^@]+)?)(?:@(.+))?$/);return c?.[1]??(b||null)}async function g(a){try{return(await (0,d.stat)(a)).isDirectory()}catch{return!1}}async function h(a){let b=a.configured.flatMap(a=>{let b=f(a.source);return b?[{name:b,item:a}]:[]}),c=(0,e.join)(a.agentDir,"npm","package.json"),h={};try{let a=JSON.parse(await (0,d.readFile)(c,"utf8"));a.dependencies&&"object"==typeof a.dependencies&&(h=a.dependencies)}catch(c){if(0===b.length)return null;let a=c instanceof Error&&c.message?c.message:String(c);return{message:`Pi Package npm 根不可用:${a}`,englishMessage:`Pi Package npm root is unavailable: ${a}`,i18n:{key:"errors:pluginNpmRootUnavailable",params:{detail:a.slice(0,1e3)}}}}let i=a.repairSource?f(a.repairSource):null,j=b.filter(a=>a.name!==i),k=new Set(j.map(a=>a.name)),l=new Set(Object.keys(h)),m=[...k].filter(a=>!l.has(a)),n=[];for(let{name:a,item:b}of j)b.installedPath&&await g(b.installedPath)||n.push(a);if(0===m.length&&0===n.length)return null;let o=[m.length>0?`缺少声明:${m.join("、")}`:null,n.length>0?`缺少目录:${n.join("、")}`:null].filter(a=>null!==a),p=[m.length>0?`missing declarations: ${m.join(", ")}`:null,n.length>0?`missing folders: ${n.join(", ")}`:null].filter(a=>null!==a),q=m.length>0?n.length>0?"errors:pluginNpmRootMissingBoth":"errors:pluginNpmRootMissingDeclarations":"errors:pluginNpmRootMissingFolders";return{message:`Pi Package 配置与 npm 根不一致(${o.join(";")})`,englishMessage:`Pi Package configuration does not match the npm root (${p.join("; ")})`,i18n:{key:q,params:{declarations:m.join(", ").slice(0,1e3),folders:n.join(", ").slice(0,1e3)}}}}},76019:(a,b,c)=>{c.d(b,{J8:()=>f,fD:()=>g,qf:()=>e});var d=c(36153);let e=d.KC([d.Yj(),d.Ik({default:d.Yj(),translations:d.g1(d.Yj().min(1).max(35),d.Yj()).refine(a=>Object.keys(a).length<=16,"too many translations")}).strict()]);function f(a,b){return{default:a,translations:{en:b}}}function g(a,b){return"string"==typeof a?a:a.translations[b]??a.translations[b.split("-")[0]]??a.default}},78597:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{E:()=>k});var e=c(75430),f=c(4287),g=c(5235),h=c(34458),i=c(47154),j=a([e,g,h]);[e,g,h]=j.then?(await j)():j;class k{constructor(a,b,c){this.agentDir=a,this.cwd=b,this.signal=c,this.cache=new Map}async resolveInstall(a,b,c,d){let e=(0,f.ug)(a),i=e?/^npm:(?:@[^/]+\/)?[^@]+@([^@]+)$/.exec(a)?.[1]:void 0,j=i&&!/^v?\d+\./.test(i)&&f.mR.safeParse(i).success?i:null,k=e?d?(0,g.ey)(b,this.agentDir):c.tag??j??(0,g.ey)(b,this.agentDir):null,l=e&&k&&(d||!i)?`npm:${e}@${k}`:a;return{...await (0,h.dz)(l,{...c,agentDir:this.agentDir,signal:this.signal,cache:!d&&void 0}),updateTag:k}}clear(a){let b=(0,f.LD)(a);for(let[a,c]of this.cache)c.identity===b&&this.cache.delete(a)}async read(a,b){for(let[a,b]of this.cache)b.expiresAt<=Date.now()&&this.cache.delete(a);let c=b.sources?new Set(b.sources.map(f.LD)):null,d=new Map;for(let j of a){if("package"!==j.kind)continue;let a=(0,f.LD)(j.source),k=(0,f.ug)(j.source),l=k?(0,g.ey)(j.source,this.agentDir):null,m={updateTag:l,updateAvailable:null,availableVersion:null,updateError:null};d.set(j.source,m);let n=!0===b.checkUpdates&&(!c||c.has(a))&&(!b.tag||b.tag===l);if(k){if(!n&&![...this.cache.values()].some(b=>b.identity===a))continue;let b=null;try{let c=(0,g.to)(this.agentDir).downloadSource,e=await (0,h.qX)(k,{agentDir:this.agentDir,downloadSource:c});b=JSON.stringify([a,l,c.mode,e.registry,e.fallback]);let i=this.cache.get(b)?.value;if(n){if(!j.path||!j.version)throw Error("无法读取插件已安装版本");let d=await (0,h.dz)(`npm:${k}@${l}`,{downloadSource:c,agentDir:this.agentDir,signal:this.signal,cache:!1}),e=d.source.slice(d.source.lastIndexOf("@")+1);i={...m,availableVersion:e},this.store(b,a,i)}i&&d.set(j.source,{...i,updateAvailable:!i.updateError&&j.version&&i.availableVersion?(0,f.zj)(i.availableVersion,j.version):null})}catch(e){let c={...m,updateError:this.message(j.source,e)};d.set(j.source,c),b&&this.store(b,a,c)}}else if(/^(?:git:|https?:|git@)/.test(j.source)){let b=JSON.stringify([a,"git"]),c=this.cache.get(b)?.value;if(c&&d.set(j.source,c),!n)continue;try{let c=e.SettingsManager.inMemory({packages:[j.source]}),f=new e.DefaultPackageManager({agentDir:this.agentDir,cwd:this.cwd,settingsManager:c}),g=await (0,i.V)(()=>f.checkForAvailableUpdates()),h={...m,updateAvailable:g.some(a=>"user"===a.scope)};d.set(j.source,h),this.store(b,a,h)}catch(e){let c={...m,updateError:this.message(j.source,e)};d.set(j.source,c),this.store(b,a,c)}}}return d}store(a,b,c){for(this.cache.delete(a);this.cache.size>=128;){let a=this.cache.keys().next().value;if(void 0===a)break;this.cache.delete(a)}this.cache.set(a,{identity:b,expiresAt:Date.now()+3e5,value:c})}message(a,b){let c=(b instanceof Error?b.message:String(b)).slice(0,4e3);return console.warn("[Pi Desk][PluginManagement] 检查插件更新失败",{source:a,message:c}),this.clear(a),c}}d()}catch(a){d(a)}})},86148:(a,b,c)=>{function d(a){let b=a.replaceAll("\\","/");return"tsx"===b||/(?:^|\/)tsx(?:\/|$)/.test(b)}function e(a=process.execArgv){for(let b=0;b<a.length;b+=1){let c=a[b];if("--import"===c){let c=a[b+1];if(c&&d(c))return c;b+=1;continue}if(c.startsWith("--import=")){let a=c.slice(9);if(d(a))return a}}throw Error("Pi Desk 服务缺少 tsx loader,无法启动插件维护子进程")}c.d(b,{I:()=>e})},93951:(a,b,c)=>{c.d(b,{LC:()=>E,tA:()=>G,oP:()=>H});var d=c(36153),e=c(72497),f=c(76019),g=c(4287),h=c(69375);let i=g.SZ,j=g.w3;d.Ik({downloadSource:j,recommendedRegistry:i}).strict(),d.Ik({downloadSource:j}).strict(),d.Ik({query:d.Yj().trim().max(200).default(""),page:d.ai().int().min(1).max(100).default(1),kind:d.k5(["all","desk","pi"]).default("all"),registry:i.optional()}).strict(),d.Ik({name:d.Yj().trim().min(1).max(214).regex(/^(?:@[a-z0-9_.-]+\/)?[a-z0-9][a-z0-9_.-]*$/i),version:d.Yj().trim().min(1).max(128).optional(),registry:i.optional()}).strict();let k=d.Ik({name:d.Yj(),description:f.qf.nullable(),version:d.Yj(),publisher:d.Yj().nullable(),kind:d.k5(["desk","pi","unknown"]),official:d.zM(),registry:i}).strict();d.Ik({items:d.YO(k),hasMore:d.zM()}).strict(),k.extend({versions:d.YO(d.Yj()),readme:f.qf.nullable(),homepage:d.Yj().nullable(),repository:d.Yj().nullable(),compatible:d.zM().nullable(),compatibilityNote:d.Yj().nullable()}).strict();let l=d.Yj().trim().min(1).max(2048),m=g.mR,n=d.YO(l).min(1).max(32),o=d.Ik({phase:d.k5(["package","entry","setup","resources","resolve","native"]),message:f.qf.refine(a=>"string"==typeof a?a.length>0:a.default.length>0)}).strict(),p=d.Yj().trim().min(1).max(4096),q=d.Yj().trim().min(1).max(256),r=d.Yj().max(32768),s=d.Ik({name:q,label:r,state:d.k5(["active","inactive","shadowed"]),description:r,promptSnippet:r.nullable(),promptGuidelineCount:d.ai().int().nonnegative(),promptGuidelinePreview:r.nullable()}).strict(),t=d.Ik({name:q,label:r,state:d.k5(["active","inactive","shadowed"]),description:r,parameters:e.Dz,promptSnippet:r.nullable(),promptGuidelines:d.YO(r)}).strict(),u=d.Ik({path:p,events:d.YO(d.Ik({name:q,count:d.ai().int().positive()}).strict()),commands:d.YO(d.Ik({name:q,description:r.nullable()}).strict()),shortcuts:d.YO(d.Ik({shortcut:q,description:r.nullable()}).strict()),flags:d.YO(d.Ik({name:q,type:d.k5(["boolean","string"]),description:r.nullable(),default:d.KC([d.zM(),d.Yj(),d.ch()])}).strict()),messageRenderers:d.YO(q),entryRenderers:d.YO(q)}).strict(),v=d.Ik({name:q,description:r,path:p}).strict(),w=v.extend({modelVisible:d.zM()}).strict(),x=v.extend({content:d.Yj().max(65536),truncated:d.zM()}).strict(),y=x.extend({modelVisible:d.zM()}).strict(),z=d.Ik({name:q,path:p}).strict(),A=d.Ik({name:q,kind:d.k5(["config","native"])}).strict(),B=d.Ik({methods:d.YO(d.Ik({pluginName:q,method:q}).strict()),browserEntries:d.YO(d.Ik({pluginName:q}).strict()),messageDeclarations:d.YO(d.Ik({pluginName:q,declarationName:q,priority:d.ai().int().safe()}).strict())}).strict(),C=d.Ik({error:f.qf.refine(a=>"string"==typeof a?a.length<=32768:[a.default,...Object.values(a.translations)].every(a=>a.length<=32768)).nullable(),extensions:d.YO(u),tools:d.YO(s),skills:d.YO(w),prompts:d.YO(v),themes:d.YO(z),providers:d.YO(A),piDesk:B}).strict(),D=d.Ik({action:d.k5(["add","update","del","apply","enable","disable"]),phase:d.k5(["queued","checking","applying","waiting","failed"]),message:d.Yj().max(4e3).nullable()}).strict(),E=(0,h._G)({path:"plugins/management-update",bodySchema:d.Ik({}).strict()}),F=d.Ik({source:l,kind:d.k5(["package","extension"]).default("package"),operation:D.nullable().default(null),pluginName:d.Yj().trim().min(1).nullable(),description:f.qf.nullable().default(null),version:d.Yj().trim().min(1).nullable(),updateAvailable:d.zM().nullable(),updateTag:m.nullable().optional(),availableVersion:d.Yj().min(1).nullable().optional(),updateError:d.Yj().max(4e3).nullable().optional(),status:d.k5(["ready","available","disabled","failed"]),error:o.nullable(),capabilities:C}).strict(),G=d.Ik({source:l,readme:f.qf.nullable().default(null),tools:d.YO(t),skills:d.YO(y),prompts:d.YO(x)}).strict(),H=d.Ik({plugins:d.YO(F),restartRequired:d.zM(),loadError:f.qf.refine(a=>"string"==typeof a?a.length>0:a.default.length>0).nullable()}).strict();d.Ik({sources:d.YO(l).min(1).max(32).optional()}).strict(),d.Ik({}).strict().extend({mode:d.k5(["normal","basic"]).optional()}).strict(),d.Ik({checkUpdates:d.zM().optional(),sources:n.optional(),tag:m.optional()}).strict();let I=d.Ik({source:l}).strict(),J=I.extend({downloadSource:j.optional(),registry:i.optional(),tag:m.optional()}).strict();d.gM("action",[d.Ik({action:d.eu("add"),items:d.YO(J).min(1).max(32)}).strict(),d.Ik({action:d.eu("update"),sources:n}).strict(),d.Ik({action:d.eu("del"),sources:n}).strict(),d.Ik({action:d.eu("tag"),sources:n,tag:m}).strict()]),d.Ik({snapshot:H,results:d.YO(d.Ik({source:l,error:d.Yj().max(4e3).nullable()}).strict()).max(32)}).strict(),I.extend({enabled:d.zM()}).strict()},96783:(a,b,c)=>{c.d(b,{Y:()=>j});var d=c(76760),e=c(36153),f=c(86148),g=c(2472);let h="__PI_DESK_PLUGIN_PROBE__",i=e.Ik({packages:e.YO(e.Ik({source:e.Yj(),packageName:e.Yj().nullable(),version:e.Yj().nullable(),pluginName:e.Yj().nullable(),status:e.k5(["ready","failed"]),error:e.Ik({phase:e.k5(["package","entry","setup","resources","resolve"]),message:e.Yj()}).strict().nullable()}).strict()),loadError:e.Yj().nullable()}).strict();async function j(a,b,c=!1,e){let k=(0,f.I)(),l=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-plugin-probe-runner.mts"),{stdout:m,stderr:n,code:o}=await (0,g.i)({args:["--conditions=react-server","--import",k,l],agentDir:b,env:{PI_DESK_PLUGIN_PROBE_AGENT_DIR:b,PI_DESK_PLUGIN_PROBE_CWD:a,PI_DESK_PLUGIN_PROBE_NATIVE:c?"1":void 0},maxOutputBytes:1048576,timeoutMs:3e4,signal:e,timeoutError:()=>Error("插件预检超时")});if(0!==o)throw Error(n.trim()||`插件预检进程退出码 ${o??"null"}`);let p=m.lastIndexOf(h);if(p<0)throw Error("插件预检没有返回有效结果");let q=m.slice(p+h.length).split(/\r?\n/,1)[0];return i.parse(JSON.parse(q))}}};
|
|
5
|
+
… (truncated)`)}(a?.error??c),extensions:a?.extensions??[],tools:a?.tools.map(a=>({name:a.name,label:a.label,state:a.state,description:a.description,promptSnippet:a.promptSnippet,promptGuidelineCount:a.promptGuidelineCount,promptGuidelinePreview:a.promptGuidelinePreview}))??[],skills:a?.skills.map(a=>({name:a.name,description:a.description,path:a.path,modelVisible:a.modelVisible}))??[],prompts:a?.prompts.map(a=>({name:a.name,description:a.description,path:a.path}))??[],themes:a?.themes??[],providers:a?.providers??[],piDesk:{methods:b?[...b.methods]:[],browserEntries:b?[...b.browserEntries]:[],messageDeclarations:b?[...b.messageDeclarations]:[]}}}class O{get restartRequired(){return this.deferredMaintenance.size>0}constructor(a,b=process.cwd(),c=(0,k.getAgentDir)()){this.workSessions=a,this.cwd=b,this.agentDir=c,this.operationTail=Promise.resolve(),this.operations=new Map,this.listeners=new Set,this.lifetime=new AbortController,this.disposed=!1,this.activeSource=null,this.sourceCache=null,this.capabilityCache=null,this.deferredMaintenance=new Map;const d=(0,h.createHash)("sha256").update(this.agentDir).digest("hex").slice(0,16);this.stagingRoot=(0,j.join)(this.cwd,"temp","pi",`plugin-management-${d}`),this.packageManagerCwd=(0,j.join)((0,f.M)(),"plugin-package-manager"),this.updates=new y.E(this.agentDir,this.packageManagerCwd,this.lifetime.signal),this.maintenanceError=process.env.PI_DESK_PLUGIN_MAINTENANCE_ERROR?.trim()||null,this.unsubscribeRuntime=(0,p.getL4PiGlobalPluginRuntime)().subscribeChanges(()=>this.publish()),this.staleStagingCleanup=(0,i.rm)(this.stagingRoot,{recursive:!0,force:!0}).catch(a=>{console.warn("[Pi Desk][PluginManagement] 清理上次中断的候选目录失败",{path:this.stagingRoot,errorName:a instanceof Error?a.name:"UnknownError"})})}list(a=!1){return this.assertOpen(),this.readSnapshot(a)}async batch(a){this.assertOpen();let b=[],c=new Set,d="add"===a.action||"update"===a.action?await this.readSources():null,e=[];for(let f of"add"===a.action?a.items:a.sources.map(a=>({source:a})))try{let g="add"===a.action?this.normalizeAddedSource(f.source):f.source,h=(0,m.LD)(g);if(c.has(h))throw new K("批量请求中包含重复来源");if(c.add(h),"add"===a.action){let{source:a,...b}=f;e.push(this.acceptMutation("add",g,d,!0,void 0,b))}else"update"===a.action?e.push(this.acceptMutation("update",g,d)):"del"===a.action?await this.del(g):await this.setUpdateTag(g,a.tag);b.push({source:f.source,error:null})}catch(a){b.push({source:f.source,error:C(a).slice(0,4e3)})}return e.length>0&&this.enqueueMutations(e),{snapshot:await this.readSnapshot(!1),results:b}}subscribe(a){return this.assertOpen(),this.listeners.add(a),()=>this.listeners.delete(a)}get(a){return this.assertOpen(),this.readDetail(a)}add(a,b={}){return this.mutate("add",this.normalizeAddedSource(a),!1,void 0,b)}setEnabled(a,b){return this.mutate(b?"enable":"disable",a)}async update(a){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护");this.assertSourceIdle(a);let b=(await this.readSources()).sources.find(b=>(0,m.LD)(b.source)===(0,m.LD)(a));if(!b)throw new J(a);if((0,m.ug)(b.source)){let a=await this.readSnapshot({checkUpdates:!0,sources:[b.source]}),c=a.plugins.find(a=>a.source===b.source);if(c.updateError)throw new L(c.updateError);if(!0!==c.updateAvailable)return a}return this.mutate("update",b.source)}reinstall(a,b,c={}){return this.mutate("add",this.normalizeAddedSource(a),!0,b,c)}async setUpdateTag(a,b){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护");let c=(await this.readSources()).sources.find(b=>(0,m.LD)(b.source)===(0,m.LD)(a));if(!c)throw new J(a);if("package"!==c.kind||!(0,m.ug)(c.source))throw new L("只有 npm 插件包支持更新渠道");this.assertSourceIdle(c.source),(0,o.ks)(c.source,m.mR.parse(b),this.agentDir),this.updates.clear(c.source),this.publish()}assertSourceIdle(a){let b=(0,m.LD)(a);if(this.activeSource&&(0,m.LD)(this.activeSource)===b||[...this.operations].some(([a,c])=>(0,m.LD)(a)===b&&"failed"!==c.phase))throw new K("该来源已有未完成的维护操作")}waitForOperations(a,b){return b=AbortSignal.any([b,this.lifetime.signal]),new Promise((c,d)=>{let e=()=>void 0,f=a=>{e(),b.removeEventListener("abort",g),a?d(a):c()},g=()=>f(Error(this.disposed?"插件管理已关闭":"发起命令的会话已关闭")),h=()=>{if(this.disposed)return f(Error("插件管理已关闭"));for(let b of a){let a=this.operations.get(b);if(a?.phase==="failed")return f(Error(a.message??"插件操作失败"));if(a?.phase==="waiting"&&this.activeSource!==b&&this.restartRequired)return f(Error(`插件尚未生效,需要在设置的插件管理中重启 Pi Desk。${a.message??""}`))}a.some(a=>this.operations.has(a)||this.activeSource===a)||f()};if(b.aborted)return g();e=this.subscribe(h),b.addEventListener("abort",g,{once:!0}),h()})}del(a){return this.mutate("del",a)}async apply(a){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不加载外部插件");if(a?.some(a=>this.deferredMaintenance.has(a)))throw new M;let b=await (0,p.getL4PiGlobalPluginRuntime)().scanSourceChanges(a);this.assertOpen();let c=b.filter(b=>{if(this.deferredMaintenance.has(b.source))return!1;let c=this.operations.get(b.source);if(!c||"failed"===c.phase)return!0;if(a)throw new K("该来源已有未完成操作");return!1}),d=new Set([...this.operations].filter(([,a])=>"failed"!==a.phase).map(([a])=>a));for(let a of c)d.add(a.source);if(d.size>32)throw new K("加载变更超过队列上限,请选择部分来源");for(let a of c){if(!this.operations.has(a.source)&&this.operations.size>=64){let a=[...this.operations].find(([,a])=>"failed"===a.phase);a&&this.operations.delete(a[0])}this.operations.set(a.source,{action:"apply",phase:"queued",message:null}),this.enqueueApply(a)}return this.publish(),this.readSnapshot(!1)}enqueueApply(a){this.runExclusive(async()=>{this.activeSource=a.source;try{this.setOperation(a.source,"checking",null),await this.probeSourceChange(a),this.assertOpen(),this.setOperation(a.source,"applying",null),await (0,p.getL4PiGlobalPluginRuntime)().applySourceChange(a),a.current?.path&&(0,u.tt)(a.current.path),a.previous?.path&&(0,u.tt)(a.previous.path),this.capabilityCache=null,this.operations.delete(a.source)}catch(b){this.setOperation(a.source,"failed",C(b))}finally{this.activeSource=null,this.sourceCache=null,this.publish()}}).catch(b=>{this.disposed||this.setOperation(a.source,"failed",C(b))})}async probeSourceChange(a){let b=a.current;if(!b||!b.enabled)return;if(b.error)throw new L(b.error);if(!b.path)throw new L("插件来源目录不存在");let c=performance.now();console.info("[Pi Desk][PluginManagement] 源码候选预检开始",{source:a.source});let d=(0,j.join)(this.stagingRoot,(0,h.randomUUID)()),e=(0,j.join)(d,"agent"),f=(0,j.join)(d,"workspace");await (0,i.mkdir)(e,{recursive:!0}),await (0,i.mkdir)(f,{recursive:!0});try{if(await (0,i.writeFile)((0,j.join)(e,"settings.json"),JSON.stringify({extensions:[b.path]}),"utf8"),b.piDeskRoot||b.nativePaths.length>0){let c=await (0,w.Y)(f,e,b.nativePaths.length>0),d=c.loadError??c.packages.find(a=>"failed"===a.status)?.error?.message;if(d)throw new L(d);if(b.piDeskRoot&&!c.packages.some(a=>"ready"===a.status))throw new L("预检未加载到候选 Node Entry,放弃本次变更");for(let b of c.packages)if(b.pluginName&&(0,p.getL4PiGlobalPluginRuntime)().readDiagnostics().packages.some(c=>c.source!==a.source&&"ready"===c.status&&c.pluginName===b.pluginName))throw new L(`插件名冲突:${b.pluginName}`)}this.assertOpen()}finally{await (0,i.rm)(d,{recursive:!0,force:!0}),console.info("[Pi Desk][PluginManagement] 源码候选预检结束",{source:a.source,durationMs:Math.round(performance.now()-c)})}}reload(a){return this.activeSource||[...this.operations].some(([a,b])=>"failed"!==b.phase&&!this.deferredMaintenance.has(a))?Promise.reject(new K("维护仍在执行或等待,请先完成当前操作")):this.runExclusive(async()=>(this.assertRestartAvailable(),this.restartWhenQuiet(a)))}async mutate(a,b,c=!1,d,e={}){this.assertOpen();let f=await this.readSources(),g=this.acceptMutation(a,b,f,c,d,e);return this.enqueueMutations([g]),this.readSnapshot(!1)}acceptMutation(a,b,c,d=!1,f,g={}){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护,请通过基础聊天修复或正常启动后维护");let h=c.sources.find(a=>(0,m.LD)(a.source)===(0,m.LD)(b));if("add"!==a){if(!h)throw new J(b);if("package"!==h.kind&&"enable"!==a&&"disable"!==a)throw new L("裸扩展不是已安装包,请编辑源码后加载变更;此操作不会删除源码")}let i=(f??=h?.source)??b;if(g.tag&&!(0,m.ug)(b))throw new L("只有 npm 插件包支持更新渠道");for(let a of[b,i])this.assertSourceIdle(a);if([...this.operations.values()].filter(a=>"failed"!==a.phase).length>=32)throw new K("插件维护队列已满,请等待当前操作完成");if(this.operations.size>=64){let a=[...this.operations].find(([,a])=>"failed"===a.phase);a&&this.operations.delete(a[0])}return f&&f!==b&&this.operations.get(f)?.phase==="failed"&&this.operations.delete(f),this.operations.set(i,{action:a,phase:"queued",message:null}),this.updates.clear(i),this.updates.clear(b),{mutation:a,source:b,operationSource:i,reinstall:d,options:g}}enqueueMutations(a){this.runExclusive(async()=>{let b=performance.now(),c=await Promise.all(a.map(async a=>{try{let b=await this.prepareMutation(a);return this.assertOpen(),this.setOperation(a.operationSource,"queued","候选检查完成,等待应用"),{input:a,prepared:b}}catch(b){return this.setOperation(a.operationSource,"failed",C(b)),null}}));for(let d of(a.length>1&&console.info("[Pi Desk][PluginManagement] 批量并行准备收尾",{count:a.length,failedCount:c.filter(a=>null===a).length,durationMs:Math.round(performance.now()-b)}),c)){if(!d)continue;let{input:a,prepared:b}=d,{source:c,operationSource:e}=a;this.activeSource=e;try{this.assertOpen(),b&&await this.executeMutation(a,b),this.deferredMaintenance.has(e)||this.operations.delete(e)}catch(a){this.setOperation(e,"failed",C(a))}finally{this.updates.clear(e),this.updates.clear(c),this.sourceCache=null,this.activeSource=null,this.publish()}}}).catch(b=>{if(!this.disposed)for(let c of a)this.setOperation(c.operationSource,"failed",C(b))}),this.publish()}async prepareMutation(a){let{mutation:b,source:c,operationSource:d,reinstall:e,options:f}=a;this.assertOpen();let g=this.createPackageManager();this.throwSettingsErrors(g.settingsManager);let h=g.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope).find(a=>a.source===d),i=null,j=null,k=null;if("enable"!==b&&"disable"!==b){var l;if("add"!==b&&!h)throw new J(c);this.setOperation(d,"checking","正在确认插件版本和下载源");let a=this.candidateSource(c,h?.installedPath),g=(0,m.ug)(a),n="del"===b?{source:a,updateTag:null}:await this.updates.resolveInstall(a,d,f,"update"===b);if(j=n.updateTag,"update"===b&&g&&h?.installedPath){let a=await D(h.installedPath),b=n.source.slice(n.source.lastIndexOf("@")+1);if(!a.version)throw new L("无法读取插件已安装版本");if(!(0,m.zj)(b,a.version))return null}i={...g&&"del"!==b&&(e||h||"update"===b)?{action:"reinstall",source:n.source}:(l=n.source,{action:"add"===b?"install":"update"===b?"update":"remove",source:l}),..."registry"in n&&n.registry?{registry:n.registry}:{}},"del"!==b&&(k=await this.probeCandidate(n.source,i.registry))}return{request:i,updateTag:j,pluginName:k}}async executeMutation(a,b){let{mutation:c,source:d,operationSource:e}=a,{request:f,updateTag:g,pluginName:h}=b,i=(0,p.getL4PiGlobalPluginRuntime)(),j=a=>this.setOperation(e,"waiting",a);f&&(this.assertPluginNameAvailable(h,e),g&&((0,o.ks)(e,g,this.agentDir),this.updates.clear(e))),this.assertOpen(),await i.withSourceIdle(e,async()=>{if(this.assertOpen(),this.setOperation(e,"applying",f?.registry?`下载源:${f.registry}`:null),"enable"===c||"disable"===c){let a=(0,o.to)(this.agentDir).disabled.includes((0,m.LD)(d));(0,o.El)(d,"enable"===c,this.agentDir),this.sourceCache=null;try{if(await this.applyMutationSources([d],!0),"enable"===c&&!(await this.readSources()).sources.find(a=>a.source===d)?.enabled)throw new L("此插件仍被 Pi 配置排除,请先调整原有资源配置")}catch(b){throw(0,o.El)(d,!a,this.agentDir),this.sourceCache=null,b}}else if(f)try{await i.replaceSource(e,null),await (0,s.V)(async()=>{await (0,q.wC)({maintenance:f,agentDir:this.agentDir,cwd:this.packageManagerCwd,signal:this.lifetime.signal}),"del"!==c&&await this.verifyInstalledPackage(f.source)}),this.sourceCache=null,await this.applyMutationSources([e,f.source],!1)}catch(a){if(a instanceof q.rZ&&"locked"===a.kind&&(0,x.k)())this.deferredMaintenance.set(e,f),j("文件正在被使用,需要重启后完成操作");else throw a}this.updates.clear(e),this.updates.clear(d),this.capabilityCache=null},this.lifetime.signal,j)}async verifyInstalledPackage(a){let b=this.createPackageManager();this.throwSettingsErrors(b.settingsManager);let c=(0,m.LD)(a),d=b.packageManager.listConfiguredPackages().find(a=>"user"===a.scope&&(0,m.LD)(a.source)===c);if(!d?.installedPath)throw new L("插件安装后没有有效目录");await this.verifyPackageVersion(a,d.installedPath)}async verifyPackageVersion(a,b){let c=await D(b);if(c.error)throw new L("string"==typeof c.error.message?c.error.message:c.error.message.default);if((0,m.ug)(a)){let b=a.slice(a.lastIndexOf("@")+1);if(c.version!==b)throw new L(`插件实际安装版本与目标不一致:${c.version??"未知"},目标 ${b}`)}}async applyMutationSources(a,b){let c=new Set(a.map(m.LD)),d=(0,p.getL4PiGlobalPluginRuntime)(),e=await d.scanSourceChanges(),f=await this.readSources(),g=[...new Set([...e.filter(a=>c.has((0,m.LD)(a.source))).map(a=>a.source),...f.sources.filter(a=>c.has((0,m.LD)(a.source))).map(a=>a.source)])];for(let a of g.length?await d.scanSourceChanges(g):[])b&&await this.probeSourceChange(a),await d.applySourceChange(a),a.current?.path&&(0,u.tt)(a.current.path),a.previous?.path&&(0,u.tt)(a.previous.path)}dispose(){this.disposed||(this.disposed=!0,this.lifetime.abort(),this.unsubscribeRuntime(),this.listeners.clear())}assertOpen(){if(this.disposed)throw new K("插件管理已关闭")}setOperation(a,b,c){let d=this.operations.get(a);if(!d)return;let e=c?.slice(0,4e3)??null;(d.phase!==b||d.message!==e)&&(this.operations.set(a,{...d,phase:b,message:e}),"failed"===b&&console.warn("[Pi Desk][PluginManagement] 插件操作失败",{source:a,action:d.action,message:e}),this.publish())}publish(){if(!this.disposed)for(let a of this.listeners)try{a()}catch(a){console.warn("[Pi Desk][PluginManagement] 状态监听失败",{message:C(a)})}}async readSources(){let a=()=>null!==this.activeSource&&this.operations.get(this.activeSource)?.phase==="applying";if(a()&&this.sourceCache)return this.sourceCache;let b=await (0,t.o)(this.packageManagerCwd,this.agentDir,{DefaultPackageManager:k.DefaultPackageManager,SettingsManager:k.SettingsManager});return a()&&this.sourceCache||(this.sourceCache=b),a()&&this.sourceCache?this.sourceCache:b}async probeCandidate(a,b){let c=(0,j.join)(this.stagingRoot,(0,h.randomUUID)()),d=(0,j.join)(c,"agent"),e=(0,j.join)(c,"workspace");await (0,i.mkdir)(e,{recursive:!0}),console.info("[Pi Desk][PluginManagement] 开始在隔离 AgentDir 预检候选插件",{source:a});try{if(!b&&(0,m.ug)(a))for(let b of[".npmrc",(0,j.join)("etc","npmrc")]){let c=(0,j.join)(d,"npm",b);await (0,i.mkdir)((0,j.dirname)(c),{recursive:!0});try{await (0,i.copyFile)((0,j.join)(this.agentDir,"npm",b),c),console.info("[Pi Desk][PluginManagement] 已为隔离预检继承本机 npm 配置",{source:a,configPath:b})}catch(a){if("ENOENT"!==a.code)throw new L(`无法继承本机 npm 配置(${b}):${C(a)}`)}}await (0,q.wC)({maintenance:{action:"install",source:a,...b?{registry:b}:{}},agentDir:d,cwd:e,signal:this.lifetime.signal}),this.assertOpen();let c=this.createPackageManager(d,e);this.throwSettingsErrors(c.settingsManager);let f=c.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope)[0];if(!f?.installedPath)throw new L("候选插件安装后没有有效目录");await this.verifyPackageVersion(a,f.installedPath);let g=await (0,w.Y)(e,d,!0,this.lifetime.signal);if(g.loadError)throw new L(g.loadError);let h=g.packages.find(a=>"failed"===a.status);if(h?.error)throw new L(h.error.message);let k=g.packages[0]?.pluginName??null;return this.assertOpen(),console.info("[Pi Desk][PluginManagement] 候选插件隔离预检通过",{source:a}),k}catch(a){if(a instanceof L)throw a;throw new L(C(a))}finally{await (0,i.rm)(c,{recursive:!0,force:!0}).catch(a=>{console.warn("[Pi Desk][PluginManagement] 清理候选插件目录失败",{path:c,errorName:a instanceof Error?a.name:"UnknownError"})})}}assertPluginNameAvailable(a,b){if(a&&(0,p.getL4PiGlobalPluginRuntime)().readDiagnostics().packages.some(c=>c.source!==b&&c.pluginName===a))throw new L(`pluginName 已由其他 Package 注册:${a}`)}restartWhenQuiet(a){return this.workSessions.runPluginRestart(async()=>{let b=(0,p.getL4PiGlobalPluginRuntime)(),c=await this.readSnapshot(!1);return await b.prepareReload(),console.info("[Pi Desk][PluginManagement] 插件 Runtime 已通过静默检查,准备重启",{deferredCount:this.deferredMaintenance.size}),(0,x.Z)("basic"===a||0===this.deferredMaintenance.size?void 0:[...this.deferredMaintenance.values()],a),c})}async readDetail(a){if((0,e.P)())throw new K("基础模式不执行插件能力盘点");let b=(await this.readSources()).sources.find(b=>b.source===a),c=b?await (0,t.W)(b):null;if(!c)throw new J(a);let d=await this.readCapabilities(!1),f=d.packages.find(b=>b.source===a);if(!f)throw Error(d.loadError??`插件能力详情不可用:${a}`);let[g,h]=await Promise.all([Promise.all(f.skills.map(async a=>({name:a.name,description:a.description,path:a.path,modelVisible:a.modelVisible,...await E(c,a.filePath)}))),Promise.all(f.prompts.map(async a=>({name:a.name,description:a.description,path:a.path,...await E(c,a.filePath)})))]);return l.tA.parse({source:a,readme:await (0,n.w$)(c),tools:f.tools.map(a=>({name:a.name,label:a.label,state:a.state,description:a.description,parameters:a.parameters,promptSnippet:a.promptSnippetDetail,promptGuidelines:a.promptGuidelines})),skills:g,prompts:h})}async readSnapshot(a){if((0,e.P)())return{plugins:[],restartRequired:!1,loadError:this.maintenanceError};let b=this.createPackageManager(),c=b.settingsManager.drainErrors().map(a=>a.error.message),d=b.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope),f=await (0,r.c)({agentDir:this.agentDir,configured:d}),h=await this.readSources(),i=await this.updates.read(h.sources,"boolean"==typeof a?{checkUpdates:a}:a),j=(0,p.getL4PiGlobalPluginRuntime)(),k=j.readDiagnostics(),n=new Map(k.packages.map(a=>[a.source,a])),q=(0,u.u7)(),s=this.capabilityCache??{packages:[],loadError:null},t=new Map(s.packages.map(a=>[a.source,a])),v=new Map(j.readCapabilityRegistrations().map(a=>[a.source,a])),w=await Promise.all(h.sources.map(async a=>{let b=n.get(a.source),c=a.path?this.findNativeDiagnostic(a.path,q):null,d=(a.error?{phase:"package"===a.kind?"package":"entry",message:a.error}:null)??(b?.status==="failed"?b.error:null)??(c?{phase:"native",message:c}:null);return{source:a.source,kind:a.kind,operation:this.operationFor(a.source),pluginName:b?.pluginName??null,description:a.description,version:a.version??b?.version??null,updateAvailable:i.get(a.source)?.updateAvailable??null,updateTag:i.get(a.source)?.updateTag??null,availableVersion:i.get(a.source)?.availableVersion??null,updateError:i.get(a.source)?.updateError??null,status:a.enabled?d?"failed":b?.status==="ready"?"ready":"available":"disabled",error:d,capabilities:F(t.get(a.source),v.get(a.source),s.loadError)}}));for(let[a,b]of this.operations)w.some(b=>(0,m.LD)(b.source)===(0,m.LD)(a))||w.push({source:a,kind:"package",operation:b,pluginName:null,description:null,version:null,updateAvailable:null,updateTag:(0,m.ug)(a)?(0,o.ey)(a,this.agentDir):null,availableVersion:null,updateError:null,status:"failed"===b.phase?"failed":"available",error:null,capabilities:F(void 0,void 0,null)});return l.oP.parse({plugins:w.sort((a,b)=>a.source.localeCompare(b.source)),restartRequired:this.restartRequired,loadError:function(a){let b=[...new Map(a.flatMap(a=>{let b=("string"==typeof a?a:a.message).trim();return b?[[b,{defaultText:b,englishText:"string"==typeof a?b:a.englishMessage.trim()}]]:[]})).values()];if(0===b.length)return null;let c=b.map(a=>a.defaultText).join("; ");return b.every(a=>a.defaultText===a.englishText)?c:(0,g.J8)(c,b.map(a=>a.englishText).join("; "))}([...c,...h.errors,...k.loadError?[k.loadError]:[],...this.maintenanceError?[this.maintenanceError]:[],...f?[f]:[]])})}async readCapabilities(a){if(!a&&this.capabilityCache)return this.capabilityCache;try{return this.assertOpen(),this.capabilityCache=await (0,v.a)(this.cwd,this.agentDir),this.publish(),console.info("[Pi Desk][PluginManagement] 插件能力盘点完成",{packageCount:this.capabilityCache.packages.length,hasLoadError:null!==this.capabilityCache.loadError}),this.capabilityCache}catch(b){let a=C(b);return console.warn("[Pi Desk][PluginManagement] 插件能力盘点失败",{errorName:b instanceof Error?b.name:"UnknownError",message:a}),this.capabilityCache={packages:[],loadError:a},this.publish(),this.capabilityCache}}findNativeDiagnostic(a,b){let c,d=(c=(0,j.resolve)(a).replaceAll("\\","/"),"win32"===process.platform?c.toLowerCase():c),e=b.find(a=>("win32"===process.platform?a.message.replaceAll("\\","/").toLowerCase():a.message.replaceAll("\\","/")).includes(d));return e?.message??null}createPackageManager(a=this.agentDir,b=this.packageManagerCwd){let c=k.SettingsManager.create(b,a,{projectTrusted:!1});return{settingsManager:c,packageManager:new k.DefaultPackageManager({cwd:b,agentDir:a,settingsManager:c})}}candidateSource(a,b){return(0,j.isAbsolute)(a)||/^(?:[a-z][a-z0-9+.-]*:|git@)/i.test(a)?a:b?(0,j.resolve)(b):(0,j.resolve)(this.agentDir,a)}operationFor(a){let b=(0,m.LD)(a);return[...this.operations].find(([a])=>(0,m.LD)(a)===b)?.[1]??null}normalizeAddedSource(a){return/^(?:@[a-z0-9_.-]+\/)?[a-z0-9][a-z0-9_.-]*(?:@[^\s/]+)?$/i.test(a)?`npm:${a}`:(0,j.isAbsolute)(a)||/^(?:[a-z][a-z0-9+.-]*:|git@)/i.test(a)?a:(0,j.resolve)(this.cwd,a)}throwSettingsErrors(a){let b=a.drainErrors();if(0!==b.length)throw Error(b.map(a=>a.error.message).join("; "))}assertRestartAvailable(){if(!(0,x.k)())throw new N}runExclusive(a){let b=()=>this.staleStagingCleanup.then(()=>(this.assertOpen(),a())),c=this.operationTail.then(b,b);return this.operationTail=c.then(()=>void 0,()=>void 0),c}}function G(){globalThis.__piDeskPluginManagement?.dispose()}function H(a){globalThis.__piDeskPluginManagement||(globalThis.__piDeskPluginManagement=new O(a))}function I(){if(!globalThis.__piDeskPluginManagement)throw Error("插件管理尚未完成进程级装配");return globalThis.__piDeskPluginManagement}d()}catch(a){d(a)}})},53584:(a,b,c)=>{c.d(b,{a:()=>l});var d=c(76760),e=c(36153),f=c(86148),g=c(2472);let h="__PI_DESK_PLUGIN_CAPABILITIES__",i=e.Yj(),j=e.Ik({name:e.Yj(),description:e.Yj().nullable()}).strict(),k=e.Ik({packages:e.YO(e.Ik({source:e.Yj(),error:e.Yj().nullable(),extensions:e.YO(e.Ik({path:e.Yj(),events:e.YO(e.Ik({name:e.Yj(),count:e.ai().int().positive()}).strict()),commands:e.YO(j),shortcuts:e.YO(e.Ik({shortcut:e.Yj(),description:e.Yj().nullable()}).strict()),flags:e.YO(e.Ik({name:e.Yj(),type:e.k5(["boolean","string"]),description:e.Yj().nullable(),default:e.KC([e.zM(),e.Yj(),e.ch()])}).strict()),messageRenderers:e.YO(e.Yj()),entryRenderers:e.YO(e.Yj())}).strict()),tools:e.YO(e.Ik({name:e.Yj(),label:i,state:e.k5(["active","inactive","shadowed"]),description:i,parameters:e.g1(e.Yj(),e.Pq()),promptSnippet:i.nullable(),promptSnippetDetail:i.nullable(),promptGuidelines:e.YO(i),promptGuidelineCount:e.ai().int().nonnegative(),promptGuidelinePreview:i.nullable()}).strict()),skills:e.YO(e.Ik({name:e.Yj(),description:e.Yj(),path:e.Yj(),filePath:e.Yj(),modelVisible:e.zM()}).strict()),prompts:e.YO(e.Ik({name:e.Yj(),description:e.Yj(),path:e.Yj(),filePath:e.Yj()}).strict()),themes:e.YO(e.Ik({name:e.Yj(),path:e.Yj()}).strict()),providers:e.YO(e.Ik({name:e.Yj(),kind:e.k5(["config","native"])}).strict())}).strict()),loadError:e.Yj().nullable()}).strict();async function l(a,b){let c=(0,f.I)(),e=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-plugin-capability-probe-runner.mts"),{stdout:i,stderr:j,code:l}=await (0,g.i)({args:["--conditions=react-server","--import",c,e],agentDir:b,env:{PI_DESK_PLUGIN_CAPABILITY_AGENT_DIR:b,PI_DESK_PLUGIN_CAPABILITY_CWD:a},maxOutputBytes:4194304,timeoutMs:3e4,timeoutError:()=>Error("插件能力盘点超时")});if(0!==l)throw Error(j.trim()||`插件能力盘点进程退出码 ${l??"null"}`);let m=i.lastIndexOf(h);if(m<0)throw Error("插件能力盘点没有返回有效结果");let n=i.slice(m+h.length).split(/\r?\n/,1)[0];return k.parse(JSON.parse(n))}},64253:(a,b,c)=>{c.a(a,async(a,d)=>{try{let s;c.d(b,{B:()=>q,I:()=>r});var e=c(31421),f=c(73024),g=c(51455),h=c(76760),i=c(48161),j=c(57975),k=c(75430),l=a([k]);k=(l.then?(await l)():l)[0];let t=(0,j.promisify)(e.execFile);function m(a){return a.replace(/\$\{([^}]+)\}/g,(a,b)=>process.env[b]??a)}async function n(a,b){let c;try{let b=await (0,g.readFile)(a);if(b.length>262144)throw Error("npm 配置文件过大");c=b.toString("utf8")}catch(a){if("ENOENT"===a.code)return;throw a}for(let a of c.split(/\r?\n/)){let c=/^\s*([^;#][^=]*?)\s*=\s*(.*?)\s*$/.exec(a);if(!c)continue;let d=c[2].replace(/\s+[;#].*$/,"").replace(/^(['"])(.*)\1$/,"$2");b[c[1].trim()]=m(d)}}function o(a,b){return("win32"===process.platform?/^~[\\/]/:/^~\//).test(a)?(0,h.resolve)((0,i.homedir)(),a.slice(2)):(0,h.resolve)(b,a)}async function p(a,b){let c={};for(let[a,b]of Object.entries(process.env))if(void 0!==b&&""!==b&&/^npm_config_/i.test(a)){let d=a.slice(11);c[d.startsWith("//")?d:d.replace(/(?!^)_/g,"-").toLowerCase()]=m(b)}let d=function(){for(let a of[(0,h.dirname)(process.execPath),...(process.env.PATH??"").split("win32"===process.platform?";":":")])for(let b of[(0,h.join)(a,"node_modules/npm/bin/npm-cli.js"),(0,h.resolve)(a,"../lib/node_modules/npm/bin/npm-cli.js")])if((0,f.existsSync)(b))return b}(),e={};if(d)try{await (0,g.mkdir)(a,{recursive:!0});let c=await t(process.execPath,[d,"config","list","--json","--prefix",b],{cwd:a,timeout:4e3,maxBuffer:524288,windowsHide:!0});e=JSON.parse(c.stdout)}catch{console.warn("[Pi Desk][PluginRegistry] npm 有效配置读取失败,改用 npmrc 和环境配置")}let j={};d&&await n((0,h.resolve)((0,h.dirname)(d),"../npmrc"),j);let k="string"==typeof e.globalconfig?e.globalconfig:c.globalconfig??(0,h.join)(b,"etc/npmrc"),l="string"==typeof e.userconfig?e.userconfig:c.userconfig??(0,h.join)((0,i.homedir)(),".npmrc");for(let[d,f]of(await n(o(k,a),j),await n(o(l,a),j),!0!==e.global&&"true"!==c.global&&"global"!==e.location&&"global"!==c.location&&await n((0,h.join)(b,".npmrc"),j),Object.entries(e)))"string"!=typeof f||"(protected)"===f||/auth|password|username/i.test(d)||(j[d]=f);return{...j,...c}}function q(a=(0,k.getAgentDir)()){let b=process.env.PI_DESK_PACKAGE_MAINTENANCE_CWD??(0,h.join)(a,"pi-desk","plugin-package-manager"),c=(0,h.join)(a,"npm");if(!s||s.cwd!==b||s.prefix!==c||s.expires<=Date.now()){let a=p(b,c);s={cwd:b,prefix:c,expires:Date.now()+3e4,value:a},a.catch(()=>{s?.value===a&&(s=void 0)})}return s.value}function r(a,b){let c=`//${a.host}${a.pathname}`;for(let a of Object.keys(b).flatMap(a=>{let b=/^(\/\/.*\/):(?:_authToken|_auth|username|_password)$/i.exec(a);return b&&c.startsWith(b[1])?[b[1]]:[]}).sort((a,b)=>b.length-a.length)){let c=b[`${a}:_authToken`]??b[`${a}:_authtoken`];if(c&&!c.includes("${"))return`Bearer ${c}`;let d=b[`${a}:_auth`];if(d&&!d.includes("${"))return`Basic ${d}`;let e=b[`${a}:username`],f=b[`${a}:_password`];if(e&&f&&!f.includes("${"))return`Basic ${Buffer.from(`${e}:${Buffer.from(f,"base64").toString("utf8")}`).toString("base64")}`}let d=b.registry;if(d){let c=new URL(d);if(a.origin===c.origin&&a.pathname.startsWith(`${c.pathname.replace(/\/+$/,"")}/`)){let a=b._authToken??b._authtoken;if(a&&!a.includes("${"))return`Bearer ${a}`;if(b._auth&&!b._auth.includes("${"))return`Basic ${b._auth}`}}}d()}catch(a){d(a)}})},69371:(a,b,c)=>{c.d(b,{rZ:()=>g,wC:()=>h});var d=c(76760),e=c(86148),f=c(2472);class g extends Error{constructor(a,b,c){super(b.slice(-4e3)||`Pi Package 命令退出码 ${c??"null"}`),this.kind=a,this.output=b,this.exitCode=c,this.name="L4PiPackageMaintenanceError"}}async function h(a){let b=(0,e.I)(),c=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-package-maintenance-runner.mts"),{stdout:h,stderr:i,code:j}=await (0,f.i)({args:["--import",b,c,a.maintenance.action,a.maintenance.source,...a.maintenance.registry?[a.maintenance.registry]:[]],agentDir:a.agentDir,env:{PI_DESK_PACKAGE_MAINTENANCE_CWD:a.cwd},maxOutputBytes:1048576,timeoutMs:12e4,signal:a.signal,timeoutError:()=>new g("failed","包维护超过120秒,已停止;结果未确认,请检查配置后手动处理",null)});if(0===j)return;let k=(i||h).trim();throw new g(function(a){let b=a.toLowerCase();if(b.includes("ebusy")||b.includes("etxtbsy")||b.includes("resource busy")||b.includes("being used by another process")||b.includes("used by another process")||b.includes("process cannot access the file because it is being used"))return"locked";let c=b.includes("eperm")||b.includes("eacces")||b.includes("operation not permitted"),d=/\b(unlink|rename|rmdir|rimraf|remove|cleanup)\b/.test(b);return c&&d?"locked":"failed"}(k),k,j)}},69375:(a,b,c)=>{c.d(b,{Od:()=>r,tU:()=>n,hE:()=>q,P9:()=>f,_G:()=>j,Vc:()=>i});var d=c(36153);d.Yj().uuid();let e=d.Ik({key:d.Yj().min(1).max(160),params:d.g1(d.Yj().min(1).max(80),d.KC([d.Yj().max(1e3),d.ai().finite()])).optional()}).strict(),f=4001,g=d.Yj().trim().min(1),h=d.Yj().uuid();function i(a){return Object.freeze({op:"req",path:g.parse(a.path),inputSchema:a.inputSchema,outputSchema:a.outputSchema,...void 0===a.timeoutMs?{}:{timeoutMs:d.ai().int().positive().parse(a.timeoutMs)}})}function j(a){return Object.freeze({op:"push",path:g.parse(a.path),bodySchema:a.bodySchema})}let k=d.Ik({op:d.eu("req"),path:g,requestId:h}).strict(),l=d.Ik({op:d.eu("resp"),path:g,requestId:h}).strict(),m=d.Ik({op:d.eu("push"),path:g}).strict(),n=d.Ik({head:k,body:d.Pq()}).strict(),o=d.Ik({head:l,body:d.Ik({code:d.eu(0),msg:d.eu(""),data:d.Pq()}).strict()}).strict(),p=d.Ik({head:l,body:d.Ik({code:d.ai().int().positive(),msg:d.Yj().min(1),data:d.ch(),i18n:e.optional()}).strict()}).strict(),q=d.KC([o,p]),r=d.Ik({head:m,body:d.Pq()}).strict()},72497:(a,b,c)=>{c.d(b,{Dz:()=>h,f7:()=>g,tv:()=>f});var d=c(36153);let e=d.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=e,g=e,h=d.g1(d.Yj(),d.Pq());d.Yj().trim().min(3).max(129).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*\/[a-z0-9]+(?:-[a-z0-9]+)*$/);let i=d.k5(["plugin","server","rocket","settings","panel","message","terminal","file","folder","bot","wrench","database","globe"]);d.gM("type",[d.Ik({type:d.eu("builtin"),name:i}).strict(),d.Ik({type:d.eu("svg"),content:d.Yj().trim().min(1).max(16384)}).strict()])},73159:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{NL:()=>h,XH:()=>j,Yq:()=>i});var e=c(77598),f=c(64253),g=a([f]);f=(g.then?(await g)():g)[0];class j extends Error{constructor(a,b=502,c="invalid"){super(a),this.status=b,this.reason=c,this.name="L4PluginRegistryError"}}let k=new Map,l=0;async function h(a,b){b.signal?.throwIfAborted();let c=!1===b.auth?{}:await (0,f.B)(b.agentDir),d=(0,f.I)(a,c),g=`${a.href}:${b.limit}:${(0,e.createHash)("sha256").update(d??"").digest("hex")}`,h=k.get(g);if(!1!==b.cache&&h&&h.expires>Date.now())return h.body;let i=AbortSignal.any([AbortSignal.timeout(b.timeout??1e4),...b.signal?[b.signal]:[]]),m=a;try{for(let a=0;a<=3;a++){let d=(0,f.I)(m,c),e=await fetch(m,{signal:i,redirect:"manual",headers:d?{Authorization:d}:{}});if([301,302,303,307,308].includes(e.status)){await e.body?.cancel();let b=e.headers.get("location");if(!b||3===a)throw new j("插件源重定向无效");let c=new URL(b,m);if(!["http:","https:"].includes(c.protocol)||c.username||c.password||"https:"===m.protocol&&"https:"!==c.protocol)throw new j("插件源重定向不安全");m=c;continue}if(!e.ok){await e.body?.cancel();let a=404===e.status?"missing":[401,403].includes(e.status)?"denied":e.status>=500?"network":"invalid";throw new j(`插件源请求失败(HTTP ${e.status})`,e.status,a)}if(Number(e.headers.get("content-length")??0)>b.limit)throw await e.body?.cancel(),new j("插件源响应超过大小限制");let h=e.body?.getReader(),n=[],o=0;if(h)try{for(;;){let a=await h.read();if(a.done)break;if((o+=a.value.byteLength)>b.limit)throw new j("插件源响应超过大小限制");n.push(a.value)}}finally{await h.cancel().catch(()=>void 0),h.releaseLock()}let p=Buffer.concat(n);if(!1!==b.cache){for(let[a,b]of k)(b.expires<=Date.now()||a===g)&&(k.delete(a),l-=b.body.length);for(;k.size>=96||l+p.length>0x1800000;){let a=k.entries().next().value;if(!a)break;k.delete(a[0]),l-=a[1].body.length}p.length<=0x1800000&&(k.set(g,{body:p,expires:Date.now()+12e4}),l+=p.length)}return p}throw new j("插件源重定向过多")}catch(a){if(b.signal?.aborted)throw b.signal.reason;if(a instanceof j)throw a;throw new j("插件源网络连接失败或超时",502,"network")}}async function i(a,b,c){let d=await h(a,{limit:8388608,signal:b,agentDir:c});try{let a=JSON.parse(d.toString("utf8"));if(!a||"object"!=typeof a||Array.isArray(a))throw Error("invalid");return a}catch{throw new j("插件源返回的元数据格式无效")}}d()}catch(a){d(a)}})},75157:(a,b,c)=>{c.d(b,{c:()=>g});var d=c(51455),e=c(76760);async function f(a){try{return(await (0,d.stat)(a)).isDirectory()}catch{return!1}}async function g(a){let b=a.configured.flatMap(a=>{let b=function(a){if(!a.startsWith("npm:"))return null;let b=a.slice(4).trim(),c=b.match(/^(@?[^@]+(?:\/[^@]+)?)(?:@(.+))?$/);return c?.[1]??(b||null)}(a.source);return b?[{name:b,item:a}]:[]}),c=(0,e.join)(a.agentDir,"npm","package.json"),g={};try{let a=JSON.parse(await (0,d.readFile)(c,"utf8"));a.dependencies&&"object"==typeof a.dependencies&&(g=a.dependencies)}catch(c){if(0===b.length)return null;let a=c instanceof Error&&c.message?c.message:String(c);return{message:`Pi Package npm 根不可用:${a}`,englishMessage:`Pi Package npm root is unavailable: ${a}`,i18n:{key:"errors:pluginNpmRootUnavailable",params:{detail:a.slice(0,1e3)}}}}let h=new Set(b.map(a=>a.name)),i=new Set(Object.keys(g)),j=[...h].filter(a=>!i.has(a)),k=[];for(let{name:a,item:c}of b)c.installedPath&&await f(c.installedPath)||k.push(a);if(0===j.length&&0===k.length)return null;let l=[j.length>0?`缺少声明:${j.join("、")}`:null,k.length>0?`缺少目录:${k.join("、")}`:null].filter(a=>null!==a),m=[j.length>0?`missing declarations: ${j.join(", ")}`:null,k.length>0?`missing folders: ${k.join(", ")}`:null].filter(a=>null!==a),n=j.length>0?k.length>0?"errors:pluginNpmRootMissingBoth":"errors:pluginNpmRootMissingDeclarations":"errors:pluginNpmRootMissingFolders";return{message:`Pi Package 配置与 npm 根不一致(${l.join(";")})`,englishMessage:`Pi Package configuration does not match the npm root (${m.join("; ")})`,i18n:{key:n,params:{declarations:j.join(", ").slice(0,1e3),folders:k.join(", ").slice(0,1e3)}}}}},76019:(a,b,c)=>{c.d(b,{J8:()=>f,fD:()=>g,qf:()=>e});var d=c(36153);let e=d.KC([d.Yj(),d.Ik({default:d.Yj(),translations:d.g1(d.Yj().min(1).max(35),d.Yj()).refine(a=>Object.keys(a).length<=16,"too many translations")}).strict()]);function f(a,b){return{default:a,translations:{en:b}}}function g(a,b){return"string"==typeof a?a:a.translations[b]??a.translations[b.split("-")[0]]??a.default}},78597:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{E:()=>j});var e=c(75430),f=c(4287),g=c(5235),h=c(34458),i=a([e,g,h]);[e,g,h]=i.then?(await i)():i;class j{constructor(a,b,c){this.agentDir=a,this.cwd=b,this.signal=c,this.cache=new Map}async resolveInstall(a,b,c,d){let e=(0,f.ug)(a),i=e?/^npm:(?:@[^/]+\/)?[^@]+@([^@]+)$/.exec(a)?.[1]:void 0,j=i&&!/^v?\d+\./.test(i)&&f.mR.safeParse(i).success?i:null,k=e?d?(0,g.ey)(b,this.agentDir):c.tag??j??(0,g.ey)(b,this.agentDir):null,l=e&&k&&(d||!i)?`npm:${e}@${k}`:a;return{...await (0,h.dz)(l,{...c,agentDir:this.agentDir,signal:this.signal,cache:!d&&void 0}),updateTag:k}}clear(a){let b=(0,f.LD)(a);for(let[a,c]of this.cache)c.identity===b&&this.cache.delete(a)}async read(a,b){for(let[a,b]of this.cache)b.expiresAt<=Date.now()&&this.cache.delete(a);let c=b.sources?new Set(b.sources.map(f.LD)):null,d=new Map;for(let i of a){if("package"!==i.kind)continue;let a=(0,f.LD)(i.source),j=(0,f.ug)(i.source),k=j?(0,g.ey)(i.source,this.agentDir):null,l={updateTag:k,updateAvailable:null,availableVersion:null,updateError:null};d.set(i.source,l);let m=!0===b.checkUpdates&&(!c||c.has(a))&&(!b.tag||b.tag===k);if(j){if(!m&&![...this.cache.values()].some(b=>b.identity===a))continue;let b=null;try{let c=(0,g.to)(this.agentDir).downloadSource,e=await (0,h.qX)(j,{agentDir:this.agentDir,downloadSource:c});b=JSON.stringify([a,k,c.mode,e.registry,e.fallback]);let n=this.cache.get(b)?.value;if(m){if(!i.path||!i.version)throw Error("无法读取插件已安装版本");let d=await (0,h.dz)(`npm:${j}@${k}`,{downloadSource:c,agentDir:this.agentDir,signal:this.signal,cache:!1}),e=d.source.slice(d.source.lastIndexOf("@")+1);n={...l,availableVersion:e},this.store(b,a,n)}n&&d.set(i.source,{...n,updateAvailable:!n.updateError&&i.version&&n.availableVersion?(0,f.zj)(n.availableVersion,i.version):null})}catch(e){let c={...l,updateError:this.message(i.source,e)};d.set(i.source,c),b&&this.store(b,a,c)}}else if(/^(?:git:|https?:|git@)/.test(i.source)){let b=JSON.stringify([a,"git"]),c=this.cache.get(b)?.value;if(c&&d.set(i.source,c),!m)continue;try{let c=e.SettingsManager.inMemory({packages:[i.source]}),f=new e.DefaultPackageManager({agentDir:this.agentDir,cwd:this.cwd,settingsManager:c}),g=await f.checkForAvailableUpdates(),h={...l,updateAvailable:g.some(a=>"user"===a.scope)};d.set(i.source,h),this.store(b,a,h)}catch(e){let c={...l,updateError:this.message(i.source,e)};d.set(i.source,c),this.store(b,a,c)}}}return d}store(a,b,c){for(this.cache.delete(a);this.cache.size>=128;){let a=this.cache.keys().next().value;if(void 0===a)break;this.cache.delete(a)}this.cache.set(a,{identity:b,expiresAt:Date.now()+3e5,value:c})}message(a,b){let c=(b instanceof Error?b.message:String(b)).slice(0,4e3);return console.warn("[Pi Desk][PluginManagement] 检查插件更新失败",{source:a,message:c}),this.clear(a),c}}d()}catch(a){d(a)}})},86148:(a,b,c)=>{function d(a){let b=a.replaceAll("\\","/");return"tsx"===b||/(?:^|\/)tsx(?:\/|$)/.test(b)}function e(a=process.execArgv){for(let b=0;b<a.length;b+=1){let c=a[b];if("--import"===c){let c=a[b+1];if(c&&d(c))return c;b+=1;continue}if(c.startsWith("--import=")){let a=c.slice(9);if(d(a))return a}}throw Error("Pi Desk 服务缺少 tsx loader,无法启动插件维护子进程")}c.d(b,{I:()=>e})},93951:(a,b,c)=>{c.d(b,{LC:()=>E,tA:()=>G,oP:()=>H});var d=c(36153),e=c(72497),f=c(76019),g=c(4287),h=c(69375);let i=g.SZ,j=g.w3;d.Ik({downloadSource:j,recommendedRegistry:i}).strict(),d.Ik({downloadSource:j}).strict(),d.Ik({query:d.Yj().trim().max(200).default(""),page:d.ai().int().min(1).max(100).default(1),kind:d.k5(["all","desk","pi"]).default("all"),registry:i.optional()}).strict(),d.Ik({name:d.Yj().trim().min(1).max(214).regex(/^(?:@[a-z0-9_.-]+\/)?[a-z0-9][a-z0-9_.-]*$/i),version:d.Yj().trim().min(1).max(128).optional(),registry:i.optional()}).strict();let k=d.Ik({name:d.Yj(),description:f.qf.nullable(),version:d.Yj(),publisher:d.Yj().nullable(),kind:d.k5(["desk","pi","unknown"]),official:d.zM(),registry:i}).strict();d.Ik({items:d.YO(k),hasMore:d.zM()}).strict(),k.extend({versions:d.YO(d.Yj()),readme:f.qf.nullable(),homepage:d.Yj().nullable(),repository:d.Yj().nullable(),compatible:d.zM().nullable(),compatibilityNote:d.Yj().nullable()}).strict();let l=d.Yj().trim().min(1).max(2048),m=g.mR,n=d.YO(l).min(1).max(32),o=d.Ik({phase:d.k5(["package","entry","setup","resources","resolve","native"]),message:f.qf.refine(a=>"string"==typeof a?a.length>0:a.default.length>0)}).strict(),p=d.Yj().trim().min(1).max(4096),q=d.Yj().trim().min(1).max(256),r=d.Yj().max(32768),s=d.Ik({name:q,label:r,state:d.k5(["active","inactive","shadowed"]),description:r,promptSnippet:r.nullable(),promptGuidelineCount:d.ai().int().nonnegative(),promptGuidelinePreview:r.nullable()}).strict(),t=d.Ik({name:q,label:r,state:d.k5(["active","inactive","shadowed"]),description:r,parameters:e.Dz,promptSnippet:r.nullable(),promptGuidelines:d.YO(r)}).strict(),u=d.Ik({path:p,events:d.YO(d.Ik({name:q,count:d.ai().int().positive()}).strict()),commands:d.YO(d.Ik({name:q,description:r.nullable()}).strict()),shortcuts:d.YO(d.Ik({shortcut:q,description:r.nullable()}).strict()),flags:d.YO(d.Ik({name:q,type:d.k5(["boolean","string"]),description:r.nullable(),default:d.KC([d.zM(),d.Yj(),d.ch()])}).strict()),messageRenderers:d.YO(q),entryRenderers:d.YO(q)}).strict(),v=d.Ik({name:q,description:r,path:p}).strict(),w=v.extend({modelVisible:d.zM()}).strict(),x=v.extend({content:d.Yj().max(65536),truncated:d.zM()}).strict(),y=x.extend({modelVisible:d.zM()}).strict(),z=d.Ik({name:q,path:p}).strict(),A=d.Ik({name:q,kind:d.k5(["config","native"])}).strict(),B=d.Ik({methods:d.YO(d.Ik({pluginName:q,method:q}).strict()),browserEntries:d.YO(d.Ik({pluginName:q}).strict()),messageDeclarations:d.YO(d.Ik({pluginName:q,declarationName:q,priority:d.ai().int().safe()}).strict())}).strict(),C=d.Ik({error:f.qf.refine(a=>"string"==typeof a?a.length<=32768:[a.default,...Object.values(a.translations)].every(a=>a.length<=32768)).nullable(),extensions:d.YO(u),tools:d.YO(s),skills:d.YO(w),prompts:d.YO(v),themes:d.YO(z),providers:d.YO(A),piDesk:B}).strict(),D=d.Ik({action:d.k5(["add","update","del","apply","enable","disable"]),phase:d.k5(["queued","checking","applying","waiting","failed"]),message:d.Yj().max(4e3).nullable()}).strict(),E=(0,h._G)({path:"plugins/management-update",bodySchema:d.Ik({}).strict()}),F=d.Ik({source:l,kind:d.k5(["package","extension"]).default("package"),operation:D.nullable().default(null),pluginName:d.Yj().trim().min(1).nullable(),description:f.qf.nullable().default(null),version:d.Yj().trim().min(1).nullable(),updateAvailable:d.zM().nullable(),updateTag:m.nullable().optional(),availableVersion:d.Yj().min(1).nullable().optional(),updateError:d.Yj().max(4e3).nullable().optional(),status:d.k5(["ready","available","disabled","failed"]),error:o.nullable(),capabilities:C}).strict(),G=d.Ik({source:l,readme:f.qf.nullable().default(null),tools:d.YO(t),skills:d.YO(y),prompts:d.YO(x)}).strict(),H=d.Ik({plugins:d.YO(F),restartRequired:d.zM(),loadError:f.qf.refine(a=>"string"==typeof a?a.length>0:a.default.length>0).nullable()}).strict();d.Ik({sources:d.YO(l).min(1).max(32).optional()}).strict(),d.Ik({}).strict().extend({mode:d.k5(["normal","basic"]).optional()}).strict(),d.Ik({checkUpdates:d.zM().optional(),sources:n.optional(),tag:m.optional()}).strict();let I=d.Ik({source:l}).strict(),J=I.extend({downloadSource:j.optional(),registry:i.optional(),tag:m.optional()}).strict();d.gM("action",[d.Ik({action:d.eu("add"),items:d.YO(J).min(1).max(32)}).strict(),d.Ik({action:d.eu("update"),sources:n}).strict(),d.Ik({action:d.eu("del"),sources:n}).strict(),d.Ik({action:d.eu("tag"),sources:n,tag:m}).strict()]),d.Ik({snapshot:H,results:d.YO(d.Ik({source:l,error:d.Yj().max(4e3).nullable()}).strict()).max(32)}).strict(),I.extend({enabled:d.zM()}).strict()},96783:(a,b,c)=>{c.d(b,{Y:()=>j});var d=c(76760),e=c(36153),f=c(86148),g=c(2472);let h="__PI_DESK_PLUGIN_PROBE__",i=e.Ik({packages:e.YO(e.Ik({source:e.Yj(),packageName:e.Yj().nullable(),version:e.Yj().nullable(),pluginName:e.Yj().nullable(),status:e.k5(["ready","failed"]),error:e.Ik({phase:e.k5(["package","entry","setup","resources","resolve"]),message:e.Yj()}).strict().nullable()}).strict()),loadError:e.Yj().nullable()}).strict();async function j(a,b,c=!1,e){let k=(0,f.I)(),l=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-plugin-probe-runner.mts"),{stdout:m,stderr:n,code:o}=await (0,g.i)({args:["--conditions=react-server","--import",k,l],agentDir:b,env:{PI_DESK_PLUGIN_PROBE_AGENT_DIR:b,PI_DESK_PLUGIN_PROBE_CWD:a,PI_DESK_PLUGIN_PROBE_NATIVE:c?"1":void 0},maxOutputBytes:1048576,timeoutMs:3e4,signal:e,timeoutError:()=>Error("插件预检超时")});if(0!==o)throw Error(n.trim()||`插件预检进程退出码 ${o??"null"}`);let p=m.lastIndexOf(h);if(p<0)throw Error("插件预检没有返回有效结果");let q=m.slice(p+h.length).split(/\r?\n/,1)[0];return i.parse(JSON.parse(q))}}};
|