@jetcrab/pi-desk 1.1.22-dev → 1.1.24-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/docs/commands.md +4 -2
  2. package/docs/plugins.md +2 -0
  3. package/package.json +1 -1
  4. package/src/client/l2_biz/project-preview/l2-project-preview-dialog.tsx +1 -1
  5. package/src/client/l2_biz/project-preview/l2-project-preview-page.tsx +1 -1
  6. package/src/client/l2_biz/project-preview/l2-project-preview.tsx +28 -34
  7. package/src/client/l3_modules/project-files/l3-project-document-view.tsx +162 -151
  8. package/src/client/l3_modules/project-files/l3-project-file-browser.module.css +30 -0
  9. package/src/client/l3_modules/project-files/l3-project-file-browser.tsx +137 -111
  10. package/src/client/l3_modules/project-files/l3-project-file-tabs.tsx +26 -6
  11. package/src/client/l3_modules/project-files/views/l3-project-search-controls.tsx +118 -123
  12. package/src/client/l3_modules/project-files/views/l3-project-search-results.tsx +29 -25
  13. package/src/server/l1_entry/api/l1-plugin-management-route.ts +0 -4
  14. package/src/server/l2_biz/plugin-management/l2-plugin-management.ts +4 -37
  15. package/src/server/l2_biz/plugin-management/l2-plugin-updates.ts +1 -4
  16. package/src/server/l2_biz/work-session/l2-work-session-chat-runtime.ts +4 -2
  17. package/src/server/l4_foundation/pi/l4-pi-chat-worker.ts +16 -1
  18. package/src/server/l4_foundation/pi/l4-pi-package-root-consistency.ts +3 -6
  19. package/src/server/l4_foundation/pi/l4-pi-package-root-gate.ts +1 -1
  20. package/src/server/l4_foundation/pi/l4-pi-plugin-owner-runtime.ts +4 -0
  21. package/src/server/l4_foundation/pi/l4-pi-plugin-sources.ts +5 -1
  22. package/src/server/l4_foundation/pi/l4-pi-session-initialization.ts +30 -34
  23. package/src/server/l4_foundation/pi/l4-pi-session-resources.ts +15 -14
  24. package/src/server/l4_foundation/pi/l4-pi-work-session-runtime.ts +1 -1
  25. package/src/server/l4_foundation/skills/runtime/l4-skill-catalog.ts +159 -166
  26. package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
  27. package/temp/build/pi-desk/release/.next/build-manifest.json +3 -3
  28. package/temp/build/pi-desk/release/.next/required-server-files.js +2 -2
  29. package/temp/build/pi-desk/release/.next/required-server-files.json +2 -2
  30. package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  31. package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
  32. package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +1 -1
  33. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  34. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  35. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  36. package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  37. package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
  38. package/temp/build/pi-desk/release/.next/server/app/api/plugins/add/route.js +1 -1
  39. package/temp/build/pi-desk/release/.next/server/app/api/plugins/apply/route.js +1 -1
  40. package/temp/build/pi-desk/release/.next/server/app/api/plugins/batch/route.js +1 -1
  41. package/temp/build/pi-desk/release/.next/server/app/api/plugins/del/route.js +1 -1
  42. package/temp/build/pi-desk/release/.next/server/app/api/plugins/enabled-set/route.js +1 -1
  43. package/temp/build/pi-desk/release/.next/server/app/api/plugins/get/route.js +1 -1
  44. package/temp/build/pi-desk/release/.next/server/app/api/plugins/list/route.js +1 -1
  45. package/temp/build/pi-desk/release/.next/server/app/api/plugins/reload/route.js +1 -1
  46. package/temp/build/pi-desk/release/.next/server/app/api/plugins/update/route.js +1 -1
  47. package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
  48. package/temp/build/pi-desk/release/.next/server/app/page.js +2 -2
  49. package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
  50. package/temp/build/pi-desk/release/.next/server/app/project-preview/page.js +1 -1
  51. package/temp/build/pi-desk/release/.next/server/app/project-preview/page_client-reference-manifest.js +1 -1
  52. package/temp/build/pi-desk/release/.next/server/chunks/16438.js +1 -1
  53. package/temp/build/pi-desk/release/.next/server/chunks/18748.js +1 -0
  54. package/temp/build/pi-desk/release/.next/server/chunks/20460.js +2 -2
  55. package/temp/build/pi-desk/release/.next/server/chunks/24557.js +1 -1
  56. package/temp/build/pi-desk/release/.next/server/chunks/25406.js +13 -14
  57. package/temp/build/pi-desk/release/.next/server/chunks/36361.js +2 -2
  58. package/temp/build/pi-desk/release/.next/server/chunks/50520.js +2 -2
  59. package/temp/build/pi-desk/release/.next/server/chunks/6917.js +1 -1
  60. package/temp/build/pi-desk/release/.next/server/chunks/80290.js +1 -1
  61. package/temp/build/pi-desk/release/.next/server/chunks/92386.js +15 -16
  62. package/temp/build/pi-desk/release/.next/server/instrumentation.js +1 -1
  63. package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
  64. package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
  65. package/temp/build/pi-desk/release/.next/static/chunks/9038-05fd2688407b39c1.js +15 -0
  66. package/temp/build/pi-desk/release/.next/static/chunks/app/{page-e8a5274c115f528d.js → page-ff44dcf27c2ba1c2.js} +2 -2
  67. package/temp/build/pi-desk/release/.next/static/chunks/app/project-preview/{page-d70ee4e9409b970a.js → page-bc18765121950e65.js} +1 -1
  68. package/temp/build/pi-desk/release/.next/static/chunks/{webpack-b60891a214e0925d.js → webpack-48eecbb66781c006.js} +1 -1
  69. package/temp/build/pi-desk/release/.next/static/css/10e063cfb3cda7bd.css +1 -0
  70. package/temp/build/pi-desk/release/.next/static/css/2c3b0c0ff1f49c68.css +1 -0
  71. package/temp/build/pi-desk/release/.next/trace-build +1 -1
  72. package/temp/build/pi-desk/release/.next/server/chunks/93049.js +0 -1
  73. package/temp/build/pi-desk/release/.next/static/chunks/9038-03144ed96d613f75.js +0 -15
  74. package/temp/build/pi-desk/release/.next/static/css/6dbae2922f88ca31.css +0 -1
  75. package/temp/build/pi-desk/release/.next/static/css/f646ca6c07245c4c.css +0 -1
  76. /package/temp/build/pi-desk/release/.next/static/{MV6_lBt7Mzmi1rBNI-3dx → w3CeIboVupqJdq890TlcG}/_buildManifest.js +0 -0
  77. /package/temp/build/pi-desk/release/.next/static/{MV6_lBt7Mzmi1rBNI-3dx → w3CeIboVupqJdq890TlcG}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- "use strict";exports.id=24557,exports.ids=[24557],exports.modules={489:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{A:()=>k});var e=c(75430),f=c(96459),g=c(72498),h=c(42222),i=a([e,f,g,h]);function j(a){return[...new Map(a.map(a=>[a.name,{value:a.name,description:a.description.replace(/\s+/g," ").trim().slice(0,1e3)}])).values()].sort((a,b)=>a.value.localeCompare(b.value))}async function k(){let[a,b,c]=await Promise.all([(0,g.Zd)(),(0,h.Jj)(null),(0,f.WE)().listCapabilityDeclarations()]),d=(0,e.getAgentDir)();return{tools:j([...(0,e.createCodingTools)(d),...(0,e.createReadOnlyTools)(d),...a]),skills:j(b.skills),plugins:c}}[e,f,g,h]=i.then?(await i)():i,d()}catch(a){d(a)}})},15760:(a,b,c)=>{c.d(b,{i:()=>k});var d=c(76760),e=c(51455),f=c(63719),g=c(42633),h=c(13982),i=c(20416);function j(a){return/^(npm:|git:|https?:\/\/|ssh:\/\/|git:\/\/)/i.test(a)}function k(a){return(0,h.V)(async()=>{let{CONFIG_DIR_NAME:b,DefaultPackageManager:h,getAgentDir:k,loadSkills:l,SettingsManager:m}=await Promise.resolve().then(c.bind(c,75430)),n=k(),o=a??process.cwd(),p=null===a?"user":"project",q=m.create(o,n,{projectTrusted:null!==a}),r=new h({cwd:o,agentDir:n,settingsManager:q}),s=q.drainErrors().map(({scope:a,error:c})=>({path:(0,i.p0)("global"===a?(0,d.join)(n,"settings.json"):(0,d.join)(o,b,"settings.json")),message:c.message})),t=r.listConfiguredPackages(),u=new Set(t.filter(a=>a.scope===p&&!a.installedPath).map(a=>a.source)),v=await r.resolve(async a=>(t.some(b=>b.source===a&&b.scope===p)&&u.add(a),"skip"));for(let a of u)s.push({path:a,message:(0,g.J8)("包未安装或版本不匹配,已跳过;查看 Skills 不会自动安装包。","Package not installed or version mismatch. Skills are not installed automatically.")});let w=[(0,d.join)(n,"npm"),(0,d.join)(n,"git"),...t.flatMap(a=>j(a.source)&&a.installedPath?[a.installedPath]:[]),...null===a?[]:[(0,d.join)(a,b,"npm"),(0,d.join)(a,b,"git")]],x=await Promise.all(w.map(async a=>{try{return await (0,e.realpath)(a)}catch{return(0,d.resolve)(a)}})),y=new Set(await Promise.all(t.filter(a=>"user"===a.scope&&a.installedPath).map(async a=>{try{return(0,i.wX)(await (0,e.realpath)(a.installedPath))}catch{return(0,i.wX)(a.installedPath)}}))),z=[],A=new Set;for(let a of v.skills){if(a.metadata.scope!==p)continue;if("project"===p&&"package"===a.metadata.origin&&a.metadata.baseDir){let b=a.metadata.baseDir;try{b=await (0,e.realpath)(b)}catch{}if(y.has((0,i.wX)(b)))continue}let b=(0,i.p0)(a.path),c=(0,i.wX)(b);if(A.has(c))continue;A.add(c);let h=("SKILL.md"===(0,d.basename)(b)?(0,d.basename)((0,d.dirname)(b)):(0,d.basename)(b,".md"))||"Skill",k="";try{let a=await (0,e.stat)(b);if(!a.isFile())continue;if(a.size>f.NL)s.push({path:b,message:(0,g.J8)("入口文件超过文本读取限制。","The entry file exceeds the text read limit.")});else{let a=l({cwd:o,agentDir:n,skillPaths:[b],includeDefaults:!1});h=a.skills[0]?.name||h,k=a.skills[0]?.description??"",s.push(...a.diagnostics.map(a=>({path:(0,i.p0)(a.path??b),message:a.message})))}}catch(a){s.push({path:b,message:a instanceof Error?a.message:(0,g.J8)("入口文件读取失败","Could not read the entry file")})}a.enabled||s.push({path:b,message:(0,g.J8)("此资源已被 Pi 配置排除;仍可查看文件。","This resource is excluded by Pi configuration; its files are still available to view.")}),z.push({skillPath:b,name:h,description:k,packageSource:"package"===a.metadata.origin?a.metadata.source:null,managed:"package"===a.metadata.origin&&j(a.metadata.source)})}let B=new Map;for(let a of z){let b=B.get(a.name);b?s.push({path:a.skillPath,message:(0,g.J8)(`同名 Skill:${b};这里保留各自来源,不代表会话加载结果。`,`Duplicate Skill name: ${b}. Each source is shown here; this does not indicate the session load result.`)}):B.set(a.name,a.skillPath)}return z.sort((a,b)=>a.name.localeCompare(b.name,"zh-CN",{numeric:!0})||a.skillPath.localeCompare(b.skillPath)),{skills:z,diagnostics:s,managedRoots:x}})}},20416:(a,b,c)=>{c.d(b,{_w:()=>f,ml:()=>i,mt:()=>j,p0:()=>h,wX:()=>g});var d=c(76760),e=c(51455);class f extends Error{constructor(a,b){super(b),this.status=a,this.name="L4SkillError"}}function g(a){let b=(0,d.resolve)(a);return"win32"===process.platform?b.toLowerCase():b}function h(a){return(0,d.resolve)(a).split(d.sep).join("/")}function i(a,b){let c=(0,d.relative)(a,b);return""===c||".."!==c&&!c.startsWith(`..${d.sep}`)&&!(0,d.isAbsolute)(c)}async function j(a){try{return await (0,e.realpath)(a)}catch(a){if(a&&"object"==typeof a&&"code"in a&&("EACCES"===a.code||"EPERM"===a.code))throw new f(403,"没有权限访问 Skill 文件");throw new f(404,"Skill 或文件不存在")}}},24557:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{R:()=>i,l:()=>j});var e=c(93865),f=c(70580),g=c(8602),h=a([f]);async function i(a){let b;try{b=await a.json()}catch{return(0,g.e)(400,"请求 JSON 格式无效",{key:"errors:invalidJson"})}if(!e.XD.safeParse(b).success)return(0,g.e)(400,"能力模式查询参数无效",{key:"errors:capabilityGetInvalid"});try{return(0,g.n)(await (0,f.F)())}catch(a){return console.error("[Pi Desk][Capabilities] 读取模式设置失败",a),(0,g.e)(500,a instanceof Error?a.message:"读取能力模式失败",a instanceof Error?void 0:{key:"errors:capabilityGetFailed"})}}async function j(a){let b;try{b=await a.json()}catch{return(0,g.e)(400,"请求 JSON 格式无效",{key:"errors:invalidJson"})}let c=e.xm.safeParse(b);if(!c.success)return(0,g.e)(400,c.error.issues[0]?.message??"能力模式格式无效",c.error.issues[0]?void 0:{key:"errors:capabilityReplaceInvalid"});try{return await (0,f.x)(c.data),(0,g.n)({})}catch(a){return console.error("[Pi Desk][Capabilities] 保存模式设置失败",a),(0,g.e)(500,a instanceof Error?a.message:"保存能力模式失败",a instanceof Error?void 0:{key:"errors:capabilityReplaceFailed"})}}f=(h.then?(await h)():h)[0],d()}catch(a){d(a)}})},35324:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Qg:()=>q,uf:()=>r,zD:()=>p});var e=c(77598),f=c(73024),g=c(51455),h=c(76760),i=c(42633),j=c(63719),k=c(60351),l=c(20416),m=a([k]);async function n(a,b,c){if(!(c?j.rh:j._g).safeParse(b).success)throw new l._w(400,"Skill 内路径必须是规范相对路径");if("SKILL.md"!==(0,h.basename)(a.skillPath)&&""!==b&&b!==(0,h.basename)(a.skillPath))throw new l._w(400,"独立 Markdown Skill 只允许访问入口文件自身");let d=await (0,l.mt)((0,h.dirname)(a.skillPath)),e=await (0,l.mt)((0,h.resolve)(d,b));if(!(0,l.ml)(d,e))throw new l._w(400,"目标文件不在此 Skill 的资源目录内");return{root:d,target:e}}async function o(a,b,c){if(b.managed||a.managedRoots.some(a=>(0,l.ml)(a,c)))return(0,i.J8)("此文件由 Pi 包管理器维护,请在包的源码目录修改;更新安装包会覆盖这里的内容。","This file is managed by the Pi package manager. Edit the package source; updates will overwrite this copy.");try{return await (0,g.access)(c,f.constants.W_OK),await (0,g.access)((0,h.dirname)(c),f.constants.W_OK),null}catch{return(0,i.J8)("当前服务没有修改此文件或其所在目录的权限。","The service does not have permission to edit this file or its directory.")}}async function p(a,b){let{root:c,target:d}=await n(a,b,!0);if(!(await (0,g.stat)(d)).isDirectory())throw new l._w(400,"目标不是目录");if("SKILL.md"!==(0,h.basename)(a.skillPath))return{entries:[{name:(0,h.basename)(a.skillPath),type:"file"}],truncated:!1};let e=[];for(let a of(await (0,g.readdir)(d,{withFileTypes:!0})))if(!(a.name.includes("\\")||a.name.includes("\0")||a.name.startsWith(".pi-desk-save-")))try{let b=a.isSymbolicLink()?await (0,l.mt)((0,h.join)(d,a.name)):(0,h.join)(d,a.name);if(!(0,l.ml)(c,b))continue;let f=a.isSymbolicLink()?await (0,g.stat)(b):a;f.isDirectory()?e.push({name:a.name,type:"directory"}):f.isFile()&&e.push({name:a.name,type:"file"})}catch{}return e.sort((a,b)=>"SKILL.md"===a.name?-1:"SKILL.md"===b.name?1:(a.type===b.type?0:"directory"===a.type?-1:1)||a.name.localeCompare(b.name,"zh-CN",{numeric:!0})),{entries:e.slice(0,j.xm),truncated:e.length>j.xm}}async function q(a,b,c){let{root:d,target:e}=await n(b,c,!1),f=await (0,g.stat)(e);if(!f.isFile())throw new l._w(400,"目标不是文件");try{let c=await (0,k.dy)(d,e,"original");return"text"===c.kind?{...c,readOnlyReason:await o(a,b,e)}:c}catch(a){if(a instanceof k.n){if("unsupported"===a.kind)return{kind:"unsupported",size:f.size,reason:"此文件不是支持的图片或 UTF-8 文本,不能在 Monaco 中编辑。"};if("text-too-large"===a.kind||"image-too-large"===a.kind)throw new l._w(413,"文件超过预览大小限制,不提供截断编辑");if("not-found"===a.kind)throw new l._w(404,"文件已不存在")}throw a}}async function r(a,b,d,f){if(f.includes("\0"))throw new l._w(400,"不能保存包含空字节的文本");if(Buffer.byteLength(f,"utf8")>j.NL)throw new l._w(413,"提交文本超过大小限制");let{target:i}=await n(b,d,!1),{withFileMutationQueue:k}=await Promise.resolve().then(c.bind(c,75430));await k(i,async()=>{let c,k,m,p=await n(b,d,!1);if((0,l.wX)(p.target)!==(0,l.wX)(i))throw new l._w(409,"文件位置已变化,请重新打开后保存");let q=await o(a,b,i);if(q)throw new l._w(403,"string"==typeof q?q:q.default);let r=await (0,g.open)(i,"r");try{let a=await r.stat();if(!a.isFile())throw new l._w(400,"只能替换已有文本文件");if(a.size>j.NL)throw new l._w(413,"原文件超过文本编辑限制");k=a.mode;let b=Buffer.alloc(j.NL+1),d=0;for(;d<b.length;){let a=await r.read(b,d,b.length-d,null);if(0===a.bytesRead)break;d+=a.bytesRead}if(d>j.NL)throw new l._w(413,"原文件超过文本编辑限制");c=b.subarray(0,d)}finally{await r.close()}try{if(c.includes(0))throw Error("binary");m=new TextDecoder("utf-8",{fatal:!0}).decode(c)}catch{throw new l._w(400,"只能保存完整的 UTF-8 文本文件")}let s=239===c[0]&&187===c[1]&&191===c[2],t=m.match(/\r\n|\n|\r/)?.[0]??"\n",u=f.replace(/^\uFEFF/,"").replace(/\r\n|\r/g,"\n").replace(/\n/g,t),v=Buffer.from(`${s?"\uFEFF":""}${u}`,"utf8");if(v.length>j.NL)throw new l._w(413,"保存后的文件超过文本大小限制");let w=(0,h.join)((0,h.dirname)(i),`.pi-desk-save-${(0,e.randomUUID)()}`);try{let a=await (0,g.open)(w,"wx",k);try{await a.writeFile(v),await a.chmod(511&k),await a.sync()}finally{await a.close()}await (0,g.stat)(i),await (0,g.rename)(w,i)}finally{await (0,g.rm)(w,{force:!0})}})}k=(m.then?(await m)():m)[0],d()}catch(a){d(a)}})},42222:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Jj:()=>j,Lx:()=>k,W3:()=>m,_w:()=>g._w,ed:()=>l});var e=c(15760),f=c(35324),g=c(20416),h=a([f]);function i(a,b){let c=a.skills.find(a=>(0,g.wX)(a.skillPath)===(0,g.wX)(b));if(!c)throw new g._w(404,"当前范围内未找到此 Skill,请刷新目录");return c}async function j(a){let b=await (0,e.i)(a);return{skills:b.skills.map(({skillPath:a,name:b,description:c,packageSource:d})=>({skillPath:a,name:b,description:c,packageSource:d})),diagnostics:b.diagnostics}}async function k(a,b,c){let d=await (0,e.i)(a);return(0,f.zD)(i(d,b),c)}async function l(a,b,c){let d=await (0,e.i)(a);return(0,f.Qg)(d,i(d,b),c)}async function m(a,b,c,d){let g=await (0,e.i)(a);await (0,f.uf)(g,i(g,b),c,d)}f=(h.then?(await h)():h)[0],d()}catch(a){d(a)}})},70580:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{F:()=>i,x:()=>j});var e=c(93865),f=c(489),g=c(61518),h=a([f,g]);async function i(){let a=(0,g.O)().read(),b=await (0,f.A)();return e.zh.parse({modes:a,catalog:b})}async function j(a){await (0,g.O)().replace(a.modes)}[f,g]=h.then?(await h)():h,d()}catch(a){d(a)}})},93865:(a,b,c)=>{c.d(b,{XD:()=>f,xm:()=>h,zh:()=>g});var d=c(59473),e=c(20369);let f=d.Ik({}).strict(),g=d.Ik({modes:e.f$,catalog:e.IS}).strict(),h=d.Ik({modes:e.f$}).strict();d.Ik({}).strict()}};
1
+ "use strict";exports.id=24557,exports.ids=[24557],exports.modules={489:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{A:()=>k});var e=c(75430),f=c(96459),g=c(72498),h=c(42222),i=a([e,f,g,h]);function j(a){return[...new Map(a.map(a=>[a.name,{value:a.name,description:a.description.replace(/\s+/g," ").trim().slice(0,1e3)}])).values()].sort((a,b)=>a.value.localeCompare(b.value))}async function k(){let[a,b,c]=await Promise.all([(0,g.Zd)(),(0,h.Jj)(null),(0,f.WE)().listCapabilityDeclarations()]),d=(0,e.getAgentDir)();return{tools:j([...(0,e.createCodingTools)(d),...(0,e.createReadOnlyTools)(d),...a]),skills:j(b.skills),plugins:c}}[e,f,g,h]=i.then?(await i)():i,d()}catch(a){d(a)}})},15760:(a,b,c)=>{c.d(b,{i:()=>j});var d=c(76760),e=c(51455),f=c(63719),g=c(42633),h=c(20416);function i(a){return/^(npm:|git:|https?:\/\/|ssh:\/\/|git:\/\/)/i.test(a)}async function j(a){let{CONFIG_DIR_NAME:b,DefaultPackageManager:j,getAgentDir:k,loadSkills:l,SettingsManager:m}=await Promise.resolve().then(c.bind(c,75430)),n=k(),o=a??process.cwd(),p=null===a?"user":"project",q=m.create(o,n,{projectTrusted:null!==a}),r=new j({cwd:o,agentDir:n,settingsManager:q}),s=q.drainErrors().map(({scope:a,error:c})=>({path:(0,h.p0)("global"===a?(0,d.join)(n,"settings.json"):(0,d.join)(o,b,"settings.json")),message:c.message})),t=r.listConfiguredPackages(),u=new Set(t.filter(a=>a.scope===p&&!a.installedPath).map(a=>a.source)),v=await r.resolve(async a=>(t.some(b=>b.source===a&&b.scope===p)&&u.add(a),"skip"));for(let a of u)s.push({path:a,message:(0,g.J8)("包未安装或版本不匹配,已跳过;查看 Skills 不会自动安装包。","Package not installed or version mismatch. Skills are not installed automatically.")});let w=[(0,d.join)(n,"npm"),(0,d.join)(n,"git"),...t.flatMap(a=>i(a.source)&&a.installedPath?[a.installedPath]:[]),...null===a?[]:[(0,d.join)(a,b,"npm"),(0,d.join)(a,b,"git")]],x=await Promise.all(w.map(async a=>{try{return await (0,e.realpath)(a)}catch{return(0,d.resolve)(a)}})),y=new Set(await Promise.all(t.filter(a=>"user"===a.scope&&a.installedPath).map(async a=>{try{return(0,h.wX)(await (0,e.realpath)(a.installedPath))}catch{return(0,h.wX)(a.installedPath)}}))),z=[],A=new Set;for(let a of v.skills){if(a.metadata.scope!==p)continue;if("project"===p&&"package"===a.metadata.origin&&a.metadata.baseDir){let b=a.metadata.baseDir;try{b=await (0,e.realpath)(b)}catch{}if(y.has((0,h.wX)(b)))continue}let b=(0,h.p0)(a.path),c=(0,h.wX)(b);if(A.has(c))continue;A.add(c);let j=("SKILL.md"===(0,d.basename)(b)?(0,d.basename)((0,d.dirname)(b)):(0,d.basename)(b,".md"))||"Skill",k="";try{let a=await (0,e.stat)(b);if(!a.isFile())continue;if(a.size>f.NL)s.push({path:b,message:(0,g.J8)("入口文件超过文本读取限制。","The entry file exceeds the text read limit.")});else{let a=l({cwd:o,agentDir:n,skillPaths:[b],includeDefaults:!1});j=a.skills[0]?.name||j,k=a.skills[0]?.description??"",s.push(...a.diagnostics.map(a=>({path:(0,h.p0)(a.path??b),message:a.message})))}}catch(a){s.push({path:b,message:a instanceof Error?a.message:(0,g.J8)("入口文件读取失败","Could not read the entry file")})}a.enabled||s.push({path:b,message:(0,g.J8)("此资源已被 Pi 配置排除;仍可查看文件。","This resource is excluded by Pi configuration; its files are still available to view.")}),z.push({skillPath:b,name:j,description:k,packageSource:"package"===a.metadata.origin?a.metadata.source:null,managed:"package"===a.metadata.origin&&i(a.metadata.source)})}let B=new Map;for(let a of z){let b=B.get(a.name);b?s.push({path:a.skillPath,message:(0,g.J8)(`同名 Skill:${b};这里保留各自来源,不代表会话加载结果。`,`Duplicate Skill name: ${b}. Each source is shown here; this does not indicate the session load result.`)}):B.set(a.name,a.skillPath)}return z.sort((a,b)=>a.name.localeCompare(b.name,"zh-CN",{numeric:!0})||a.skillPath.localeCompare(b.skillPath)),{skills:z,diagnostics:s,managedRoots:x}}},20416:(a,b,c)=>{c.d(b,{_w:()=>f,ml:()=>i,mt:()=>j,p0:()=>h,wX:()=>g});var d=c(76760),e=c(51455);class f extends Error{constructor(a,b){super(b),this.status=a,this.name="L4SkillError"}}function g(a){let b=(0,d.resolve)(a);return"win32"===process.platform?b.toLowerCase():b}function h(a){return(0,d.resolve)(a).split(d.sep).join("/")}function i(a,b){let c=(0,d.relative)(a,b);return""===c||".."!==c&&!c.startsWith(`..${d.sep}`)&&!(0,d.isAbsolute)(c)}async function j(a){try{return await (0,e.realpath)(a)}catch(a){if(a&&"object"==typeof a&&"code"in a&&("EACCES"===a.code||"EPERM"===a.code))throw new f(403,"没有权限访问 Skill 文件");throw new f(404,"Skill 或文件不存在")}}},24557:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{R:()=>i,l:()=>j});var e=c(93865),f=c(70580),g=c(8602),h=a([f]);async function i(a){let b;try{b=await a.json()}catch{return(0,g.e)(400,"请求 JSON 格式无效",{key:"errors:invalidJson"})}if(!e.XD.safeParse(b).success)return(0,g.e)(400,"能力模式查询参数无效",{key:"errors:capabilityGetInvalid"});try{return(0,g.n)(await (0,f.F)())}catch(a){return console.error("[Pi Desk][Capabilities] 读取模式设置失败",a),(0,g.e)(500,a instanceof Error?a.message:"读取能力模式失败",a instanceof Error?void 0:{key:"errors:capabilityGetFailed"})}}async function j(a){let b;try{b=await a.json()}catch{return(0,g.e)(400,"请求 JSON 格式无效",{key:"errors:invalidJson"})}let c=e.xm.safeParse(b);if(!c.success)return(0,g.e)(400,c.error.issues[0]?.message??"能力模式格式无效",c.error.issues[0]?void 0:{key:"errors:capabilityReplaceInvalid"});try{return await (0,f.x)(c.data),(0,g.n)({})}catch(a){return console.error("[Pi Desk][Capabilities] 保存模式设置失败",a),(0,g.e)(500,a instanceof Error?a.message:"保存能力模式失败",a instanceof Error?void 0:{key:"errors:capabilityReplaceFailed"})}}f=(h.then?(await h)():h)[0],d()}catch(a){d(a)}})},35324:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Qg:()=>q,uf:()=>r,zD:()=>p});var e=c(77598),f=c(73024),g=c(51455),h=c(76760),i=c(42633),j=c(63719),k=c(60351),l=c(20416),m=a([k]);async function n(a,b,c){if(!(c?j.rh:j._g).safeParse(b).success)throw new l._w(400,"Skill 内路径必须是规范相对路径");if("SKILL.md"!==(0,h.basename)(a.skillPath)&&""!==b&&b!==(0,h.basename)(a.skillPath))throw new l._w(400,"独立 Markdown Skill 只允许访问入口文件自身");let d=await (0,l.mt)((0,h.dirname)(a.skillPath)),e=await (0,l.mt)((0,h.resolve)(d,b));if(!(0,l.ml)(d,e))throw new l._w(400,"目标文件不在此 Skill 的资源目录内");return{root:d,target:e}}async function o(a,b,c){if(b.managed||a.managedRoots.some(a=>(0,l.ml)(a,c)))return(0,i.J8)("此文件由 Pi 包管理器维护,请在包的源码目录修改;更新安装包会覆盖这里的内容。","This file is managed by the Pi package manager. Edit the package source; updates will overwrite this copy.");try{return await (0,g.access)(c,f.constants.W_OK),await (0,g.access)((0,h.dirname)(c),f.constants.W_OK),null}catch{return(0,i.J8)("当前服务没有修改此文件或其所在目录的权限。","The service does not have permission to edit this file or its directory.")}}async function p(a,b){let{root:c,target:d}=await n(a,b,!0);if(!(await (0,g.stat)(d)).isDirectory())throw new l._w(400,"目标不是目录");if("SKILL.md"!==(0,h.basename)(a.skillPath))return{entries:[{name:(0,h.basename)(a.skillPath),type:"file"}],truncated:!1};let e=[];for(let a of(await (0,g.readdir)(d,{withFileTypes:!0})))if(!(a.name.includes("\\")||a.name.includes("\0")||a.name.startsWith(".pi-desk-save-")))try{let b=a.isSymbolicLink()?await (0,l.mt)((0,h.join)(d,a.name)):(0,h.join)(d,a.name);if(!(0,l.ml)(c,b))continue;let f=a.isSymbolicLink()?await (0,g.stat)(b):a;f.isDirectory()?e.push({name:a.name,type:"directory"}):f.isFile()&&e.push({name:a.name,type:"file"})}catch{}return e.sort((a,b)=>"SKILL.md"===a.name?-1:"SKILL.md"===b.name?1:(a.type===b.type?0:"directory"===a.type?-1:1)||a.name.localeCompare(b.name,"zh-CN",{numeric:!0})),{entries:e.slice(0,j.xm),truncated:e.length>j.xm}}async function q(a,b,c){let{root:d,target:e}=await n(b,c,!1),f=await (0,g.stat)(e);if(!f.isFile())throw new l._w(400,"目标不是文件");try{let c=await (0,k.dy)(d,e,"original");return"text"===c.kind?{...c,readOnlyReason:await o(a,b,e)}:c}catch(a){if(a instanceof k.n){if("unsupported"===a.kind)return{kind:"unsupported",size:f.size,reason:"此文件不是支持的图片或 UTF-8 文本,不能在 Monaco 中编辑。"};if("text-too-large"===a.kind||"image-too-large"===a.kind)throw new l._w(413,"文件超过预览大小限制,不提供截断编辑");if("not-found"===a.kind)throw new l._w(404,"文件已不存在")}throw a}}async function r(a,b,d,f){if(f.includes("\0"))throw new l._w(400,"不能保存包含空字节的文本");if(Buffer.byteLength(f,"utf8")>j.NL)throw new l._w(413,"提交文本超过大小限制");let{target:i}=await n(b,d,!1),{withFileMutationQueue:k}=await Promise.resolve().then(c.bind(c,75430));await k(i,async()=>{let c,k,m,p=await n(b,d,!1);if((0,l.wX)(p.target)!==(0,l.wX)(i))throw new l._w(409,"文件位置已变化,请重新打开后保存");let q=await o(a,b,i);if(q)throw new l._w(403,"string"==typeof q?q:q.default);let r=await (0,g.open)(i,"r");try{let a=await r.stat();if(!a.isFile())throw new l._w(400,"只能替换已有文本文件");if(a.size>j.NL)throw new l._w(413,"原文件超过文本编辑限制");k=a.mode;let b=Buffer.alloc(j.NL+1),d=0;for(;d<b.length;){let a=await r.read(b,d,b.length-d,null);if(0===a.bytesRead)break;d+=a.bytesRead}if(d>j.NL)throw new l._w(413,"原文件超过文本编辑限制");c=b.subarray(0,d)}finally{await r.close()}try{if(c.includes(0))throw Error("binary");m=new TextDecoder("utf-8",{fatal:!0}).decode(c)}catch{throw new l._w(400,"只能保存完整的 UTF-8 文本文件")}let s=239===c[0]&&187===c[1]&&191===c[2],t=m.match(/\r\n|\n|\r/)?.[0]??"\n",u=f.replace(/^\uFEFF/,"").replace(/\r\n|\r/g,"\n").replace(/\n/g,t),v=Buffer.from(`${s?"\uFEFF":""}${u}`,"utf8");if(v.length>j.NL)throw new l._w(413,"保存后的文件超过文本大小限制");let w=(0,h.join)((0,h.dirname)(i),`.pi-desk-save-${(0,e.randomUUID)()}`);try{let a=await (0,g.open)(w,"wx",k);try{await a.writeFile(v),await a.chmod(511&k),await a.sync()}finally{await a.close()}await (0,g.stat)(i),await (0,g.rename)(w,i)}finally{await (0,g.rm)(w,{force:!0})}})}k=(m.then?(await m)():m)[0],d()}catch(a){d(a)}})},42222:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Jj:()=>j,Lx:()=>k,W3:()=>m,_w:()=>g._w,ed:()=>l});var e=c(15760),f=c(35324),g=c(20416),h=a([f]);function i(a,b){let c=a.skills.find(a=>(0,g.wX)(a.skillPath)===(0,g.wX)(b));if(!c)throw new g._w(404,"当前范围内未找到此 Skill,请刷新目录");return c}async function j(a){let b=await (0,e.i)(a);return{skills:b.skills.map(({skillPath:a,name:b,description:c,packageSource:d})=>({skillPath:a,name:b,description:c,packageSource:d})),diagnostics:b.diagnostics}}async function k(a,b,c){let d=await (0,e.i)(a);return(0,f.zD)(i(d,b),c)}async function l(a,b,c){let d=await (0,e.i)(a);return(0,f.Qg)(d,i(d,b),c)}async function m(a,b,c,d){let g=await (0,e.i)(a);await (0,f.uf)(g,i(g,b),c,d)}f=(h.then?(await h)():h)[0],d()}catch(a){d(a)}})},70580:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{F:()=>i,x:()=>j});var e=c(93865),f=c(489),g=c(61518),h=a([f,g]);async function i(){let a=(0,g.O)().read(),b=await (0,f.A)();return e.zh.parse({modes:a,catalog:b})}async function j(a){await (0,g.O)().replace(a.modes)}[f,g]=h.then?(await h)():h,d()}catch(a){d(a)}})},93865:(a,b,c)=>{c.d(b,{XD:()=>f,xm:()=>h,zh:()=>g});var d=c(59473),e=c(20369);let f=d.Ik({}).strict(),g=d.Ik({modes:e.f$,catalog:e.IS}).strict(),h=d.Ik({modes:e.f$}).strict();d.Ik({}).strict()}};