blade-code 0.10.127 → 0.10.129

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 (147) hide show
  1. package/dist/blade.js +2 -2
  2. package/dist/chunk-0z9nqbd0.js +2 -0
  3. package/dist/chunk-1c11sbk3.js +2 -0
  4. package/dist/{chunk-g7f3nhg2.js → chunk-1q6sasj0.js} +2 -2
  5. package/dist/chunk-1y8x5q68.js +1 -0
  6. package/dist/chunk-2bnpn8be.js +1 -0
  7. package/dist/{chunk-hbafhk9y.js → chunk-2y1qngw7.js} +1 -1
  8. package/dist/{chunk-s20hq62y.js → chunk-440v1nhy.js} +3 -3
  9. package/dist/{chunk-s6562rsq.js → chunk-44jtpg8y.js} +1 -1
  10. package/dist/{chunk-q265drks.js → chunk-53h87fmt.js} +1 -1
  11. package/dist/chunk-54yagjc7.js +2 -0
  12. package/dist/chunk-606343xt.js +1 -0
  13. package/dist/{chunk-a552m4hx.js → chunk-651cnx1s.js} +2 -2
  14. package/dist/{chunk-p0khbmbc.js → chunk-67qdrjyy.js} +1 -1
  15. package/dist/chunk-6czf04er.js +1 -0
  16. package/dist/{chunk-zm2bbagg.js → chunk-6p6ts4kv.js} +2 -2
  17. package/dist/{chunk-sca5q3tt.js → chunk-77efqpdc.js} +1 -1
  18. package/dist/{chunk-85bamng3.js → chunk-93x9xbew.js} +1 -1
  19. package/dist/chunk-9gs4eqt8.js +1 -0
  20. package/dist/{chunk-hhmhs2q1.js → chunk-9kt66etm.js} +1 -1
  21. package/dist/chunk-9pzfv6nb.js +1 -0
  22. package/dist/{chunk-eq1anf88.js → chunk-9rj01jd1.js} +2 -2
  23. package/dist/chunk-9s8saznq.js +1 -0
  24. package/dist/{chunk-gna6njws.js → chunk-9snmrjg8.js} +2 -2
  25. package/dist/{chunk-pezzyyyk.js → chunk-a60cmnmz.js} +2 -2
  26. package/dist/{chunk-adkpwx6c.js → chunk-aaxc81jc.js} +1 -1
  27. package/dist/{chunk-7n7swtwg.js → chunk-ajsw4te2.js} +2 -2
  28. package/dist/{chunk-rw2sq3mf.js → chunk-amc5d34g.js} +1 -1
  29. package/dist/{chunk-68sf54n4.js → chunk-ar5np5h5.js} +2 -2
  30. package/dist/{chunk-t727txa9.js → chunk-bamj4e6v.js} +2 -2
  31. package/dist/{chunk-sv833k2e.js → chunk-dfjmvj3d.js} +2 -2
  32. package/dist/{chunk-dknmpacf.js → chunk-dg54m1y3.js} +2 -2
  33. package/dist/{chunk-8qp8v96d.js → chunk-edtxcqxa.js} +1 -1
  34. package/dist/chunk-f8gb685p.js +2 -0
  35. package/dist/chunk-fhafrrvs.js +1 -0
  36. package/dist/{chunk-2t6b962t.js → chunk-g4xny949.js} +1 -1
  37. package/dist/chunk-gfbkrk60.js +338 -0
  38. package/dist/{chunk-1b2dkwpv.js → chunk-gmqpfm52.js} +2 -2
  39. package/dist/{chunk-2xezz3nt.js → chunk-grhsv55v.js} +2 -2
  40. package/dist/{chunk-y94239bb.js → chunk-jkfkyedn.js} +1 -1
  41. package/dist/chunk-jxh9wf3c.js +1708 -0
  42. package/dist/{chunk-a3ewfebr.js → chunk-kbxqsf93.js} +2 -2
  43. package/dist/chunk-kd3k1q9z.js +1 -0
  44. package/dist/{chunk-ve4kvj1n.js → chunk-m5vpmvrs.js} +20 -20
  45. package/dist/chunk-m9mw8ppy.js +1 -0
  46. package/dist/{chunk-r5nvt35e.js → chunk-mawx6fa5.js} +2 -2
  47. package/dist/{chunk-ye4wyq1k.js → chunk-mdew58v9.js} +1 -1
  48. package/dist/{chunk-mpwyf1fe.js → chunk-mkzze9aq.js} +2 -2
  49. package/dist/{chunk-dh03cybw.js → chunk-mvm1rzc4.js} +2 -2
  50. package/dist/chunk-nz8wbcf1.js +1 -0
  51. package/dist/{chunk-g2jx4y8f.js → chunk-p00f53yq.js} +1 -1
  52. package/dist/{chunk-wmds1jq3.js → chunk-pa636c8e.js} +1 -1
  53. package/dist/chunk-pd1b8jrv.js +1 -0
  54. package/dist/chunk-pj69j4zp.js +2 -0
  55. package/dist/{chunk-t23n4wn0.js → chunk-q6xsfm60.js} +2 -2
  56. package/dist/{chunk-1g0d9yw0.js → chunk-qcvxff27.js} +2 -2
  57. package/dist/chunk-r1b4pnce.js +94 -0
  58. package/dist/{chunk-gqv0vkg9.js → chunk-rnmt44jm.js} +2 -2
  59. package/dist/chunk-s51h6n70.js +23 -0
  60. package/dist/chunk-s6158tg7.js +170 -0
  61. package/dist/{chunk-xvn80fge.js → chunk-sfe4810k.js} +1 -1
  62. package/dist/{chunk-cw2b3383.js → chunk-sj1dzeta.js} +1 -1
  63. package/dist/{chunk-0zzh482s.js → chunk-sx77dpxw.js} +1 -1
  64. package/dist/chunk-t6bg5b37.js +1 -0
  65. package/dist/{chunk-w7n73ag8.js → chunk-tkydv9k8.js} +1 -1
  66. package/dist/{chunk-z1zr4wts.js → chunk-v52wc8yg.js} +2 -2
  67. package/dist/chunk-wzcwxhhz.js +1 -0
  68. package/dist/{chunk-shd1ec3n.js → chunk-xcmadwjv.js} +2 -2
  69. package/dist/chunk-xdphpfrg.js +14 -0
  70. package/dist/chunk-xsjtjrt9.js +10 -0
  71. package/dist/{chunk-m76jmvsf.js → chunk-y4f99y85.js} +2 -2
  72. package/dist/{chunk-xdvn6yrd.js → chunk-z03dtyh6.js} +1 -1
  73. package/dist/chunk-za8gyypy.js +171 -0
  74. package/dist/{chunk-hmwz31tc.js → chunk-zkzhm39s.js} +1 -1
  75. package/dist/{chunk-6kwg4hcv.js → chunk-zwjrensv.js} +1 -1
  76. package/dist/chunk-zzgxy86p.js +1 -0
  77. package/dist/web/assets/ChatView-Bg36FUaj.js +53 -0
  78. package/dist/web/assets/{CodeBlockHighlighter-0VOa5Mes.js → CodeBlockHighlighter-D5rB73Eo.js} +2 -2
  79. package/dist/web/assets/FilePreview-BxaBSmap.js +65 -0
  80. package/dist/web/assets/KanbanBoard-B4gx3JMo.js +16 -0
  81. package/dist/web/assets/{MarkdownRenderer-3g4TPTeI.js → MarkdownRenderer-BRH7LHhN.js} +3 -3
  82. package/dist/web/assets/ScrollArea-DikU3QeQ.js +1 -0
  83. package/dist/web/assets/SessionHistorySurface-DG80d6-F.js +6 -0
  84. package/dist/web/assets/{SettingsModal-3GMy6V-E.js → SettingsModal-Bxqkok81.js} +3 -3
  85. package/dist/web/assets/Sidebar-DGaHGcHx.js +31 -0
  86. package/dist/web/assets/TaskSwitcher-DOnLPurk.js +26 -0
  87. package/dist/web/assets/TerminalPanel-BzhCF9vw.js +6 -0
  88. package/dist/web/assets/archive-BiDGrqry.js +6 -0
  89. package/dist/web/assets/{arrow-left-03GxbYI7.js → arrow-left-BY-esOAP.js} +1 -1
  90. package/dist/web/assets/{calendar-clock-8W4ostX1.js → calendar-clock-BCyxvfVt.js} +1 -1
  91. package/dist/web/assets/chevron-right-Bg-10yuN.js +6 -0
  92. package/dist/web/assets/{chevrons-up-down-BboZzEAk.js → chevrons-up-down-M5SAJq7T.js} +1 -1
  93. package/dist/web/assets/{clock-3-aXgeptZP.js → clock-3-v-nHTA0A.js} +1 -1
  94. package/dist/web/assets/copy-p1zc_rjZ.js +6 -0
  95. package/dist/web/assets/download-D_-kbJXR.js +6 -0
  96. package/dist/web/assets/{external-link-UkIIC2ds.js → external-link-wSGTIqe3.js} +1 -1
  97. package/dist/web/assets/{folder-BOCc5dv2.js → folder-Ltm9jCS5.js} +1 -1
  98. package/dist/web/assets/index-B4186fIT.css +1 -0
  99. package/dist/web/assets/index-_xnlrekR.js +210 -0
  100. package/dist/web/assets/{pause-DVIT6IIr.js → pause-_LvCZkxM.js} +1 -1
  101. package/dist/web/assets/pencil-DB6ICr_h.js +6 -0
  102. package/dist/web/assets/{play-DsdF5dji.js → play-BRXP1rHJ.js} +1 -1
  103. package/dist/web/assets/plus-BqvjEpLw.js +6 -0
  104. package/dist/web/assets/session-events-AGMXvPey.js +22 -0
  105. package/dist/web/assets/settings-LfQbDvBA.js +6 -0
  106. package/dist/web/assets/teamService-B5FnUcet.js +1 -0
  107. package/dist/web/assets/terminal-By4sO9Gw.js +6 -0
  108. package/dist/web/assets/vendor-radix-D6QrtXqd.js +45 -0
  109. package/dist/web/index.html +3 -3
  110. package/package.json +1 -1
  111. package/dist/chunk-23wg4jvz.js +0 -8
  112. package/dist/chunk-2a0vs0a0.js +0 -1
  113. package/dist/chunk-2j2mnzdg.js +0 -2
  114. package/dist/chunk-462sbp8t.js +0 -171
  115. package/dist/chunk-54f7t2g3.js +0 -1
  116. package/dist/chunk-8k26rhcp.js +0 -1
  117. package/dist/chunk-8zftskf2.js +0 -2
  118. package/dist/chunk-9cvq8w6k.js +0 -10
  119. package/dist/chunk-9hm3hy8d.js +0 -1
  120. package/dist/chunk-9rj1may5.js +0 -1
  121. package/dist/chunk-9xzw649r.js +0 -2
  122. package/dist/chunk-a0t558d4.js +0 -169
  123. package/dist/chunk-az5eb47t.js +0 -1
  124. package/dist/chunk-d4z5cp40.js +0 -2
  125. package/dist/chunk-d71gxct6.js +0 -118
  126. package/dist/chunk-hxfqcy5r.js +0 -23
  127. package/dist/chunk-k0n2028d.js +0 -1
  128. package/dist/chunk-mg4jnq0p.js +0 -1
  129. package/dist/chunk-mxkezzj9.js +0 -1
  130. package/dist/chunk-mzxwhhnc.js +0 -1
  131. package/dist/chunk-tqjrt537.js +0 -1
  132. package/dist/chunk-xba79vkf.js +0 -1703
  133. package/dist/chunk-xgp318dt.js +0 -1
  134. package/dist/chunk-xnbzrh8b.js +0 -140
  135. package/dist/chunk-y3jbc2xx.js +0 -1
  136. package/dist/chunk-yc64nfym.js +0 -1
  137. package/dist/chunk-yqh061d8.js +0 -1
  138. package/dist/web/assets/ChatView-DCHnicTP.js +0 -58
  139. package/dist/web/assets/FilePreview-C_3KHzzj.js +0 -65
  140. package/dist/web/assets/KanbanBoard-D_NTkUnD.js +0 -16
  141. package/dist/web/assets/TaskSwitcher-eCdxu5Eo.js +0 -26
  142. package/dist/web/assets/TerminalPanel-9q9Trmv9.js +0 -6
  143. package/dist/web/assets/index-DGf6Z2kM.css +0 -1
  144. package/dist/web/assets/index-DaiT-mmo.js +0 -275
  145. package/dist/web/assets/session-events-CWzF04l4.js +0 -22
  146. package/dist/web/assets/teamService-BliaDj1Z.js +0 -1
  147. package/dist/web/assets/vendor-radix-Bc1_Q9tz.js +0 -45
@@ -1,8 +1,8 @@
1
- import{$f as b1,ag as L0,bg as z1,gg as N0}from"./chunk-0zzh482s.js";import{ng as jO,og as wO}from"./chunk-adkpwx6c.js";import{rg as A1}from"./chunk-85bamng3.js";import{sg as b0,ug as J0}from"./chunk-s20hq62y.js";import{Hh as S0,Ih as GO,Mh as I0}from"./chunk-m76jmvsf.js";import{Qh as u,Sh as L,Vh as c1}from"./chunk-cw2b3383.js";import{ci as M}from"./chunk-s6562rsq.js";import{Ei as k,Fi as S}from"./chunk-68sf54n4.js";import{Si as u0}from"./chunk-a3ewfebr.js";import{Zi as N}from"./chunk-1g0d9yw0.js";import H1 from"node:path";import LO from"node:path";import v0 from"node:fs";import W0 from"node:os";import E from"node:path";import dO from"yaml";var U1=2000,V1=50,j1=1000,Y4={type:"object",properties:{verdict:{type:"string",enum:["pass","fail","partial"]},summary:{type:"string",minLength:1,maxLength:U1},findings:{type:"array",maxItems:V1,items:{type:"string",minLength:1,maxLength:j1}}},required:["verdict","summary","findings"],additionalProperties:!1};function F1(O,$){let Q=O.trim().replaceAll(/\s+/g," ");if($)Q=Q.replaceAll($,".");return Q.replace(/\bBearer\s+[^\s"'`]+/gi,"Bearer [redacted]").replace(/\bsk-[A-Za-z0-9_-]{8,}\b/g,"[redacted-key]").replace(/\b(api(?:[_-]?|\s+)key|access(?:[_-]?|\s+)token|authorization|cookie|password|passwd|refresh(?:[_-]?|\s+)token|secret|session(?:[_-]?|\s+)token)\b(\s*[:=]\s*)([^\s,;]+)/gi,"$1$2[redacted]")}function hO(O){if(O.length<=N0)return O;let $=" [verification feedback truncated]",Q=O.slice(0,N0-$.length);if(/[\uD800-\uDBFF]$/.test(Q))Q=Q.slice(0,-1);return Q.trimEnd()+$}function B1(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let $=O;if($.verdict!=="pass"&&$.verdict!=="fail"&&$.verdict!=="partial"||typeof $.summary!=="string"||!$.summary.trim()||$.summary.length>U1||!Array.isArray($.findings)||$.findings.length>V1||!$.findings.every((Q)=>typeof Q==="string"&&Q.trim().length>0&&Q.length<=j1))return;return{verdict:$.verdict,summary:$.summary.trim(),findings:$.findings.map((Q)=>Q.trim())}}function X4(O,$){let Q=B1(O);if(!Q)return;let Z=F1(Q.summary,$),J=Q.findings.map((K)=>F1(K,$));return hO([Z,J.length>0?`Findings:
1
+ import{Lg as A1,Mg as L0,Ng as M1,Sg as v0}from"./chunk-sx77dpxw.js";import{Zg as SO,_g as F1}from"./chunk-aaxc81jc.js";import{bh as x1}from"./chunk-93x9xbew.js";import{ch as A0,eh as J0}from"./chunk-440v1nhy.js";import{ri as z0,si as WO,wi as b0}from"./chunk-y4f99y85.js";import{Ii as M}from"./chunk-44jtpg8y.js";import{Ji as u,Li as L,Oi as l1}from"./chunk-sj1dzeta.js";import{oj as P,pj as S}from"./chunk-ar5np5h5.js";import{Cj as c0}from"./chunk-kbxqsf93.js";import{Jj as N}from"./chunk-qcvxff27.js";import{ek as qO}from"./chunk-pj69j4zp.js";import N0 from"node:path";import YO from"node:path";import y0 from"node:fs";import W0 from"node:os";import E from"node:path";import pO from"yaml";var V1=2000,j1=50,B1=1000,X4={type:"object",properties:{verdict:{type:"string",enum:["pass","fail","partial"]},summary:{type:"string",minLength:1,maxLength:V1},findings:{type:"array",maxItems:j1,items:{type:"string",minLength:1,maxLength:B1}}},required:["verdict","summary","findings"],additionalProperties:!1};function U1(O,$){let Q=O.trim().replaceAll(/\s+/g," ");if($)Q=Q.replaceAll($,".");return Q.replace(/\bBearer\s+[^\s"'`]+/gi,"Bearer [redacted]").replace(/\bsk-[A-Za-z0-9_-]{8,}\b/g,"[redacted-key]").replace(/\b(api(?:[_-]?|\s+)key|access(?:[_-]?|\s+)token|authorization|cookie|password|passwd|refresh(?:[_-]?|\s+)token|secret|session(?:[_-]?|\s+)token)\b(\s*[:=]\s*)([^\s,;]+)/gi,"$1$2[redacted]")}function kO(O){if(O.length<=v0)return O;let $=" [verification feedback truncated]",Q=O.slice(0,v0-$.length);if(/[\uD800-\uDBFF]$/.test(Q))Q=Q.slice(0,-1);return Q.trimEnd()+$}function S1(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let $=O;if($.verdict!=="pass"&&$.verdict!=="fail"&&$.verdict!=="partial"||typeof $.summary!=="string"||!$.summary.trim()||$.summary.length>V1||!Array.isArray($.findings)||$.findings.length>j1||!$.findings.every((Q)=>typeof Q==="string"&&Q.trim().length>0&&Q.length<=B1))return;return{verdict:$.verdict,summary:$.summary.trim(),findings:$.findings.map((Q)=>Q.trim())}}function H4(O,$){let Q=S1(O);if(!Q)return;let Z=U1(Q.summary,$),J=Q.findings.map((K)=>U1(K,$));return kO([Z,J.length>0?`Findings:
2
2
  ${J.map((K)=>`- ${K}`).join(`
3
3
  `)}`:""].filter(Boolean).join(`
4
4
 
5
- `))}function H4(O){return B1(O)?.verdict}var kO=`# Goal Completion Verifier
5
+ `))}function F4(O){return S1(O)?.verdict}var PO=`# Goal Completion Verifier
6
6
 
7
7
  You are a fresh, independent, adversarial verifier. The parent Agent has claimed
8
8
  that a persisted goal is complete. Your job is to refute that claim unless the
@@ -46,7 +46,7 @@ Submit the host-requested structured final object with:
46
46
  - findings: concrete gaps with file or command locators
47
47
 
48
48
  PASS is allowed only when every requirement is directly proven and no relevant
49
- check fails.`,S1={name:L0,description:"Host-reserved adversarial verifier for persisted Goal completion claims. Read-only, objective-scoped, and evidence-driven.",tools:["Read","Glob","Grep","Bash"],disallowedTools:["Task"],systemPrompt:kO,permissionMode:"yolo",maxTurns:12,source:"builtin"};var PO=`# Code Review Agent
49
+ check fails.`,z1={name:L0,description:"Host-reserved adversarial verifier for persisted Goal completion claims. Read-only, objective-scoped, and evidence-driven.",tools:["Read","Glob","Grep","Bash"],disallowedTools:["Task"],systemPrompt:PO,permissionMode:"yolo",maxTurns:12,source:"builtin"};var mO=`# Code Review Agent
50
50
 
51
51
  You are an independent senior code reviewer. Find actionable defects introduced
52
52
  by the requested change. Do not implement fixes and do not praise the author.
@@ -101,7 +101,7 @@ Your final response must be exactly one JSON object and no Markdown fence:
101
101
 
102
102
  Use workspace-relative paths. Keep line ranges within 10 lines and overlapping
103
103
  the reviewed diff. Return an empty findings array when no qualifying defect is
104
- found.`,M1={name:z1,description:"Independent read-only code reviewer for uncommitted changes, base branches, and commits.",tools:["Read","Glob","Grep","Bash"],disallowedTools:["Task","WebFetch","WebSearch"],permissionMode:"default",maxTurns:24,systemPrompt:PO,source:"builtin"};var B4={type:"object",properties:{verdict:{type:"string",enum:["pass","fail","partial"]},summary:{type:"string",minLength:1,maxLength:2000},findings:{type:"array",maxItems:50,items:{type:"string",minLength:1,maxLength:1000}}},required:["verdict","summary","findings"],additionalProperties:!1};function S4(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let $=O.verdict;return $==="pass"||$==="fail"||$==="partial"?$:void 0}var mO=`# Verification Agent
104
+ found.`,I1={name:M1,description:"Independent read-only code reviewer for uncommitted changes, base branches, and commits.",tools:["Read","Glob","Grep","Bash"],disallowedTools:["Task","WebFetch","WebSearch"],permissionMode:"default",maxTurns:24,systemPrompt:mO,source:"builtin"};var S4={type:"object",properties:{verdict:{type:"string",enum:["pass","fail","partial"]},summary:{type:"string",minLength:1,maxLength:2000},findings:{type:"array",maxItems:50,items:{type:"string",minLength:1,maxLength:1000}}},required:["verdict","summary","findings"],additionalProperties:!1};function z4(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let $=O.verdict;return $==="pass"||$==="fail"||$==="partial"?$:void 0}var dO=`# Verification Agent
105
105
 
106
106
  You are an **independent verification engineer**. Your sole purpose is to find problems — not to praise or reassure. You are the last line of defense before code ships.
107
107
 
@@ -186,7 +186,7 @@ Submit exactly these fields:
186
186
  - **FAIL**: Any automated check fails OR any HIGH severity issue found.
187
187
  - **PARTIAL**: All automated checks pass BUT MEDIUM severity issues exist.
188
188
 
189
- Be thorough. Be skeptical. Find the bugs.`,I1={name:"verification",description:"Independent verification agent that validates implementation by running builds, tests, linters, and adversarial"+" probes. Strictly read-only — cannot modify code. Use"+" after completing implementation to get an independent quality assessment.",tools:["Read","Glob","Grep","Bash"],maxTurns:24,systemPrompt:mO,source:"builtin"};var E0=[{name:"general-purpose",description:"General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you.",tools:[]},{name:"Explore",description:'Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.',tools:["Glob","Grep","Read","WebFetch","WebSearch"],systemPrompt:`# Explore Subagent
189
+ Be thorough. Be skeptical. Find the bugs.`,b1={name:"verification",description:"Independent verification agent that validates implementation by running builds, tests, linters, and adversarial"+" probes. Strictly read-only — cannot modify code. Use"+" after completing implementation to get an independent quality assessment.",tools:["Read","Glob","Grep","Bash"],maxTurns:24,systemPrompt:dO,source:"builtin"};var R0=[{name:"general-purpose",description:"General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you.",tools:[]},{name:"Explore",description:'Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.',tools:["Glob","Grep","Read","WebFetch","WebSearch"],systemPrompt:`# Explore Subagent
190
190
 
191
191
  You are a specialized code exploration agent. Your job is to **directly execute searches** using the tools available to you.
192
192
 
@@ -253,9 +253,9 @@ You are a software architect specializing in implementation planning.
253
253
  **Risks**:
254
254
  - [Potential issue and mitigation]
255
255
 
256
- Be thorough but concise. Focus on actionable steps.`},{name:"statusline-setup",description:"Use this agent to configure the user's Claude Code status line setting.",tools:["Read","Edit"]},M1,I1,S1];var Y0=k("Agent"),R0=new Set([b1,L0]);class C{workspaceRoot;static instances=new Map;subagents=new Map;constructor(O=M()){this.workspaceRoot=O}static getInstance(O=M()){let $=E.resolve(O),Q=C.instances.get($);if(!Q)Q=new C($),C.instances.set($,Q);return Q}static resetInstances(){C.instances.clear()}static releaseInstance(O,$){let Q=E.resolve(O),Z=C.instances.get(Q);if(!Z||$&&Z!==$)return!1;return C.instances.delete(Q)}register(O){if(R0.has(O.name))throw Error(`Subagent '${O.name}' is reserved by Blade`);if(this.subagents.has(O.name))throw Error(`Subagent '${O.name}' already registered`);this.subagents.set(O.name,O)}applyOverrides(O){for(let $ of O){if(R0.has($.name))throw Error(`Subagent '${$.name}' is reserved by Blade`);this.subagents.set($.name,$)}}getSubagent(O){return this.subagents.get(O)}getAllNames(){return Array.from(this.subagents.keys())}getAllSubagents(){return Array.from(this.subagents.values())}getDescriptionsForPrompt(){let O=this.getAllSubagents();if(O.length===0)return"No subagents available.";return`Available agent types and the tools they have access to:
256
+ Be thorough but concise. Focus on actionable steps.`},{name:"statusline-setup",description:"Use this agent to configure the user's Claude Code status line setting.",tools:["Read","Edit"]},I1,b1,z1];var Y0=P("Agent"),f0=new Set([A1,L0]);class w{workspaceRoot;static instances=new Map;subagents=new Map;constructor(O=M()){this.workspaceRoot=O}static getInstance(O=M()){let $=E.resolve(O),Q=w.instances.get($);if(!Q)Q=new w($),w.instances.set($,Q);return Q}static resetInstances(){w.instances.clear()}static releaseInstance(O,$){let Q=E.resolve(O),Z=w.instances.get(Q);if(!Z||$&&Z!==$)return!1;return w.instances.delete(Q)}register(O){if(f0.has(O.name))throw Error(`Subagent '${O.name}' is reserved by Blade`);if(this.subagents.has(O.name))throw Error(`Subagent '${O.name}' already registered`);this.subagents.set(O.name,O)}applyOverrides(O){for(let $ of O){if(f0.has($.name))throw Error(`Subagent '${$.name}' is reserved by Blade`);this.subagents.set($.name,$)}}getSubagent(O){return this.subagents.get(O)}getAllNames(){return Array.from(this.subagents.keys())}getAllSubagents(){return Array.from(this.subagents.values())}getDescriptionsForPrompt(){let O=this.getAllSubagents();if(O.length===0)return"No subagents available.";return`Available agent types and the tools they have access to:
257
257
  ${O.map((Q)=>{let Z=!Q.tools||Q.tools.length===0?"All tools":Q.tools.join(", ");return`- ${Q.name}: ${Q.description} (Tools: ${Z})`}).join(`
258
- `)}`}loadFromDirectory(O,$){if(!v0.existsSync(O))return;let Q=v0.readdirSync(O);for(let Z of Q){if(!Z.endsWith(".md"))continue;let J=E.join(O,Z);try{let K=this.parseConfigFile(J,$);if(R0.has(K.name)){Y0.warn(`Skipping reserved subagent configuration: ${K.name}`);continue}this.subagents.set(K.name,K)}catch(K){Y0.warn(`Failed to load subagent config from ${J}:`,K)}}}parseConfigFile(O,$){let Z=v0.readFileSync(O,"utf-8").match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);if(!Z)throw Error(`No YAML frontmatter found in ${O}`);let[,J,K]=Z,q=dO.parse(J);if(!q.name||!q.description)throw Error(`Missing required fields (name, description) in ${O}`);if(q.isolation!==void 0&&q.isolation!=="none"&&q.isolation!=="worktree")throw Error(`Invalid isolation mode "${String(q.isolation)}" in ${O}`);let W=K.trim(),G=this.parseStringOrArray(q.tools),Y=this.parseStringOrArray(q.skills),X=A1(q.permissionMode);return{name:q.name,description:q.description,systemPrompt:W,tools:G,color:q.color,configPath:O,model:q.model||"inherit",permissionMode:X,skills:Y,isolation:q.isolation,source:$}}parseStringOrArray(O){if(!O)return;if(Array.isArray(O))return O.map(($)=>$.trim()).filter(Boolean);return O.split(",").map(($)=>$.trim()).filter(Boolean)}loadFromStandardLocations(O){let $=O??N.getInstance().isTrustedCached(this.workspaceRoot);this.loadBuiltinAgents();let Q=E.join(W0.homedir(),".claude","agents");if(this.loadFromDirectory(Q,"claude-code-user"),$){let K=E.join(this.workspaceRoot,".claude","agents");this.loadFromDirectory(K,"claude-code-project")}let Z=E.join(W0.homedir(),".blade","agents");if(this.loadFromDirectory(Z,"blade-user"),$){let K=E.join(this.workspaceRoot,".blade","agents");this.loadFromDirectory(K,"blade-project")}let J=this.getAllNames().length;return Y0.debug(`Loaded ${J} subagents from standard locations`),J}loadBuiltinAgents(){for(let O of E0)this.subagents.set(O.name,{...O,model:O.model||"inherit",source:"builtin"});Y0.debug(`Loaded ${E0.length} builtin subagents`)}clear(){this.subagents.clear()}snapshot(){let O=new C(this.workspaceRoot);for(let $ of this.subagents.values())O.subagents.set($.name,{...$,...$.tools?{tools:[...$.tools]}:{},...$.disallowedTools?{disallowedTools:[...$.disallowedTools]}:{},...$.skills?{skills:[...$.skills]}:{}});return O}getSubagentsBySource(){let O={builtin:[],"claude-code-user":[],"claude-code-project":[],"blade-user":[],"blade-project":[],flag:[],plugin:[]};for(let $ of this.subagents.values()){let Q=$.source||"builtin",Z=Q.startsWith("plugin:")?"plugin":Q;O[Z].push($)}return O}clearPluginAgents(){let O=[];for(let[$,Q]of this.subagents.entries())if(Q.source?.startsWith("plugin:"))O.push($);for(let $ of O)this.subagents.delete($)}static getClaudeCodeAgentsDir(O){if(O==="user")return E.join(W0.homedir(),".claude","agents");return E.join(M(),".claude","agents")}static getBladeAgentsDir(O){if(O==="user")return E.join(W0.homedir(),".blade","agents");return E.join(M(),".blade","agents")}}function o(O=M()){return C.getInstance(O)}var y4=new Proxy({},{get(O,$){let Q=o(),Z=Reflect.get(Q,$,Q);return typeof Z==="function"?Z.bind(Q):Z}});import*as j0 from"node:fs/promises";import{homedir as R1}from"node:os";import*as w from"node:path";var X0={name:"skill-creator",description:"Create new Skills interactively. Use when the user wants to create a new Skill, define a custom workflow, or add a specialized capability to Blade.",allowedTools:["Read","Write","Glob","Bash","AskUserQuestion"],version:"1.0.0",argumentHint:void 0,userInvocable:!0,disableModelInvocation:!1,model:void 0,whenToUse:"User wants to create a new skill, define a custom workflow, or add a specialized capability.",path:"builtin://skill-creator",basePath:"",source:"builtin"};function x1(){return{metadata:X0,instructions:`# Skill Creator
258
+ `)}`}loadFromDirectory(O,$){if(!y0.existsSync(O))return;let Q=y0.readdirSync(O);for(let Z of Q){if(!Z.endsWith(".md"))continue;let J=E.join(O,Z);try{let K=this.parseConfigFile(J,$);if(f0.has(K.name)){Y0.warn(`Skipping reserved subagent configuration: ${K.name}`);continue}this.subagents.set(K.name,K)}catch(K){Y0.warn(`Failed to load subagent config from ${J}:`,K)}}}parseConfigFile(O,$){let Z=y0.readFileSync(O,"utf-8").match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);if(!Z)throw Error(`No YAML frontmatter found in ${O}`);let[,J,K]=Z,q=pO.parse(J);if(!q.name||!q.description)throw Error(`Missing required fields (name, description) in ${O}`);if(q.isolation!==void 0&&q.isolation!=="none"&&q.isolation!=="worktree")throw Error(`Invalid isolation mode "${String(q.isolation)}" in ${O}`);let W=K.trim(),G=this.parseStringOrArray(q.tools),Y=this.parseStringOrArray(q.skills),X=x1(q.permissionMode);return{name:q.name,description:q.description,systemPrompt:W,tools:G,color:q.color,configPath:O,model:q.model||"inherit",permissionMode:X,skills:Y,isolation:q.isolation,source:$}}parseStringOrArray(O){if(!O)return;if(Array.isArray(O))return O.map(($)=>$.trim()).filter(Boolean);return O.split(",").map(($)=>$.trim()).filter(Boolean)}loadFromStandardLocations(O){let $=O??N.getInstance().isTrustedCached(this.workspaceRoot);this.loadBuiltinAgents();let Q=E.join(W0.homedir(),".claude","agents");if(this.loadFromDirectory(Q,"claude-code-user"),$){let K=E.join(this.workspaceRoot,".claude","agents");this.loadFromDirectory(K,"claude-code-project")}let Z=E.join(W0.homedir(),".blade","agents");if(this.loadFromDirectory(Z,"blade-user"),$){let K=E.join(this.workspaceRoot,".blade","agents");this.loadFromDirectory(K,"blade-project")}let J=this.getAllNames().length;return Y0.debug(`Loaded ${J} subagents from standard locations`),J}loadBuiltinAgents(){for(let O of R0)this.subagents.set(O.name,{...O,model:O.model||"inherit",source:"builtin"});Y0.debug(`Loaded ${R0.length} builtin subagents`)}clear(){this.subagents.clear()}snapshot(){let O=new w(this.workspaceRoot);for(let $ of this.subagents.values())O.subagents.set($.name,{...$,...$.tools?{tools:[...$.tools]}:{},...$.disallowedTools?{disallowedTools:[...$.disallowedTools]}:{},...$.skills?{skills:[...$.skills]}:{}});return O}getSubagentsBySource(){let O={builtin:[],"claude-code-user":[],"claude-code-project":[],"blade-user":[],"blade-project":[],flag:[],plugin:[]};for(let $ of this.subagents.values()){let Q=$.source||"builtin",Z=Q.startsWith("plugin:")?"plugin":Q;O[Z].push($)}return O}clearPluginAgents(){let O=[];for(let[$,Q]of this.subagents.entries())if(Q.source?.startsWith("plugin:"))O.push($);for(let $ of O)this.subagents.delete($)}static getClaudeCodeAgentsDir(O){if(O==="user")return E.join(W0.homedir(),".claude","agents");return E.join(M(),".claude","agents")}static getBladeAgentsDir(O){if(O==="user")return E.join(W0.homedir(),".blade","agents");return E.join(M(),".blade","agents")}}function o(O=M()){return w.getInstance(O)}var f4=new Proxy({},{get(O,$){let Q=o(),Z=Reflect.get(Q,$,Q);return typeof Z==="function"?Z.bind(Q):Z}});import*as j0 from"node:fs/promises";import{homedir as y1}from"node:os";import*as D from"node:path";var X0={name:"skill-creator",description:"Create new Skills interactively. Use when the user wants to create a new Skill, define a custom workflow, or add a specialized capability to Blade.",allowedTools:["Read","Write","Glob","Bash","AskUserQuestion"],version:"1.0.0",argumentHint:void 0,userInvocable:!0,disableModelInvocation:!1,model:void 0,whenToUse:"User wants to create a new skill, define a custom workflow, or add a specialized capability.",path:"builtin://skill-creator",basePath:"",source:"builtin"};function T1(){return{metadata:X0,instructions:`# Skill Creator
259
259
 
260
260
  帮助用户创建新的 Blade Skills。
261
261
 
@@ -438,7 +438,7 @@ user-invocable: true
438
438
  <footer>
439
439
  \`\`\`
440
440
  \`\`\`
441
- `}}var H0={name:"update-config",description:"配置 Blade harness(settings/hooks/permissions)。"+"用户请求自动化行为时使用此 Skill。",allowedTools:["ConfigTool","Read","Bash","AskUserQuestion"],version:"1.0.0",userInvocable:!0,disableModelInvocation:!1,whenToUse:'用户说"从现在起..."、"每次..."、"当...时..."、'+"需要改配置、安装 hooks、修改权限",path:"builtin://update-config",basePath:"",source:"builtin"};function T1(){return{metadata:H0,instructions:`# Update Config Skill
441
+ `}}var H0={name:"update-config",description:"配置 Blade harness(settings/hooks/permissions)。"+"用户请求自动化行为时使用此 Skill。",allowedTools:["ConfigTool","Read","Bash","AskUserQuestion"],version:"1.0.0",userInvocable:!0,disableModelInvocation:!1,whenToUse:'用户说"从现在起..."、"每次..."、"当...时..."、'+"需要改配置、安装 hooks、修改权限",path:"builtin://update-config",basePath:"",source:"builtin"};function _1(){return{metadata:H0,instructions:`# Update Config Skill
442
442
 
443
443
  配置 Blade 运行环境。管理 settings、hooks、permissions、环境变量等。
444
444
 
@@ -711,23 +711,23 @@ ConfigTool({
711
711
  2. **permissions 字段使用 replace 策略**:设置 permissions 会完全替换现有值。如果只想添加规则,先 GET 当前值,合并后再 SET
712
712
  3. **env 字段使用 deep-merge 策略**:可以逐个添加环境变量
713
713
  4. **scope 默认值**:不指定 scope 时,根据字段路由表决定(hooks/permissions/env 默认 local,temperature/codeTheme 等默认 global)
714
- `}}import{exec as pO}from"node:child_process";import*as V from"node:fs/promises";import{homedir as gO}from"node:os";import*as A from"node:path";import{promisify as uO}from"node:util";var F0=uO(pO),b=k("General"),f0={url:"https://github.com/anthropics/skills.git",branch:"main",defaultSkills:["skill-creator"]};class _1{skillsDir;constructor(O){this.skillsDir=O||A.join(gO(),".blade","skills")}async isInstalled(O){let $=A.join(this.skillsDir,O,"SKILL.md");try{return await V.access($),!0}catch{return!1}}async isGitAvailable(){try{return await F0("git --version"),!0}catch{return!1}}async installOfficialSkill(O){let{url:$,branch:Q}=f0,Z=A.join(this.skillsDir,O),J=A.join(this.skillsDir,`.tmp-${O}-${Date.now()}`);try{if(!await this.isGitAvailable())return b.warn("Git not available, skipping skill installation"),!1;b.info(`Installing official skill: ${O}...`),await V.mkdir(this.skillsDir,{recursive:!0,mode:493}),await F0(`git clone --depth 1 --branch ${Q} --single-branch ${$} "${J}"`,{timeout:30000});let K=A.join(J,"skills",O);try{await V.access(K)}catch{return b.warn(`Skill ${O} not found in official repository`),await V.rm(J,{recursive:!0,force:!0}),!1}try{await V.rm(Z,{recursive:!0,force:!0})}catch{}return await V.cp(K,Z,{recursive:!0}),await V.rm(J,{recursive:!0,force:!0}),b.info(`Successfully installed: ${O}`),!0}catch(K){try{await V.rm(J,{recursive:!0,force:!0})}catch{}return b.warn(`Failed to install ${O}: ${K instanceof Error?K.message:"Unknown error"}`),!1}}async ensureDefaultSkillsInstalled(){await V.mkdir(this.skillsDir,{recursive:!0,mode:493});for(let O of f0.defaultSkills)if(!await this.isInstalled(O))await this.installOfficialSkill(O)}async installFromRepo(O,$){let Q=$||this.extractRepoName(O),Z=A.join(this.skillsDir,Q),J=A.join(this.skillsDir,`.tmp-repo-${Q}-${Date.now()}`);try{if(!await this.isGitAvailable())return b.warn("Git not available, cannot install from repo"),!1;b.info(`Installing skill from repo: ${O}...`),await V.mkdir(this.skillsDir,{recursive:!0,mode:493}),await F0(`git clone --depth 1 "${O}" "${J}"`,{timeout:60000});let K=A.join(J,"SKILL.md");try{await V.access(K)}catch{return b.warn(`No SKILL.md found in repository ${O}`),await V.rm(J,{recursive:!0,force:!0}),!1}await V.rm(Z,{recursive:!0,force:!0}),await V.rename(J,Z);try{await V.rm(A.join(Z,".git"),{recursive:!0,force:!0})}catch{}return b.info(`Successfully installed skill from repo: ${Q}`),!0}catch(K){try{await V.rm(J,{recursive:!0,force:!0})}catch{}return b.warn(`Failed to install from repo ${O}: ${K instanceof Error?K.message:"Unknown error"}`),!1}}async installFromLocal(O,$,Q=!0){let Z=$||A.basename(O),J=A.join(this.skillsDir,Z);try{let K=A.resolve(O);try{await V.access(K)}catch{return b.warn(`Local path does not exist: ${K}`),!1}let q=A.join(K,"SKILL.md");try{await V.access(q)}catch{return b.warn(`No SKILL.md found in local path: ${K}`),!1}if(b.info(`Installing skill from local path: ${K}...`),await V.mkdir(this.skillsDir,{recursive:!0,mode:493}),await V.rm(J,{recursive:!0,force:!0}),Q)await V.symlink(K,J,"dir"),b.info(`Created symlink for skill: ${Z}`);else await V.cp(K,J,{recursive:!0}),b.info(`Copied skill to: ${Z}`);return!0}catch(K){return b.warn(`Failed to install from local path ${O}: ${K instanceof Error?K.message:"Unknown error"}`),!1}}extractRepoName(O){return O.match(/\/([^/]+?)(\.git)?$/)?.[1]||"unknown-skill"}async installAllOfficialSkills(){let{url:O,branch:$}=f0,Q=A.join(this.skillsDir,`.tmp-all-${Date.now()}`),Z=[],J=[];try{if(!await this.isGitAvailable())return b.warn("Git not available, skipping skill installation"),{installed:Z,failed:J};await V.mkdir(this.skillsDir,{recursive:!0,mode:493}),b.info("Cloning official skills repository..."),await F0(`git clone --depth 1 --branch ${$} --single-branch ${O} "${Q}"`,{timeout:60000});let K=A.join(Q,"skills"),q=await V.readdir(K,{withFileTypes:!0});for(let W of q){if(!W.isDirectory())continue;let G=W.name,Y=A.join(K,G),X=A.join(this.skillsDir,G);try{await V.access(A.join(Y,"SKILL.md")),await V.rm(X,{recursive:!0,force:!0}),await V.cp(Y,X,{recursive:!0}),b.info(`Installed: ${G}`),Z.push(G)}catch(U){b.warn(`Failed to install ${G}`),J.push(G)}}await V.rm(Q,{recursive:!0,force:!0})}catch(K){try{await V.rm(Q,{recursive:!0,force:!0})}catch{}b.warn(`Failed to install skills: ${K instanceof Error?K.message:"Unknown error"}`)}return{installed:Z,failed:J}}}var h0=null;function w1(O){if(!h0)h0=new _1(O);return h0}import*as a from"node:fs/promises";import*as U0 from"node:path";import{parse as cO}from"yaml";var lO=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/,sO=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/,D1=1024;function nO(O){if(!O)return;if(typeof O==="string")return O.split(",").map(($)=>$.trim()).filter(Boolean);if(Array.isArray(O))return O.map(($)=>String($).trim()).filter(Boolean);return}function C1(O){if(O===void 0)return;if(typeof O==="boolean")return O;if(typeof O==="string"){let $=O.toLowerCase().trim();if($==="true"||$==="yes"||$==="1")return!0;if($==="false"||$==="no"||$==="0")return!1}return}function iO(O,$){if(!O.name)return{valid:!1,error:"Missing required field: name"};if(!sO.test(O.name))return{valid:!1,error:`Invalid name "${O.name}": must be lowercase letters, numbers, and hyphens only, 1-64 characters`};if(!O.description)return{valid:!1,error:"Missing required field: description"};if(O.description.length>D1)return{valid:!1,error:`Description too long: ${O.description.length} characters (max ${D1})`};let Q;if(O.model)Q=O.model==="inherit"?"inherit":O.model;return{valid:!0,metadata:{name:O.name,description:O.description.trim(),allowedTools:nO(O["allowed-tools"]),version:O.version,argumentHint:O["argument-hint"]?.trim(),userInvocable:C1(O["user-invocable"]),disableModelInvocation:C1(O["disable-model-invocation"]),model:Q,whenToUse:O.when_to_use?.trim()}}}function N1(O,$,Q){let Z=O.match(lO);if(!Z)return{success:!1,error:"Invalid SKILL.md format: missing YAML frontmatter (must start with ---)"};let[,J,K]=Z,q;try{q=cO(J)}catch(Y){return{success:!1,error:`Failed to parse YAML frontmatter: ${Y instanceof Error?Y.message:String(Y)}`}}let W=iO(q,$);if(!W.valid)return{success:!1,error:W.error};let G=U0.dirname($);return{success:!0,content:{metadata:{...W.metadata,path:$,basePath:G,source:Q},instructions:K.trim()}}}async function V0(O,$){try{let Q=await a.readFile(O,"utf-8");return N1(Q,O,$)}catch(Q){if(Q.code==="ENOENT")return{success:!1,error:`File not found: ${O}`};return{success:!1,error:`Failed to read file: ${Q instanceof Error?Q.message:String(Q)}`}}}async function E1(O){try{let $=await a.readFile(O.path,"utf-8"),Q=N1($,O.path,O.source);return Q.success?Q.content:null}catch{return null}}async function v1(O){try{return await a.access(U0.join(O,"SKILL.md")),!0}catch{return!1}}var oO={userSkillsDir:w.join(R1(),".blade","skills"),projectSkillsDir:".blade/skills",claudeUserSkillsDir:w.join(R1(),".claude","skills"),claudeProjectSkillsDir:".claude/skills"},t=new Map;function y1(O){return w.resolve(O?.cwd??M())}class P{skills=new Map;pluginSkills=new Map;config;initialized=!1;constructor(O){this.config={...oO,cwd:M(),...O}}static getInstance(O){let $=y1(O),Q=t.get($);if(!Q)Q=new P({...O,cwd:w.resolve(O?.cwd??M())}),t.set($,Q);return Q}static resetInstance(){t.clear()}static releaseInstance(O,$){let Q=y1(O),Z=t.get(Q);if(!Z||$&&Z!==$)return!1;return t.delete(Q)}async initialize(){if(this.initialized)return{skills:Array.from(this.skills.values()),errors:[]};let O=[],$=[];try{await w1(this.config.userSkillsDir).ensureDefaultSkillsInstalled()}catch(K){O.push({path:"SkillInstaller",error:`Failed to install default skills: ${K instanceof Error?K.message:"Unknown error"}`})}this.loadBuiltinSkills();let Q=await this.scanDirectory(this.config.claudeUserSkillsDir,"user");$.push(...Q.skills),O.push(...Q.errors);let Z=await this.scanDirectory(this.config.userSkillsDir,"user");if($.push(...Z.skills),O.push(...Z.errors),(await N.getInstance().getStatus(this.config.cwd)).state==="trusted"){let K=w.isAbsolute(this.config.claudeProjectSkillsDir)?this.config.claudeProjectSkillsDir:w.join(this.config.cwd,this.config.claudeProjectSkillsDir),q=await this.scanDirectory(K,"project");$.push(...q.skills),O.push(...q.errors);let W=w.isAbsolute(this.config.projectSkillsDir)?this.config.projectSkillsDir:w.join(this.config.cwd,this.config.projectSkillsDir),G=await this.scanDirectory(W,"project");$.push(...G.skills),O.push(...G.errors)}for(let K of $)this.skills.set(K.name,K);return this.initialized=!0,{skills:Array.from(this.skills.values()),errors:O}}loadBuiltinSkills(){this.skills.set(X0.name,X0),this.skills.set(H0.name,H0)}async scanDirectory(O,$){let Q=[],Z=[];try{await j0.access(O)}catch{return{skills:Q,errors:Z}}try{let J=await j0.readdir(O,{withFileTypes:!0});for(let K of J){if(!K.isDirectory())continue;let q=w.join(O,K.name),W=w.join(q,"SKILL.md");if(!await v1(q))continue;let G=await V0(W,$);if(G.success&&G.content)Q.push(G.content.metadata);else Z.push({path:W,error:G.error||"Unknown error"})}}catch(J){Z.push({path:O,error:`Failed to scan directory: ${J instanceof Error?J.message:String(J)}`})}return{skills:Q,errors:Z}}getAll(){return Array.from(this.skills.values())}get(O){return this.skills.get(O)}has(O){return this.skills.has(O)}async loadContent(O){let $=this.skills.get(O);if(!$)return null;if($.source==="builtin")return this.loadBuiltinContent(O);return E1($)}loadBuiltinContent(O){switch(O){case"skill-creator":return x1();case"update-config":return T1();default:return null}}getModelInvocableSkills(){return Array.from(this.skills.values()).filter((O)=>!O.disableModelInvocation)}getUserInvocableSkills(){return Array.from(this.skills.values()).filter((O)=>O.userInvocable===!0)}generateAvailableSkillsList(){let O=this.getModelInvocableSkills().sort((Q,Z)=>Q.name<Z.name?-1:Q.name>Z.name?1:0);if(O.length===0)return"";let $=[];for(let Q of O){let Z=Q.description.length>100?`${Q.description.substring(0,97)}...`:Q.description,J=Q.argumentHint?`${Q.name} ${Q.argumentHint}`:Q.name;$.push(`- ${J}: ${Z}`)}return $.join(`
715
- `)}get size(){return this.skills.size}async refresh(){return this.skills.clear(),this.pluginSkills.clear(),this.initialized=!1,this.initialize()}snapshot(){let O=new P({...this.config});return O.skills=new Map(Array.from(this.skills,([$,Q])=>[$,{...Q,...Q.allowedTools?{allowedTools:[...Q.allowedTools]}:{}}])),O.pluginSkills=new Map(Array.from(this.pluginSkills,([$,Q])=>[$,{...Q,metadata:{...Q.metadata,...Q.metadata.allowedTools?{allowedTools:[...Q.metadata.allowedTools]}:{}}}])),O.initialized=this.initialized,O}registerPluginSkill(O){this.pluginSkills.set(O.namespacedName,O),this.skills.set(O.namespacedName,O.metadata)}findPluginSkill(O){let $=this.pluginSkills.get(O);if($)return $;let Q=[];for(let Z of this.pluginSkills.values())if(Z.originalName===O)Q.push(Z);if(Q.length===1)return Q[0];return}getAllPluginSkills(){return Array.from(this.pluginSkills.values())}clearPluginSkills(){for(let O of this.pluginSkills.values())this.skills.delete(O.namespacedName);this.pluginSkills.clear()}getPluginSkillCount(){return this.pluginSkills.size}}function g(O){return P.getInstance(O)}import p0 from"node:path";import{execSync as aO}from"node:child_process";import f1 from"node:fs";import h1 from"node:path";class k0{async execute(O,$){let Q=O.content;if($.signal?.aborted)throw Error("Command execution aborted");return Q=this.interpolateArgs(Q,$.args),Q=await this.executeBashEmbeds(Q,$),Q=await this.resolveFileReferences(Q,$.workspaceRoot),Q}interpolateArgs(O,$){O=O.replace(/\$ARGUMENTS/g,$.join(" "));for(let Q=9;Q>=1;Q--){let Z=`$${Q}`,J=$[Q-1]??"";O=O.split(Z).join(J)}return O}async executeBashEmbeds(O,$){let Q=/!`([^`]+)`/g,Z=[];for(let K of O.matchAll(Q))Z.push({match:K[0],command:K[1]});let J=O;for(let{match:K,command:q}of Z){if($.signal?.aborted){J=J.replace(K,"[Execution aborted]");continue}try{let W=aO(q,{cwd:$.workspaceRoot,encoding:"utf-8",timeout:30000,maxBuffer:1048576,stdio:["pipe","pipe","pipe"]}).trim();J=J.replace(K,W)}catch(W){let G=W instanceof Error?W.message:String(W);J=J.replace(K,`[Error executing '${q}': ${G}]`)}}return J}async resolveFileReferences(O,$){let Q=/@([\w./-]+(?:\/[\w./-]+|\.[\w]+))/g,Z=[];for(let K of O.matchAll(Q))Z.push({match:K[0],relativePath:K[1]});let J=O;for(let{match:K,relativePath:q}of Z){let W=h1.resolve($,q);try{if(f1.statSync(W).isFile()){let Y=f1.readFileSync(W,"utf-8"),U=`\`\`\`${h1.extname(q).slice(1)||"text"}
714
+ `}}import{exec as gO}from"node:child_process";import*as V from"node:fs/promises";import{homedir as uO}from"node:os";import*as A from"node:path";import{promisify as cO}from"node:util";var F0=cO(gO),b=P("General"),k0={url:"https://github.com/anthropics/skills.git",branch:"main",defaultSkills:["skill-creator"]};class w1{skillsDir;constructor(O){this.skillsDir=O||A.join(uO(),".blade","skills")}async isInstalled(O){let $=A.join(this.skillsDir,O,"SKILL.md");try{return await V.access($),!0}catch{return!1}}async isGitAvailable(){try{return await F0("git --version"),!0}catch{return!1}}async installOfficialSkill(O){let{url:$,branch:Q}=k0,Z=A.join(this.skillsDir,O),J=A.join(this.skillsDir,`.tmp-${O}-${Date.now()}`);try{if(!await this.isGitAvailable())return b.warn("Git not available, skipping skill installation"),!1;b.info(`Installing official skill: ${O}...`),await V.mkdir(this.skillsDir,{recursive:!0,mode:493}),await F0(`git clone --depth 1 --branch ${Q} --single-branch ${$} "${J}"`,{timeout:30000});let K=A.join(J,"skills",O);try{await V.access(K)}catch{return b.warn(`Skill ${O} not found in official repository`),await V.rm(J,{recursive:!0,force:!0}),!1}try{await V.rm(Z,{recursive:!0,force:!0})}catch{}return await V.cp(K,Z,{recursive:!0}),await V.rm(J,{recursive:!0,force:!0}),b.info(`Successfully installed: ${O}`),!0}catch(K){try{await V.rm(J,{recursive:!0,force:!0})}catch{}return b.warn(`Failed to install ${O}: ${K instanceof Error?K.message:"Unknown error"}`),!1}}async ensureDefaultSkillsInstalled(){await V.mkdir(this.skillsDir,{recursive:!0,mode:493});for(let O of k0.defaultSkills)if(!await this.isInstalled(O))await this.installOfficialSkill(O)}async installFromRepo(O,$){let Q=$||this.extractRepoName(O),Z=A.join(this.skillsDir,Q),J=A.join(this.skillsDir,`.tmp-repo-${Q}-${Date.now()}`);try{if(!await this.isGitAvailable())return b.warn("Git not available, cannot install from repo"),!1;b.info(`Installing skill from repo: ${O}...`),await V.mkdir(this.skillsDir,{recursive:!0,mode:493}),await F0(`git clone --depth 1 "${O}" "${J}"`,{timeout:60000});let K=A.join(J,"SKILL.md");try{await V.access(K)}catch{return b.warn(`No SKILL.md found in repository ${O}`),await V.rm(J,{recursive:!0,force:!0}),!1}await V.rm(Z,{recursive:!0,force:!0}),await V.rename(J,Z);try{await V.rm(A.join(Z,".git"),{recursive:!0,force:!0})}catch{}return b.info(`Successfully installed skill from repo: ${Q}`),!0}catch(K){try{await V.rm(J,{recursive:!0,force:!0})}catch{}return b.warn(`Failed to install from repo ${O}: ${K instanceof Error?K.message:"Unknown error"}`),!1}}async installFromLocal(O,$,Q=!0){let Z=$||A.basename(O),J=A.join(this.skillsDir,Z);try{let K=A.resolve(O);try{await V.access(K)}catch{return b.warn(`Local path does not exist: ${K}`),!1}let q=A.join(K,"SKILL.md");try{await V.access(q)}catch{return b.warn(`No SKILL.md found in local path: ${K}`),!1}if(b.info(`Installing skill from local path: ${K}...`),await V.mkdir(this.skillsDir,{recursive:!0,mode:493}),await V.rm(J,{recursive:!0,force:!0}),Q)await V.symlink(K,J,"dir"),b.info(`Created symlink for skill: ${Z}`);else await V.cp(K,J,{recursive:!0}),b.info(`Copied skill to: ${Z}`);return!0}catch(K){return b.warn(`Failed to install from local path ${O}: ${K instanceof Error?K.message:"Unknown error"}`),!1}}extractRepoName(O){return O.match(/\/([^/]+?)(\.git)?$/)?.[1]||"unknown-skill"}async installAllOfficialSkills(){let{url:O,branch:$}=k0,Q=A.join(this.skillsDir,`.tmp-all-${Date.now()}`),Z=[],J=[];try{if(!await this.isGitAvailable())return b.warn("Git not available, skipping skill installation"),{installed:Z,failed:J};await V.mkdir(this.skillsDir,{recursive:!0,mode:493}),b.info("Cloning official skills repository..."),await F0(`git clone --depth 1 --branch ${$} --single-branch ${O} "${Q}"`,{timeout:60000});let K=A.join(Q,"skills"),q=await V.readdir(K,{withFileTypes:!0});for(let W of q){if(!W.isDirectory())continue;let G=W.name,Y=A.join(K,G),X=A.join(this.skillsDir,G);try{await V.access(A.join(Y,"SKILL.md")),await V.rm(X,{recursive:!0,force:!0}),await V.cp(Y,X,{recursive:!0}),b.info(`Installed: ${G}`),Z.push(G)}catch(U){b.warn(`Failed to install ${G}`),J.push(G)}}await V.rm(Q,{recursive:!0,force:!0})}catch(K){try{await V.rm(Q,{recursive:!0,force:!0})}catch{}b.warn(`Failed to install skills: ${K instanceof Error?K.message:"Unknown error"}`)}return{installed:Z,failed:J}}}var P0=null;function D1(O){if(!P0)P0=new w1(O);return P0}import*as a from"node:fs/promises";import*as U0 from"node:path";import{parse as lO}from"yaml";var sO=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/,nO=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/,C1=1024;function iO(O){if(!O)return;if(typeof O==="string")return O.split(",").map(($)=>$.trim()).filter(Boolean);if(Array.isArray(O))return O.map(($)=>String($).trim()).filter(Boolean);return}function N1(O){if(O===void 0)return;if(typeof O==="boolean")return O;if(typeof O==="string"){let $=O.toLowerCase().trim();if($==="true"||$==="yes"||$==="1")return!0;if($==="false"||$==="no"||$==="0")return!1}return}function oO(O,$){if(!O.name)return{valid:!1,error:"Missing required field: name"};if(!nO.test(O.name))return{valid:!1,error:`Invalid name "${O.name}": must be lowercase letters, numbers, and hyphens only, 1-64 characters`};if(!O.description)return{valid:!1,error:"Missing required field: description"};if(O.description.length>C1)return{valid:!1,error:`Description too long: ${O.description.length} characters (max ${C1})`};let Q;if(O.model)Q=O.model==="inherit"?"inherit":O.model;return{valid:!0,metadata:{name:O.name,description:O.description.trim(),allowedTools:iO(O["allowed-tools"]),version:O.version,argumentHint:O["argument-hint"]?.trim(),userInvocable:N1(O["user-invocable"]),disableModelInvocation:N1(O["disable-model-invocation"]),model:Q,whenToUse:O.when_to_use?.trim()}}}function E1(O,$,Q){let Z=O.match(sO);if(!Z)return{success:!1,error:"Invalid SKILL.md format: missing YAML frontmatter (must start with ---)"};let[,J,K]=Z,q;try{q=lO(J)}catch(Y){return{success:!1,error:`Failed to parse YAML frontmatter: ${Y instanceof Error?Y.message:String(Y)}`}}let W=oO(q,$);if(!W.valid)return{success:!1,error:W.error};let G=U0.dirname($);return{success:!0,content:{metadata:{...W.metadata,path:$,basePath:G,source:Q},instructions:K.trim()}}}async function V0(O,$){try{let Q=await a.readFile(O,"utf-8");return E1(Q,O,$)}catch(Q){if(Q.code==="ENOENT")return{success:!1,error:`File not found: ${O}`};return{success:!1,error:`Failed to read file: ${Q instanceof Error?Q.message:String(Q)}`}}}async function v1(O){try{let $=await a.readFile(O.path,"utf-8"),Q=E1($,O.path,O.source);return Q.success?Q.content:null}catch{return null}}async function R1(O){try{return await a.access(U0.join(O,"SKILL.md")),!0}catch{return!1}}var aO={userSkillsDir:D.join(y1(),".blade","skills"),projectSkillsDir:".blade/skills",claudeUserSkillsDir:D.join(y1(),".claude","skills"),claudeProjectSkillsDir:".claude/skills"},t=new Map;function f1(O){return D.resolve(O?.cwd??M())}class h{skills=new Map;pluginSkills=new Map;config;initialized=!1;constructor(O){this.config={...aO,cwd:M(),...O}}static getInstance(O){let $=f1(O),Q=t.get($);if(!Q)Q=new h({...O,cwd:D.resolve(O?.cwd??M())}),t.set($,Q);return Q}static resetInstance(){t.clear()}static releaseInstance(O,$){let Q=f1(O),Z=t.get(Q);if(!Z||$&&Z!==$)return!1;return t.delete(Q)}async initialize(){if(this.initialized)return{skills:Array.from(this.skills.values()),errors:[]};let O=[],$=[];try{await D1(this.config.userSkillsDir).ensureDefaultSkillsInstalled()}catch(K){O.push({path:"SkillInstaller",error:`Failed to install default skills: ${K instanceof Error?K.message:"Unknown error"}`})}this.loadBuiltinSkills();let Q=await this.scanDirectory(this.config.claudeUserSkillsDir,"user");$.push(...Q.skills),O.push(...Q.errors);let Z=await this.scanDirectory(this.config.userSkillsDir,"user");if($.push(...Z.skills),O.push(...Z.errors),(await N.getInstance().getStatus(this.config.cwd)).state==="trusted"){let K=D.isAbsolute(this.config.claudeProjectSkillsDir)?this.config.claudeProjectSkillsDir:D.join(this.config.cwd,this.config.claudeProjectSkillsDir),q=await this.scanDirectory(K,"project");$.push(...q.skills),O.push(...q.errors);let W=D.isAbsolute(this.config.projectSkillsDir)?this.config.projectSkillsDir:D.join(this.config.cwd,this.config.projectSkillsDir),G=await this.scanDirectory(W,"project");$.push(...G.skills),O.push(...G.errors)}for(let K of $)this.skills.set(K.name,K);return this.initialized=!0,{skills:Array.from(this.skills.values()),errors:O}}loadBuiltinSkills(){this.skills.set(X0.name,X0),this.skills.set(H0.name,H0)}async scanDirectory(O,$){let Q=[],Z=[];try{await j0.access(O)}catch{return{skills:Q,errors:Z}}try{let J=await j0.readdir(O,{withFileTypes:!0});for(let K of J){if(!K.isDirectory())continue;let q=D.join(O,K.name),W=D.join(q,"SKILL.md");if(!await R1(q))continue;let G=await V0(W,$);if(G.success&&G.content)Q.push(G.content.metadata);else Z.push({path:W,error:G.error||"Unknown error"})}}catch(J){Z.push({path:O,error:`Failed to scan directory: ${J instanceof Error?J.message:String(J)}`})}return{skills:Q,errors:Z}}getAll(){return Array.from(this.skills.values())}get(O){return this.skills.get(O)}has(O){return this.skills.has(O)}async loadContent(O){let $=this.skills.get(O);if(!$)return null;if($.source==="builtin")return this.loadBuiltinContent(O);return v1($)}loadBuiltinContent(O){switch(O){case"skill-creator":return T1();case"update-config":return _1();default:return null}}getModelInvocableSkills(){return Array.from(this.skills.values()).filter((O)=>!O.disableModelInvocation)}getUserInvocableSkills(){return Array.from(this.skills.values()).filter((O)=>O.userInvocable===!0)}generateAvailableSkillsList(){let O=this.getModelInvocableSkills().sort((Q,Z)=>Q.name<Z.name?-1:Q.name>Z.name?1:0);if(O.length===0)return"";let $=[];for(let Q of O){let Z=Q.description.length>100?`${Q.description.substring(0,97)}...`:Q.description,J=Q.argumentHint?`${Q.name} ${Q.argumentHint}`:Q.name;$.push(`- ${J}: ${Z}`)}return $.join(`
715
+ `)}get size(){return this.skills.size}async refresh(){return this.skills.clear(),this.pluginSkills.clear(),this.initialized=!1,this.initialize()}snapshot(){let O=new h({...this.config});return O.skills=new Map(Array.from(this.skills,([$,Q])=>[$,{...Q,...Q.allowedTools?{allowedTools:[...Q.allowedTools]}:{}}])),O.pluginSkills=new Map(Array.from(this.pluginSkills,([$,Q])=>[$,{...Q,metadata:{...Q.metadata,...Q.metadata.allowedTools?{allowedTools:[...Q.metadata.allowedTools]}:{}}}])),O.initialized=this.initialized,O}registerPluginSkill(O){this.pluginSkills.set(O.namespacedName,O),this.skills.set(O.namespacedName,O.metadata)}findPluginSkill(O){let $=this.pluginSkills.get(O);if($)return $;let Q=[];for(let Z of this.pluginSkills.values())if(Z.originalName===O)Q.push(Z);if(Q.length===1)return Q[0];return}getAllPluginSkills(){return Array.from(this.pluginSkills.values())}clearPluginSkills(){for(let O of this.pluginSkills.values())this.skills.delete(O.namespacedName);this.pluginSkills.clear()}getPluginSkillCount(){return this.pluginSkills.size}}function g(O){return h.getInstance(O)}import B0 from"node:path";import{execSync as tO}from"node:child_process";import h1 from"node:fs";import k1 from"node:path";class m0{async execute(O,$){let Q=O.content;if($.signal?.aborted)throw Error("Command execution aborted");return Q=this.interpolateArgs(Q,$.args),Q=await this.executeBashEmbeds(Q,$),Q=await this.resolveFileReferences(Q,$.workspaceRoot),Q}interpolateArgs(O,$){O=O.replace(/\$ARGUMENTS/g,$.join(" "));for(let Q=9;Q>=1;Q--){let Z=`$${Q}`,J=$[Q-1]??"";O=O.split(Z).join(J)}return O}async executeBashEmbeds(O,$){let Q=/!`([^`]+)`/g,Z=[];for(let K of O.matchAll(Q))Z.push({match:K[0],command:K[1]});let J=O;for(let{match:K,command:q}of Z){if($.signal?.aborted){J=J.replace(K,"[Execution aborted]");continue}try{let W=tO(q,{cwd:$.workspaceRoot,encoding:"utf-8",timeout:30000,maxBuffer:1048576,stdio:["pipe","pipe","pipe"]}).trim();J=J.replace(K,W)}catch(W){let G=W instanceof Error?W.message:String(W);J=J.replace(K,`[Error executing '${q}': ${G}]`)}}return J}async resolveFileReferences(O,$){let Q=/@([\w./-]+(?:\/[\w./-]+|\.[\w]+))/g,Z=[];for(let K of O.matchAll(Q))Z.push({match:K[0],relativePath:K[1]});let J=O;for(let{match:K,relativePath:q}of Z){let W=k1.resolve($,q);try{if(h1.statSync(W).isFile()){let Y=h1.readFileSync(W,"utf-8"),U=`\`\`\`${k1.extname(q).slice(1)||"text"}
716
716
  ${Y}
717
- \`\`\``;J=J.replace(K,U)}}catch{}}return J}hasDynamicContent(O){return{hasArgs:/\$ARGUMENTS|\$\d/.test(O),hasBashEmbeds:/!`[^`]+`/.test(O),hasFileRefs:/@[\w./-]+(?:\/[\w./-]+|\.[\w]+)/.test(O)}}}import m0 from"node:fs";import P1 from"node:os";import h from"node:path";import tO from"node:fs";import k1 from"node:path";import rO from"gray-matter";class P0{parse(O,$,Q,Z){try{let J=tO.readFileSync(O,"utf-8"),{data:K,content:q}=rO(J),{name:W,namespace:G}=this.extractNameAndNamespace(O,$);if(!W)return null;return{name:W,namespace:G,config:this.normalizeConfig(K),content:q.trim(),path:O,source:Q,sourceDir:Z}}catch(J){return console.error(`Failed to parse command file: ${O}`,J),null}}normalizeConfig(O){return{description:this.asString(O.description),allowedTools:this.parseAllowedTools(O["allowed-tools"]),argumentHint:this.asString(O["argument-hint"]),model:this.asString(O.model),disableModelInvocation:O["disable-model-invocation"]===!0}}asString(O){if(typeof O==="string"&&O.trim())return O.trim();return}parseAllowedTools(O){if(!O)return;if(Array.isArray(O))return O.map(($)=>String($).trim()).filter(Boolean);if(typeof O==="string")return O.split(",").map(($)=>$.trim()).filter(Boolean);return}extractNameAndNamespace(O,$){let Z=k1.relative($,O).split(k1.sep),J=Z.pop();if(!J)return{name:""};let K=J.replace(/\.md$/i,""),q=Z.length>0?Z.join("/"):void 0;return{name:K,namespace:q}}validateConfig(O){let $=[];if(O.model&&!this.isValidModelId(O.model))$.push(`Invalid model ID: ${O.model}`);return $}isValidModelId(O){return O.length>0&&O.length<200}}class d0{parser=new P0;async discover(O){let $=[],Q=[],Z=[],J=this.getSearchDirs(O);for(let K of J){if(!m0.existsSync(K.path))continue;Q.push(K.path);try{let q=await this.scanDirectory(K.path);for(let W of q)try{let G=this.parser.parse(W,K.path,K.source,K.sourceDir);if(G)$.push(G)}catch(G){Z.push({path:W,error:G instanceof Error?G.message:String(G)})}}catch(q){Z.push({path:K.path,error:q instanceof Error?q.message:String(q)})}}return{commands:$,scannedDirs:Q,errors:Z}}getSearchDirs(O){let $=P1.homedir();return[{path:h.join($,".blade","commands"),source:"user",sourceDir:"blade"},{path:h.join($,".claude","commands"),source:"user",sourceDir:"claude"},{path:h.join(O,".blade","commands"),source:"project",sourceDir:"blade"},{path:h.join(O,".claude","commands"),source:"project",sourceDir:"claude"}]}async scanDirectory(O){let $=[],Q=async(Z)=>{let J=await m0.promises.readdir(Z,{withFileTypes:!0});for(let K of J){let q=h.join(Z,K.name);if(K.isDirectory())await Q(q);else if(K.isFile()&&K.name.endsWith(".md"))$.push(q)}};return await Q(O),$}async hasCommands(O){let $=this.getSearchDirs(O);for(let Q of $){if(!m0.existsSync(Q.path))continue;if((await this.scanDirectory(Q.path)).length>0)return!0}return!1}getCommandDirs(O){let $=P1.homedir();return{projectBlade:h.join(O,".blade","commands"),projectClaude:h.join(O,".claude","commands"),userBlade:h.join($,".blade","commands"),userClaude:h.join($,".claude","commands")}}}class T{static instances=new Map;commands=new Map;pluginCommands=new Map;loader=new d0;executor=new k0;initialized=!1;workspaceRoot="";lastDiscoveryResult=null;static getInstance(O=M()){let $=p0.resolve(O),Q=T.instances.get($);if(!Q)Q=new T,T.instances.set($,Q);return Q}static resetInstance(){T.instances.clear()}static releaseInstance(O,$){let Q=p0.resolve(O),Z=T.instances.get(Q);if(!Z||$&&Z!==$)return!1;return T.instances.delete(Q)}static getExistingInstance(O=M()){return T.instances.get(p0.resolve(O))}constructor(){}async initialize(O){this.workspaceRoot=O;let $=await this.loader.discover(O),Q=(await N.getInstance().getStatus(O)).state==="trusted",Z={...$,commands:$.commands.filter((J)=>J.source!=="project"||Q)};this.lastDiscoveryResult=Z,this.commands.clear();for(let J of Z.commands)this.commands.set(J.name,J);return this.initialized=!0,Z}async refresh(){if(!this.workspaceRoot)throw Error("Registry not initialized. Call initialize() first.");return this.initialize(this.workspaceRoot)}isInitialized(){return this.initialized}getWorkspaceRoot(){return this.workspaceRoot}getCommand(O){return this.commands.get(O)}hasCommand(O){return this.commands.has(O)}getAllCommands(){return Array.from(this.commands.values())}getCommandCount(){return this.commands.size}getModelInvocableCommands(){return this.getAllCommands().filter((O)=>O.config.description&&!O.config.disableModelInvocation)}getModelInvocablePluginCommands(){return this.getAllPluginCommands().filter((O)=>O.config.description&&!O.config.disableModelInvocation)}async executeCommand(O,$){let Q=this.getCommand(O);if(!Q)return null;return this.executor.execute(Q,$)}getCommandLabel(O){let $=O.source==="project"?"project":"user";if(O.namespace)return`(${$}:${O.namespace})`;return`(${$})`}getCommandDisplayName(O){let $=[`/${O.name}`];if(O.config.argumentHint)$.push(O.config.argumentHint);if(O.config.description)$.push("-",O.config.description);return $.push(this.getCommandLabel(O)),$.join(" ")}getCommandsBySource(){let O=[],$=[];for(let Q of this.commands.values())if(Q.source==="project")O.push(Q);else $.push(Q);return{project:O,user:$}}getLastDiscoveryResult(){return this.lastDiscoveryResult}getCommandDirs(){if(!this.workspaceRoot)return null;return this.loader.getCommandDirs(this.workspaceRoot)}generateCommandListDescription(O=15000){let $=[...this.getModelInvocableCommands().map((q)=>({name:q.name,description:q.config.description,argumentHint:q.config.argumentHint,label:this.getCommandLabel(q)})),...this.getModelInvocablePluginCommands().map((q)=>({name:q.namespacedName,description:q.config.description,argumentHint:q.config.argumentHint,label:`(plugin:${q.pluginName})`}))],Q=$.length;if(Q===0)return{text:"No custom commands available.",includedCount:0,totalCount:0};let Z=`Available custom commands:
717
+ \`\`\``;J=J.replace(K,U)}}catch{}}return J}hasDynamicContent(O){return{hasArgs:/\$ARGUMENTS|\$\d/.test(O),hasBashEmbeds:/!`[^`]+`/.test(O),hasFileRefs:/@[\w./-]+(?:\/[\w./-]+|\.[\w]+)/.test(O)}}}import p0 from"node:fs";import m1 from"node:os";import k from"node:path";import rO from"node:fs";import P1 from"node:path";import eO from"gray-matter";class d0{parse(O,$,Q,Z){try{let J=rO.readFileSync(O,"utf-8"),{data:K,content:q}=eO(J),{name:W,namespace:G}=this.extractNameAndNamespace(O,$);if(!W)return null;return{name:W,namespace:G,config:this.normalizeConfig(K),content:q.trim(),path:O,source:Q,sourceDir:Z}}catch(J){return console.error(`Failed to parse command file: ${O}`,J),null}}normalizeConfig(O){return{description:this.asString(O.description),allowedTools:this.parseAllowedTools(O["allowed-tools"]),argumentHint:this.asString(O["argument-hint"]),model:this.asString(O.model),disableModelInvocation:O["disable-model-invocation"]===!0}}asString(O){if(typeof O==="string"&&O.trim())return O.trim();return}parseAllowedTools(O){if(!O)return;if(Array.isArray(O))return O.map(($)=>String($).trim()).filter(Boolean);if(typeof O==="string")return O.split(",").map(($)=>$.trim()).filter(Boolean);return}extractNameAndNamespace(O,$){let Z=P1.relative($,O).split(P1.sep),J=Z.pop();if(!J)return{name:""};let K=J.replace(/\.md$/i,""),q=Z.length>0?Z.join("/"):void 0;return{name:K,namespace:q}}validateConfig(O){let $=[];if(O.model&&!this.isValidModelId(O.model))$.push(`Invalid model ID: ${O.model}`);return $}isValidModelId(O){return O.length>0&&O.length<200}}class g0{parser=new d0;async discover(O){let $=[],Q=[],Z=[],J=this.getSearchDirs(O);for(let K of J){if(!p0.existsSync(K.path))continue;Q.push(K.path);try{let q=await this.scanDirectory(K.path);for(let W of q)try{let G=this.parser.parse(W,K.path,K.source,K.sourceDir);if(G)$.push(G)}catch(G){Z.push({path:W,error:G instanceof Error?G.message:String(G)})}}catch(q){Z.push({path:K.path,error:q instanceof Error?q.message:String(q)})}}return{commands:$,scannedDirs:Q,errors:Z}}getSearchDirs(O){let $=m1.homedir();return[{path:k.join($,".blade","commands"),source:"user",sourceDir:"blade"},{path:k.join($,".claude","commands"),source:"user",sourceDir:"claude"},{path:k.join(O,".blade","commands"),source:"project",sourceDir:"blade"},{path:k.join(O,".claude","commands"),source:"project",sourceDir:"claude"}]}async scanDirectory(O){let $=[],Q=async(Z)=>{let J=await p0.promises.readdir(Z,{withFileTypes:!0});for(let K of J){let q=k.join(Z,K.name);if(K.isDirectory())await Q(q);else if(K.isFile()&&K.name.endsWith(".md"))$.push(q)}};return await Q(O),$}async hasCommands(O){let $=this.getSearchDirs(O);for(let Q of $){if(!p0.existsSync(Q.path))continue;if((await this.scanDirectory(Q.path)).length>0)return!0}return!1}getCommandDirs(O){let $=m1.homedir();return{projectBlade:k.join(O,".blade","commands"),projectClaude:k.join(O,".claude","commands"),userBlade:k.join($,".blade","commands"),userClaude:k.join($,".claude","commands")}}}class x{static instances=new Map;commands=new Map;pluginCommands=new Map;loader=new g0;executor=new m0;initialized=!1;workspaceRoot="";lastDiscoveryResult=null;static getInstance(O=M()){let $=B0.resolve(O),Q=x.instances.get($);if(!Q)Q=new x,x.instances.set($,Q);return Q}static empty(O){let $=new x;return $.workspaceRoot=B0.resolve(O),$.initialized=!0,$}static resetInstance(){x.instances.clear()}static releaseInstance(O,$){let Q=B0.resolve(O),Z=x.instances.get(Q);if(!Z||$&&Z!==$)return!1;return x.instances.delete(Q)}static getExistingInstance(O=M()){return x.instances.get(B0.resolve(O))}constructor(){}async initialize(O){this.workspaceRoot=O;let $=await this.loader.discover(O),Q=(await N.getInstance().getStatus(O)).state==="trusted",Z={...$,commands:$.commands.filter((J)=>J.source!=="project"||Q)};this.lastDiscoveryResult=Z,this.commands.clear();for(let J of Z.commands)this.commands.set(J.name,J);return this.initialized=!0,Z}async refresh(){if(!this.workspaceRoot)throw Error("Registry not initialized. Call initialize() first.");return this.initialize(this.workspaceRoot)}isInitialized(){return this.initialized}getWorkspaceRoot(){return this.workspaceRoot}getCommand(O){return this.commands.get(O)}hasCommand(O){return this.commands.has(O)}getAllCommands(){return Array.from(this.commands.values())}getCommandCount(){return this.commands.size}getModelInvocableCommands(){return this.getAllCommands().filter((O)=>O.config.description&&!O.config.disableModelInvocation)}getModelInvocablePluginCommands(){return this.getAllPluginCommands().filter((O)=>O.config.description&&!O.config.disableModelInvocation)}async executeCommand(O,$){let Q=this.getCommand(O);if(!Q)return null;return this.executor.execute(Q,$)}getCommandLabel(O){let $=O.source==="project"?"project":"user";if(O.namespace)return`(${$}:${O.namespace})`;return`(${$})`}getCommandDisplayName(O){let $=[`/${O.name}`];if(O.config.argumentHint)$.push(O.config.argumentHint);if(O.config.description)$.push("-",O.config.description);return $.push(this.getCommandLabel(O)),$.join(" ")}getCommandsBySource(){let O=[],$=[];for(let Q of this.commands.values())if(Q.source==="project")O.push(Q);else $.push(Q);return{project:O,user:$}}getLastDiscoveryResult(){return this.lastDiscoveryResult}getCommandDirs(){if(!this.workspaceRoot)return null;return this.loader.getCommandDirs(this.workspaceRoot)}generateCommandListDescription(O=15000){let $=[...this.getModelInvocableCommands().map((q)=>({name:q.name,description:q.config.description,argumentHint:q.config.argumentHint,label:this.getCommandLabel(q)})),...this.getModelInvocablePluginCommands().map((q)=>({name:q.namespacedName,description:q.config.description,argumentHint:q.config.argumentHint,label:`(plugin:${q.pluginName})`}))],Q=$.length;if(Q===0)return{text:"No custom commands available.",includedCount:0,totalCount:0};let Z=`Available custom commands:
718
718
 
719
719
  `,J=Z.length,K=0;for(let q of $){let W=q.argumentHint?` ${q.argumentHint}`:"",G=`- /${q.name}${W}: ${q.description} ${q.label}
720
720
  `;if(J+G.length>O)break;Z+=G,J+=G.length,K++}if(K<Q)Z+=`
721
- (${K} of ${Q} commands shown due to character budget)`;return{text:Z,includedCount:K,totalCount:Q}}snapshot(){let O=new T;return O.workspaceRoot=this.workspaceRoot,O.commands=new Map(Array.from(this.commands,([$,Q])=>[$,{...Q,config:{...Q.config,...Q.config.allowedTools?{allowedTools:[...Q.config.allowedTools]}:{}}}])),O.pluginCommands=new Map(Array.from(this.pluginCommands,([$,Q])=>[$,{...Q,config:{...Q.config,...Q.config.allowedTools?{allowedTools:[...Q.config.allowedTools]}:{}}}])),O.initialized=this.initialized,O.lastDiscoveryResult=this.lastDiscoveryResult?{commands:Array.from(O.commands.values()),scannedDirs:[...this.lastDiscoveryResult.scannedDirs],errors:this.lastDiscoveryResult.errors.map(($)=>({...$}))}:null,O}registerPluginCommand(O){this.pluginCommands.set(O.namespacedName,O)}findPluginCommand(O){let $=this.pluginCommands.get(O);if($)return $;let Q=[];for(let Z of this.pluginCommands.values())if(Z.originalName===O)Q.push(Z);if(Q.length===1)return Q[0];return}hasPluginCommand(O){return this.findPluginCommand(O)!==void 0}getAllPluginCommands(){return Array.from(this.pluginCommands.values())}async executePluginCommand(O,$){let Q=this.findPluginCommand(O);if(!Q)return null;let Z={name:Q.namespacedName,config:Q.config,content:Q.content,path:Q.path,source:"project",sourceDir:"blade"};return this.executor.execute(Z,$)}clearPluginCommands(){this.pluginCommands.clear()}getPluginCommandCount(){return this.pluginCommands.size}hasPluginCommandConflict(O){let $=0;for(let Q of this.pluginCommands.values())if(Q.originalName===O){if($++,$>1)return!0}return!1}getPluginCommandProviders(O){let $=[];for(let Q of this.pluginCommands.values())if(Q.originalName===O)$.push(Q.pluginName);return $}}import e0 from"node:path";import{satisfies as g0,validRange as m1}from"semver";var eO=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function c0(O){if(O.bladeVersion!==void 0&&(!O.bladeVersion.trim()||!m1(O.bladeVersion)))throw Error(`Invalid Blade version range in plugin "${O.name}": ${O.bladeVersion}`);for(let[$,Q]of Object.entries(O.dependencies??{})){if(!eO.test($))throw Error(`Invalid dependency name in plugin "${O.name}": ${$}`);if($===O.name)throw Error(`Plugin "${O.name}" cannot depend on itself`);if(!Q.trim()||!m1(Q))throw Error(`Invalid dependency range for ${$} in plugin "${O.name}": ${Q}`)}}function p1(O,$=u0()){if(c0(O),O.bladeVersion&&!g0($,O.bladeVersion))throw Error(`Plugin "${O.name}" requires Blade ${O.bladeVersion}, current ${$}`)}function d1(O,$){O.status="error",O.compatibilityIssues=[...O.compatibilityIssues??[],$],O.error=O.compatibilityIssues.map((Q)=>Q.message).join("; ")}function g1(O,$=u0()){let Q=[],Z=new Map(O.map((K)=>[K.manifest.name,K]));for(let K of O){if(K.status!=="active")continue;if(K.manifest.bladeVersion&&!g0($,K.manifest.bladeVersion)){let q={code:"blade-version",expected:K.manifest.bladeVersion,actual:$,message:`Requires Blade ${K.manifest.bladeVersion}, current ${$}`};d1(K,q),Q.push(q)}}let J=!0;while(J){J=!1;for(let K of O){if(K.status!=="active")continue;for(let[q,W]of Object.entries(K.manifest.dependencies??{})){let G=Z.get(q),Y;if(!G)Y={code:"dependency-missing",dependency:q,expected:W,message:`Missing dependency ${q}@${W}`};else if(!g0(G.manifest.version,W))Y={code:"dependency-version",dependency:q,expected:W,actual:G.manifest.version,message:`Dependency ${q} requires ${W}, found ${G.manifest.version}`};else if(G.status!=="active")Y={code:"dependency-inactive",dependency:q,expected:W,actual:G.status,message:`Dependency ${q} is ${G.status}`};if(!Y)continue;d1(K,Y),Q.push(Y),J=!0;break}}}return Q}import{execFile as V$}from"node:child_process";import{createHash as j$,randomUUID as e1}from"node:crypto";import{constants as O0,promises as F}from"node:fs";import{homedir as n0}from"node:os";import j from"node:path";import{promisify as B$}from"node:util";import{Mutex as S$}from"async-mutex";import{satisfies as i0}from"semver";import z$ from"write-file-atomic";import*as B0 from"node:fs/promises";import*as a1 from"node:path";var c=L.String({minLength:2,maxLength:64,pattern:"^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]{1,2}$"}),l0=L.String({pattern:"^\\d+\\.\\d+\\.\\d+(-[\\w.]+)?(\\+[\\w.]+)?$"}),O$=L.Object({name:L.String({minLength:1}),email:L.Optional(L.String({format:"email"})),url:L.Optional(L.String({format:"uri"}))}),l1=L.Object({name:c,description:L.String({minLength:1,maxLength:500}),version:l0,author:L.Optional(O$),license:L.Optional(L.String()),repository:L.Optional(L.String({format:"uri"})),homepage:L.Optional(L.String({format:"uri"})),keywords:L.Optional(L.Array(L.String())),dependencies:L.Optional(L.Record(L.String(),L.String())),bladeVersion:L.Optional(L.String())}),$$=L.Union([L.Object({type:L.Literal("git"),url:L.String({minLength:1}),ref:L.Optional(L.String({minLength:1}))},{additionalProperties:!1}),L.Object({type:L.Literal("local"),path:L.String({minLength:1})},{additionalProperties:!1}),L.Object({type:L.Literal("marketplace"),marketplace:c},{additionalProperties:!1})]),Q$=L.Object({name:c,source:$$,installPath:L.String({minLength:1}),version:l0,revision:L.String({minLength:1,maxLength:128}),contentDigest:L.String({pattern:"^[a-f0-9]{64}$"}),installedAt:L.String({format:"date-time"}),updatedAt:L.String({format:"date-time"})},{additionalProperties:!1}),Z$=L.Union([L.Object({type:L.Literal("git"),url:L.String({minLength:1}),ref:L.Optional(L.String({minLength:1}))},{additionalProperties:!1}),L.Object({type:L.Literal("local"),path:L.String({minLength:1})},{additionalProperties:!1})]),J$=L.Object({name:c,source:Z$,installPath:L.String({minLength:1}),revision:L.String({minLength:1,maxLength:128}),contentDigest:L.String({pattern:"^[a-f0-9]{64}$"}),addedAt:L.String({format:"date-time"}),updatedAt:L.String({format:"date-time"})},{additionalProperties:!1}),q$=L.Object({version:L.Literal(1),installed:L.Record(L.String(),Q$),marketplaces:L.Record(L.String(),J$)},{additionalProperties:!1}),s1=L.Object({name:L.String({minLength:1}),email:L.Optional(L.String({format:"email"})),url:L.Optional(L.String({format:"uri"}))}),K$=L.Object({name:c,description:L.Optional(L.String({maxLength:500})),version:L.Optional(l0),author:L.Optional(L.Union([L.String({minLength:1}),s1])),source:L.Union([L.String({minLength:1}),L.Object({source:L.Literal("url"),url:L.String({minLength:1}),ref:L.Optional(L.String({minLength:1})),sha:L.Optional(L.String({pattern:"^[a-fA-F0-9]{40}$"}))})]),category:L.Optional(L.String()),homepage:L.Optional(L.String({format:"uri"})),tags:L.Optional(L.Array(L.String()))}),G$=L.Object({name:c,description:L.Optional(L.String({maxLength:500})),owner:L.Optional(s1),metadata:L.Optional(L.Object({description:L.Optional(L.String({maxLength:500})),version:L.Optional(L.String())})),plugins:L.Array(K$,{maxItems:5000})}),u1=L.Object({type:c1(["stdio","sse","http"]),command:L.Optional(L.String()),args:L.Optional(L.Array(L.String())),env:L.Optional(L.Record(L.String(),L.String())),cwd:L.Optional(L.String()),url:L.Optional(L.String({format:"uri"})),headers:L.Optional(L.Record(L.String(),L.String())),timeout:L.Optional(L.Integer({minimum:1000,maximum:1800000})),idleTimeout:L.Optional(L.Integer({minimum:1000,maximum:1800000})),sampling:L.Optional(L.Object({enabled:L.Boolean(),maxTokens:L.Optional(L.Integer({minimum:1,maximum:4096})),maxRequestsPerToolCall:L.Optional(L.Integer({minimum:1,maximum:8})),maxInputBytes:L.Optional(L.Integer({minimum:1,maximum:1048576}))})),oauth:L.Optional(L.Object({enabled:L.Optional(L.Boolean()),clientId:L.Optional(L.String({minLength:1,maxLength:4096})),scopes:L.Optional(L.Array(L.String({minLength:1,maxLength:128}),{maxItems:32})),callbackPort:L.Optional(L.Integer({minimum:1024,maximum:65535}))},{additionalProperties:!1})),healthCheck:L.Optional(L.Object({enabled:L.Optional(L.Boolean()),interval:L.Optional(L.Number({exclusiveMinimum:0})),timeout:L.Optional(L.Number({exclusiveMinimum:0})),failureThreshold:L.Optional(L.Number({exclusiveMinimum:0}))}))}),L$=L.Union([L.Object({mcpServers:L.Record(L.String(),u1)}),L.Record(L.String(),u1)]);function n1(O){return u(L$,O)}function i1(O){return u(q$,O)}function o1(O){return u(G$,O)}var W$=[{dir:".blade-plugin",source:"blade"},{dir:".claude-plugin",source:"claude"}];async function r(O){for(let{dir:$,source:Q}of W$){let Z=a1.join(O,$,"plugin.json");try{await B0.access(Z)}catch{continue}try{let J=await B0.readFile(Z,"utf-8"),K=JSON.parse(J),q=u(l1,K);if(!q.success){let W=q.error.issues.map((G)=>`${G.path.join(".")}: ${G.message}`).join("; ");throw Error(`Invalid plugin.json: ${W}`)}return c0(q.data),S.debug(`Parsed plugin manifest from ${Z}`),{manifest:q.data,source:Q,manifestPath:Z}}catch(J){if(J instanceof SyntaxError)throw Error(`Invalid JSON in ${Z}: ${J.message}`);throw J}}return null}import{realpathSync as Y$}from"node:fs";import s0 from"node:path";var X$=/^[a-fA-F0-9]{40}$/;class f extends Error{code;constructor(O,$){super($);this.code=O;this.name="PluginSourcePolicyError"}}function H$(O,$){let Q=(J)=>{try{return Y$.native(J)}catch{return s0.resolve(J)}},Z=s0.relative(Q(O),Q($));return Z===""||!Z.startsWith("..")&&!s0.isAbsolute(Z)}function F$(O){let $=O.match(/^[^@]+@([^:]+):/);if($?.[1])return $[1].toLowerCase();try{return new URL(O).hostname.toLowerCase()}catch{return}}function U$(O,$){if(!$.startsWith("*."))return O===$;let Q=$.slice(1);return O.endsWith(Q)&&O.length>Q.length}function t1(O,$,Q){if(O.requireGitCommitSha&&(!$.ref||!X$.test($.ref)))throw new f("PLUGIN_GIT_SHA_REQUIRED",`${Q} must pin a full 40-character Git commit SHA`);if(!O.restrictToAllowedSources)return;let Z=F$($.url);if(!Z||!O.allowedGitHosts.some((J)=>U$(Z,J)))throw new f("PLUGIN_SOURCE_BLOCKED",`${Q} Git host is not allowed by plugin source policy`)}function r1(O,$,Q){if(!O.restrictToAllowedSources)return;if(!O.allowedLocalRoots.some((Z)=>H$(Z,$)))throw new f("PLUGIN_SOURCE_BLOCKED",`${Q} local path is not allowed by plugin source policy`)}function l(O,$,Q="Marketplace"){if($.type==="git")t1(O,$,Q);else r1(O,$.path,Q)}function e(O,$,Q,Z="Plugin"){if($.type==="git"){t1(O,$,Z);return}if($.type==="local"){r1(O,$.path,Z);return}if(O.restrictToAllowedSources&&!O.allowedMarketplaces.includes($.marketplace))throw new f("PLUGIN_SOURCE_BLOCKED",`Marketplace "${$.marketplace}" is not allowed by plugin source policy`);let J=Q[$.marketplace];if(!J)throw new f("MARKETPLACE_NOT_FOUND",`Marketplace "${$.marketplace}" is not configured`);l(O,J.source,`Marketplace "${$.marketplace}"`)}var M$=B$(V$),I$=1,OO=2097152,$O=1e4,QO=104857600,b$=120000,A$=15000,x$=600000,t0=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/,ZO=/^[a-fA-F0-9]{40}$/,T$=[j.join(".blade-plugin","marketplace.json"),j.join(".claude-plugin","marketplace.json"),"marketplace.json"];class H extends Error{code;constructor(O,$){super($);this.code=O;this.name="PluginPackageError"}}function _$(){return{version:I$,installed:{},marketplaces:{}}}function s(O){return O.code==="ENOENT"}function n(O){if(O instanceof H||O instanceof f)return{code:O.code,message:O.message};return{code:"PLUGIN_PACKAGE_ERROR",message:O instanceof Error?O.message:String(O)}}function o0(O){return j.isAbsolute(O)||O.startsWith("./")||O.startsWith("../")||O==="~"||O.startsWith("~/")}function $0(O,$){let Q=j.relative(O,$);return Q===""||!Q.startsWith("..")&&!j.isAbsolute(Q)}function i(O,$="plugin"){if(!t0.test(O))throw new H("INVALID_PLUGIN_NAME",`Invalid ${$} name: ${O}`);return O}function w$(O){if(O.startsWith("git@"))return;let $=O.lastIndexOf("@");if($<=0||$===O.length-1)return;let Q=O.slice(0,$),Z=O.slice($+1);if(!t0.test(Q)||!t0.test(Z))return;return{pluginName:Q,marketplace:Z}}class JO{userPluginsDir;stateRoot;statePath;mutex=new S$;constructor(O,$){this.userPluginsDir=O??j.join(n0(),".blade","plugins"),this.stateRoot=$??j.join(j.dirname(this.userPluginsDir),"plugin-state"),this.statePath=j.join(this.stateRoot,"state.json")}async install(O,$={}){return this.runMutation(async()=>{let Q=[];try{this.requireSourceTrust($.trusted);let Z=await this.readState(),J=await this.resolvePluginSource(O,Z,$),K=this.effectivePolicy($.policy);if(e(K,J.recordSource,Z.marketplaces),J.expectedName&&Z.installed[J.expectedName])throw new H("PLUGIN_ALREADY_INSTALLED",`Plugin "${J.expectedName}" is already installed`);let q=await this.preparePluginClosure({state:Z,source:J.source,recordSource:J.recordSource,expectedName:J.expectedName,policy:K,updateRoot:!1});Q=q.prepared;let W=await this.commitPreparedPlugins(Z,Q),G=W.records.get(q.root.name);if(!G)throw new H("PLUGIN_PACKAGE_ERROR","Root plugin was not committed");let Y=Q.map((X)=>X.name).filter((X)=>X!==q.root.name);return S.info(`Installed managed plugin ${q.root.name} at revision ${G.revision}`),{success:!0,pluginName:q.root.name,pluginPath:G.installPath,manifest:q.root.manifest,installation:G,installedDependencies:Y,changed:W.changed.has(q.root.name)}}catch(Z){await this.cleanupPreparedPlugins(Q);let J=n(Z);return{success:!1,code:J.code,error:J.message}}})}async update(O,$={}){return this.runMutation(async()=>{let Q=[];try{this.requireSourceTrust($.trusted),i(O);let Z=await this.readState(),J=Z.installed[O];if(!J)throw new H("PLUGIN_NOT_MANAGED",`Plugin "${O}" is not managed by Blade's package store`);let K=this.effectivePolicy($.policy);e(K,J.source,Z.marketplaces);let q=await this.preparePluginClosure({state:Z,source:J.source,recordSource:J.source,expectedName:O,policy:K,updateRoot:!0});Q=q.prepared;let W=await this.commitPreparedPlugins(Z,Q),G=W.records.get(O);if(!G)throw new H("PLUGIN_PACKAGE_ERROR","Updated root plugin was not committed");let Y=Q.map((X)=>X.name).filter((X)=>X!==O&&W.changed.has(X));return S.info(`Updated managed plugin ${O} to revision ${G.revision}`),{success:!0,pluginName:O,pluginPath:G.installPath,manifest:q.root.manifest,installation:G,updatedDependencies:Y,changed:W.changed.has(O)}}catch(Z){await this.cleanupPreparedPlugins(Q);let J=n(Z);return{success:!1,pluginName:O,code:J.code,error:J.message}}})}async uninstall(O,$=!1){return this.runMutation(async()=>{try{if(i(O),!$)throw new H("CONFIRMATION_REQUIRED",`Uninstalling "${O}" requires explicit confirmation`);let Q=await this.readState(),Z=Q.installed[O];if(!Z)throw new H("PLUGIN_NOT_MANAGED",`Plugin "${O}" is not managed by Blade's package store`);return delete Q.installed[O],await this.writeState(Q),S.info(`Uninstalled managed plugin ${O}`),{success:!0,pluginName:O,installation:Z}}catch(Q){let Z=n(Q);return{success:!1,pluginName:O,code:Z.code,error:Z.message}}})}async listInstalled(){return Object.keys((await this.readState()).installed).sort()}async listInstallationRecords(){return Object.values((await this.readState()).installed).sort((O,$)=>O.name.localeCompare($.name))}async getInstallation(O){return(await this.readState()).installed[O]}async verifyInstallation(O){let $=await F.lstat(O.installPath);if(!$.isDirectory()||$.isSymbolicLink())throw new H("PLUGIN_PACKAGE_TAMPERED",`Managed plugin "${O.name}" has an invalid package path`);let Q=await F.realpath(this.stateRoot),Z=await F.realpath(O.installPath);if(!$0(Q,Z))throw new H("PLUGIN_PACKAGE_TAMPERED",`Managed plugin "${O.name}" has an invalid package path`);if(await this.digestTree(Z)!==O.contentDigest)throw new H("PLUGIN_PACKAGE_TAMPERED",`Managed plugin "${O.name}" failed content verification`);let K=await r(Z);if(!K||K.manifest.name!==O.name||K.manifest.version!==O.version)throw new H("PLUGIN_PACKAGE_TAMPERED",`Managed plugin "${O.name}" failed manifest verification`)}async addMarketplace(O,$={}){return this.runMutation(async()=>{let Q;try{let Z=await this.normalizeMarketplaceSource(O,$);l(this.effectivePolicy($.policy),Z);let J=await this.readState();Q=await this.materializeSource(Z);let K=await this.readMarketplaceManifest(Q.stagingPath),q=i(K.name,"marketplace");if(J.marketplaces[q])throw new H("MARKETPLACE_ALREADY_EXISTS",`Marketplace "${q}" is already configured`);let{revision:W,contentDigest:G}=Q,Y=await this.publishPackage("marketplaces",q,Q);Q=void 0;let X=new Date().toISOString(),U={name:q,source:Z,installPath:Y,revision:W,contentDigest:G,addedAt:X,updatedAt:X};return J.marketplaces[q]=U,await this.writeState(J),{success:!0,marketplace:U,manifest:K,changed:!0}}catch(Z){if(Q)await F.rm(Q.stagingPath,{recursive:!0,force:!0});let J=n(Z);return{success:!1,code:J.code,error:J.message}}})}async refreshMarketplace(O,$){return this.runMutation(async()=>{let Q;try{i(O,"marketplace");let Z=await this.readState(),J=Z.marketplaces[O];if(!J)throw new H("MARKETPLACE_NOT_FOUND",`Marketplace "${O}" is not configured`);l(this.effectivePolicy($),J.source,`Marketplace "${O}"`),Q=await this.materializeSource(J.source);let K=await this.readMarketplaceManifest(Q.stagingPath);if(K.name!==O)throw new H("MARKETPLACE_IDENTITY_MISMATCH",`Marketplace "${O}" now declares "${K.name}"`);if(J.revision===Q.revision&&J.contentDigest===Q.contentDigest)return await F.rm(Q.stagingPath,{recursive:!0,force:!0}),Q=void 0,{success:!0,marketplace:J,manifest:K,changed:!1};let{revision:q,contentDigest:W}=Q,G=await this.publishPackage("marketplaces",O,Q);Q=void 0;let Y={...J,installPath:G,revision:q,contentDigest:W,updatedAt:new Date().toISOString()};return Z.marketplaces[O]=Y,await this.writeState(Z),{success:!0,marketplace:Y,manifest:K,changed:!0}}catch(Z){if(Q)await F.rm(Q.stagingPath,{recursive:!0,force:!0});let J=n(Z);return{success:!1,code:J.code,error:J.message}}})}async removeMarketplace(O,$=!1){return this.runMutation(async()=>{try{if(i(O,"marketplace"),!$)throw new H("CONFIRMATION_REQUIRED",`Removing marketplace "${O}" requires explicit confirmation`);let Q=await this.readState(),Z=Q.marketplaces[O];if(!Z)throw new H("MARKETPLACE_NOT_FOUND",`Marketplace "${O}" is not configured`);let J=Object.values(Q.installed).filter((K)=>K.source.type==="marketplace"&&K.source.marketplace===O).map((K)=>K.name).sort();if(J.length>0)throw new H("MARKETPLACE_IN_USE",`Marketplace "${O}" still owns installed plugins: ${J.join(", ")}`);return delete Q.marketplaces[O],await this.writeState(Q),{success:!0,marketplace:Z,changed:!0}}catch(Q){let Z=n(Q);return{success:!1,code:Z.code,error:Z.message}}})}async listMarketplaces(){return Object.values((await this.readState()).marketplaces).sort((O,$)=>O.name.localeCompare($.name))}async listCatalogs(){let O=await this.listMarketplaces();return Promise.all(O.map(async($)=>({marketplace:$,manifest:await this.readMarketplaceManifest($.installPath)})))}async runMutation(O){return this.mutex.runExclusive(async()=>{let $=await this.acquireStoreLock();try{return await O()}finally{await $()}})}async acquireStoreLock(){await this.ensureStoreDirectory();let O=j.join(this.stateRoot,".operation.lock"),$=e1(),Q=Date.now()+A$;while(Date.now()<Q)try{let Z=await F.open(O,O0.O_CREAT|O0.O_EXCL|O0.O_WRONLY,384);return await Z.writeFile(`${JSON.stringify({version:1,pid:process.pid,token:$,createdAt:new Date().toISOString()})}
722
- `,"utf8"),await Z.close(),async()=>{try{if(JSON.parse(await F.readFile(O,"utf8")).token===$)await F.unlink(O)}catch(J){if(!s(J))S.warn(`Failed to release plugin package lock: ${J}`)}}}catch(Z){if(Z.code!=="EEXIST")throw Z;await this.removeStaleStoreLock(O),await new Promise((J)=>setTimeout(J,50))}throw new H("PLUGIN_STORE_BUSY","Plugin package store is busy; retry the operation")}async removeStaleStoreLock(O){try{let $=await F.lstat(O);if(!$.isFile()||$.isSymbolicLink())throw new H("PLUGIN_STORE_INVALID","Plugin package lock must be a regular file");if(process.getuid&&$.uid!==process.getuid()||($.mode&511)!==384)throw new H("PLUGIN_STORE_INVALID","Plugin package lock ownership or permissions are invalid");if(Date.now()-$.mtimeMs<x$)return;await F.unlink(O)}catch($){if(!s($)&&$ instanceof H)throw $}}requireSourceTrust(O){if(O!==!0)throw new H("SOURCE_TRUST_REQUIRED","Plugin installation or update requires explicit source trust")}effectivePolicy(O){return O??S0.pluginSourcePolicy}async preparePluginClosure(O){let $=[],Q=new Map,Z=[],J=(q,W,G,Y)=>{if(!i0(W,G))throw new H("DEPENDENCY_VERSION_MISMATCH",`Plugin "${Y}" requires ${q}@${G}, found ${W}`)},K=async(q)=>{let W=q.expectedName?O.state.installed[q.expectedName]:void 0;if(W&&!q.root&&q.requiredRange){if(i0(W.version,q.requiredRange))return W;if(q.recordSource.type!=="marketplace"||W.source.type!=="marketplace"||W.source.marketplace!==q.recordSource.marketplace)J(W.name,W.version,q.requiredRange,q.requiredBy??"dependency");q={...q,source:W.source,recordSource:W.source}}if(W&&q.root&&!O.updateRoot)throw new H("PLUGIN_ALREADY_INSTALLED",`Plugin "${W.name}" is already installed`);if(q.expectedName){let B=Q.get(q.expectedName);if(B){if(q.requiredRange)J(B.name,B.manifest.version,q.requiredRange,q.requiredBy??"dependency");return B}if(Z.includes(q.expectedName))throw new H("DEPENDENCY_CYCLE",`Plugin dependency cycle: ${[...Z,q.expectedName].join(" -> ")}`)}let G=await this.materializePluginSource(q.source,O.state,q.expectedName,O.policy),Y=await r(G.stagingPath);if(!Y)throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),new H("INVALID_PLUGIN","Plugin manifest was not found");let X=i(Y.manifest.name);if(q.expectedName&&q.expectedName!==X)throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),new H("PLUGIN_IDENTITY_MISMATCH",`Requested "${q.expectedName}" but source declares "${X}"`);if(Z.includes(X))throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),new H("DEPENDENCY_CYCLE",`Plugin dependency cycle: ${[...Z,X].join(" -> ")}`);if(q.root&&O.state.installed[X]&&!O.updateRoot)throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),new H("PLUGIN_ALREADY_INSTALLED",`Plugin "${X}" is already installed`);try{p1(Y.manifest)}catch(B){throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),new H("VERSION_INCOMPATIBLE",B instanceof Error?B.message:String(B))}let U={name:X,source:q.recordSource,manifest:Y.manifest,materialized:G,existing:O.state.installed[X]};Z.push(X);try{for(let[B,p]of Object.entries(Y.manifest.dependencies??{}).sort(([G0],[y])=>G0.localeCompare(y))){let G0=Q.get(B);if(G0){J(B,G0.manifest.version,p,X);continue}let y=O.state.installed[B];if(y&&i0(y.version,p))continue;if(q.recordSource.type!=="marketplace")throw new H(y?"DEPENDENCY_VERSION_MISMATCH":"DEPENDENCY_MISSING",y?`Plugin "${X}" requires ${B}@${p}, found ${y.version}`:`Plugin "${X}" requires missing dependency ${B}@${p}; direct sources cannot auto-install dependencies`);let C0=await K({source:y?.source.type==="marketplace"&&y.source.marketplace===q.recordSource.marketplace?y.source:{type:"marketplace",marketplace:q.recordSource.marketplace},recordSource:{type:"marketplace",marketplace:q.recordSource.marketplace},expectedName:B,requiredRange:p,requiredBy:X,root:!1});J(B,"manifest"in C0?C0.manifest.version:C0.version,p,X)}}catch(B){throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),B}finally{Z.pop()}return Q.set(X,U),$.push(U),U};try{let q=await K({source:O.source,recordSource:O.recordSource,expectedName:O.expectedName,root:!0});if(!("manifest"in q))throw new H("PLUGIN_PACKAGE_ERROR","Root plugin unexpectedly resolved to an existing dependency");return{root:q,prepared:$}}catch(q){throw await this.cleanupPreparedPlugins($),q}}async commitPreparedPlugins(O,$){let Q=new Map,Z=new Set,J=new Date().toISOString();for(let K of $){let q=K.existing;if(q?.revision===K.materialized.revision&&q.contentDigest===K.materialized.contentDigest){await F.rm(K.materialized.stagingPath,{recursive:!0,force:!0}),Q.set(K.name,q);continue}let W=await this.publishPackage("packages",K.name,K.materialized),G={name:K.name,source:K.source,installPath:W,version:K.manifest.version,revision:K.materialized.revision,contentDigest:K.materialized.contentDigest,installedAt:q?.installedAt??J,updatedAt:J};O.installed[K.name]=G,Q.set(K.name,G),Z.add(K.name)}if(Z.size>0)await this.writeState(O);return{records:Q,changed:Z}}async cleanupPreparedPlugins(O){await Promise.all(O.map(($)=>F.rm($.materialized.stagingPath,{recursive:!0,force:!0})))}async resolvePluginSource(O,$,Q){let Z=O.trim();if(!Z)throw new H("INVALID_SOURCE","Plugin source is required");let J=w$(Z);if(J){if(!$.marketplaces[J.marketplace])throw new H("MARKETPLACE_NOT_FOUND",`Marketplace "${J.marketplace}" is not configured`);return{source:{type:"marketplace",marketplace:J.marketplace},recordSource:{type:"marketplace",marketplace:J.marketplace},expectedName:J.pluginName}}if(!o0(Z)&&!this.looksLikeGitSource(Z)){let q=[];for(let W of await this.catalogsFromState($))if(W.manifest.plugins.some((G)=>G.name===Z))q.push({pluginName:Z,marketplace:W.marketplace.name});if(q.length===1)return{source:{type:"marketplace",marketplace:q[0].marketplace},recordSource:{type:"marketplace",marketplace:q[0].marketplace},expectedName:Z};if(q.length>1)throw new H("AMBIGUOUS_PLUGIN_SOURCE",`Plugin "${Z}" exists in multiple marketplaces; use name@marketplace`)}if(o0(Z)){let W={type:"local",path:await this.resolveLocalSource(Z,Q.workspaceRoot)};return{source:W,recordSource:W}}let K=this.normalizeGitSource(Z,Q.ref);return{source:K,recordSource:K}}async materializePluginSource(O,$,Q,Z){if(O.type!=="marketplace")return this.materializeSource(O);let J=$.marketplaces[O.marketplace];if(!J)throw new H("MARKETPLACE_NOT_FOUND",`Marketplace "${O.marketplace}" is not configured`);let K=await this.readMarketplaceManifest(J.installPath),q=Q?K.plugins.filter((W)=>W.name===Q):K.plugins;if(q.length!==1)throw new H("MARKETPLACE_PLUGIN_NOT_FOUND",Q?`Plugin "${Q}" was not found in marketplace "${O.marketplace}"`:`Marketplace "${O.marketplace}" requires an explicit plugin name`);return this.materializeMarketplaceEntry(J,q[0],Z)}async materializeMarketplaceEntry(O,$,Q){if(typeof $.source!=="string"){let q=this.normalizeGitSource($.source.url,$.source.sha??$.source.ref);return l(Q,q,`Plugin "${$.name}"`),this.materializeSource(q)}if($.source.startsWith("https://")||$.source.startsWith("ssh://")||$.source.startsWith("git@")){let q=this.normalizeGitSource($.source);return l(Q,q,`Plugin "${$.name}"`),this.materializeSource(q)}let Z=await F.realpath(O.installPath),J=j.resolve(Z,$.source);if(!$0(Z,J)||J===Z)throw new H("MARKETPLACE_PATH_ESCAPE",`Plugin "${$.name}" source escapes its marketplace`);let K=await F.realpath(J);if(!$0(Z,K))throw new H("MARKETPLACE_PATH_ESCAPE",`Plugin "${$.name}" source escapes its marketplace`);return this.materializeSource({type:"local",path:K})}async normalizeMarketplaceSource(O,$){let Q=O.trim();if(!Q)throw new H("INVALID_SOURCE","Marketplace source is required");if(o0(Q))return{type:"local",path:await this.resolveLocalSource(Q,$.workspaceRoot)};return this.normalizeGitSource(Q,$.ref)}normalizeGitSource(O,$){let Q=O;if(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(O))Q=`https://github.com/${O}.git`;else if(O.startsWith("git@")){if(!/^git@[A-Za-z0-9.-]+:[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+(?:\.git)?$/.test(O))throw new H("INVALID_SOURCE","Invalid SSH Git source")}else{let Z;try{Z=new URL(O)}catch{throw new H("INVALID_SOURCE","Invalid Git source")}if(Z.protocol!=="https:"&&Z.protocol!=="ssh:")throw new H("UNSAFE_GIT_PROTOCOL","Git sources must use HTTPS or SSH");if(Z.password||Z.protocol==="https:"&&Z.username)throw new H("GIT_CREDENTIALS_IN_URL","Git credentials must not be embedded in plugin source URLs");if(Z.hash||Z.search)throw new H("INVALID_SOURCE","Use the ref option instead of URL query or fragment parameters");Q=Z.toString()}if($&&(!$.trim()||$.startsWith("-")||$.includes("\x00")))throw new H("INVALID_GIT_REF","Invalid Git ref");return{type:"git",url:Q,...$?{ref:$}:{}}}looksLikeGitSource(O){return O.startsWith("https://")||O.startsWith("ssh://")||O.startsWith("git@")||/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(O)}async resolveLocalSource(O,$){let Q=O==="~"?n0():O.startsWith("~/")?j.join(n0(),O.slice(2)):O,Z=j.resolve($??process.cwd(),Q),J;try{J=await F.realpath(Z)}catch{throw new H("LOCAL_SOURCE_NOT_FOUND",`Local source does not exist: ${O}`)}let K=await F.lstat(J);if(!K.isDirectory()||K.isSymbolicLink())throw new H("INVALID_LOCAL_SOURCE","Local plugin sources must be regular directories");return J}async materializeSource(O){await this.ensureStoreDirectory();let $=j.join(this.stateRoot,"staging",e1());if(await F.mkdir(j.dirname($),{recursive:!0,mode:448}),O.type==="git"){await this.cloneGitSource(O,$);let Z=await this.runGit(["rev-parse","HEAD"],$);if(O.ref&&ZO.test(O.ref)&&Z.toLowerCase()!==O.ref.toLowerCase())throw await F.rm($,{recursive:!0,force:!0}),new H("GIT_PIN_MISMATCH","Plugin checkout does not match the requested Git commit SHA");await F.rm(j.join($,".git"),{recursive:!0,force:!0});let J=await this.digestTree($);return{stagingPath:$,revision:Z,contentDigest:J}}await this.copyLocalSource(O.path,$);let Q=await this.digestTree($);return{stagingPath:$,revision:`local-${Q.slice(0,40)}`,contentDigest:Q}}async cloneGitSource(O,$){try{if(O.ref&&ZO.test(O.ref))await F.mkdir($,{recursive:!0,mode:448}),await this.runGit(["init"],$),await this.runGit(["remote","add","origin",O.url],$),await this.runGit(["fetch","--depth","1","origin",O.ref],$),await this.runGit(["checkout","--detach","FETCH_HEAD"],$);else{let Q=["clone","--depth","1","--no-tags"];if(O.ref)Q.push("--branch",O.ref);Q.push("--",O.url,$),await this.runGit(Q)}}catch(Q){throw await F.rm($,{recursive:!0,force:!0}),new H("GIT_CLONE_FAILED",`Failed to clone plugin source: ${this.sanitizeError(Q)}`)}}async runGit(O,$){let Q=await M$("git",O,{cwd:$,encoding:"utf8",timeout:b$,maxBuffer:4194304,env:{...process.env,GIT_TERMINAL_PROMPT:"0"}}),Z=typeof Q==="string"?Q:Q.stdout;if(Z===void 0)throw Error("Git process returned an invalid result");return String(Z).trim()}sanitizeError(O){return(O instanceof Error?O.message:String(O)).replaceAll(this.stateRoot,"<plugin-store>").slice(0,500)}async copyLocalSource(O,$){await this.digestTree(O),await F.cp(O,$,{recursive:!0,force:!1,errorOnExist:!0,filter:(Q)=>{return!j.relative(O,Q).split(j.sep).includes(".git")}})}async digestTree(O){let $=[],Q=0,Z=async(K)=>{let q=await F.readdir(K,{withFileTypes:!0});q.sort((W,G)=>W.name.localeCompare(G.name));for(let W of q){if(W.name===".git")continue;let G=j.join(K,W.name),Y=j.relative(O,G),X=await F.lstat(G);if(X.isSymbolicLink())throw new H("PACKAGE_SYMLINK_FORBIDDEN",`Plugin packages may not contain symbolic links: ${Y}`);if(X.isDirectory()){await Z(G);continue}if(!X.isFile())throw new H("PACKAGE_ENTRY_FORBIDDEN",`Plugin packages may contain only files and directories: ${Y}`);if(Q+=X.size,$.push({relative:Y,absolute:G,executable:(X.mode&73)!==0}),$.length>$O||Q>QO)throw new H("PACKAGE_TOO_LARGE",`Plugin package exceeds ${$O} files or ${QO} bytes`)}};await Z(O);let J=j$("sha256");for(let K of $)J.update(K.relative),J.update("\x00"),J.update(K.executable?"x":"-"),J.update("\x00"),J.update(await F.readFile(K.absolute)),J.update("\x00");return J.digest("hex")}async publishPackage(O,$,Q){let Z=j.join(this.stateRoot,O,$,Q.contentDigest);await F.mkdir(j.dirname(Z),{recursive:!0,mode:448});try{let J=await F.lstat(Z);if(!J.isDirectory()||J.isSymbolicLink())throw new H("PACKAGE_STORE_CONFLICT","Plugin package destination is not a regular directory");return await F.rm(Q.stagingPath,{recursive:!0,force:!0}),Z}catch(J){if(!s(J))throw J}return await F.rename(Q.stagingPath,Z),Z}async readMarketplaceManifest(O){for(let $ of T$){let Q=j.join(O,$);try{let Z=await F.lstat(Q);if(!Z.isFile()||Z.isSymbolicLink()||Z.size>OO)throw new H("INVALID_MARKETPLACE","Marketplace manifest must be a regular bounded file");let J=JSON.parse(await F.readFile(Q,"utf8")),K=o1(J);if(!K.success)throw new H("INVALID_MARKETPLACE",`Invalid marketplace manifest: ${K.error.issues.map((W)=>`${W.path.join(".")}: ${W.message}`).join("; ")}`);let q=new Set;for(let W of K.data.plugins){if(q.has(W.name))throw new H("INVALID_MARKETPLACE",`Marketplace contains duplicate plugin: ${W.name}`);q.add(W.name)}return K.data}catch(Z){if(s(Z))continue;if(Z instanceof SyntaxError)throw new H("INVALID_MARKETPLACE","Marketplace manifest contains invalid JSON");throw Z}}throw new H("INVALID_MARKETPLACE","Marketplace manifest was not found")}async catalogsFromState(O){let $=Object.values(O.marketplaces).sort((Q,Z)=>Q.name.localeCompare(Z.name));return Promise.all($.map(async(Q)=>({marketplace:Q,manifest:await this.readMarketplaceManifest(Q.installPath)})))}async readState(){let O;try{O=await F.open(this.statePath,O0.O_RDONLY|O0.O_NOFOLLOW)}catch($){if(s($))return _$();throw new H("PLUGIN_STATE_INVALID","Plugin package state must be a regular file")}try{let $=await O.stat();if(!$.isFile()||$.size>OO)throw new H("PLUGIN_STATE_INVALID","Plugin package state is invalid");if(process.getuid&&$.uid!==process.getuid())throw new H("PLUGIN_STATE_INVALID","Plugin package state must be owned by the current user");if(($.mode&511)!==384)throw new H("PLUGIN_STATE_INVALID","Plugin package state permissions must be 0600");let Q=JSON.parse(await O.readFile("utf8")),Z=i1(Q);if(!Z.success)throw new H("PLUGIN_STATE_INVALID","Plugin package state schema is invalid");let J=Z.data;for(let[K,q]of Object.entries(J.installed)){let W=j.join(this.stateRoot,"packages",K);if(K!==q.name||!j.isAbsolute(q.installPath)||!$0(W,q.installPath)||j.basename(q.installPath)!==q.contentDigest||q.source.type==="local"&&!j.isAbsolute(q.source.path))throw new H("PLUGIN_STATE_INVALID","Plugin package state contains an invalid installation");if(q.source.type==="git"){let G=this.normalizeGitSource(q.source.url,q.source.ref);if(G.url!==q.source.url||G.ref!==q.source.ref)throw new H("PLUGIN_STATE_INVALID","Plugin package state contains an invalid Git source")}}for(let[K,q]of Object.entries(J.marketplaces)){let W=j.join(this.stateRoot,"marketplaces",K);if(K!==q.name||!j.isAbsolute(q.installPath)||!$0(W,q.installPath)||j.basename(q.installPath)!==q.contentDigest||q.source.type==="local"&&!j.isAbsolute(q.source.path))throw new H("PLUGIN_STATE_INVALID","Plugin package state contains an invalid marketplace");if(q.source.type==="git"){let G=this.normalizeGitSource(q.source.url,q.source.ref);if(G.url!==q.source.url||G.ref!==q.source.ref)throw new H("PLUGIN_STATE_INVALID","Plugin package state contains an invalid Marketplace Git source")}}for(let K of Object.values(J.installed))if(K.source.type==="marketplace"&&!J.marketplaces[K.source.marketplace])throw new H("PLUGIN_STATE_INVALID","Plugin package state references a missing marketplace");return J}catch($){if($ instanceof SyntaxError)throw new H("PLUGIN_STATE_INVALID","Plugin package state contains invalid JSON");throw $}finally{await O.close()}}async writeState(O){await this.ensureStoreDirectory(),await z$(this.statePath,`${JSON.stringify(O,null,2)}
723
- `,{mode:384,encoding:"utf8"}),await F.chmod(this.statePath,384)}async ensureStoreDirectory(){try{let O=await F.lstat(this.stateRoot);if(!O.isDirectory()||O.isSymbolicLink())throw new H("PLUGIN_STORE_INVALID","Plugin package store must be a regular directory");if(process.getuid&&O.uid!==process.getuid())throw new H("PLUGIN_STORE_INVALID","Plugin package store must be owned by the current user");if((O.mode&511)!==448)throw new H("PLUGIN_STORE_INVALID","Plugin package store permissions must be 0700")}catch(O){if(!s(O))throw O;await F.mkdir(this.stateRoot,{recursive:!0,mode:448}),await F.chmod(this.stateRoot,448)}}}var a0=null;function r0(O,$){if(!a0)a0=new JO(O,$);return a0}import*as _ from"node:fs/promises";import{homedir as D$}from"node:os";import*as I from"node:path";import KO from"gray-matter";function z0(O,$){return`${O}:${$}`}function qO(O,$){return`${O}__${$}`}class M0{async loadPlugin(O,$,Q={}){let Z=await r(O);if(!Z)throw Error(`Not a valid plugin directory: ${O}`);let{manifest:J,source:K}=Z,q=J.name;S.debug(`Loading plugin "${q}" from ${O}`);let W=Q.skipCommands?[]:await this.loadCommands(O,q),G=Q.skipAgents?[]:await this.loadAgents(O,q),Y=Q.skipSkills?[]:await this.loadSkills(O,q),X=Q.skipHooks?void 0:await this.loadHooks(O),U=Q.skipMcp?void 0:await this.loadMcpConfig(O,q),B=Q.skipLsp?void 0:await this.loadLspConfig(O,q);return S.debug(`Plugin "${q}" loaded: ${W.length} commands, ${G.length} agents, ${Y.length} skills`),{manifest:J,basePath:O,source:$,manifestSource:K,commands:W,agents:G,skills:Y,hooks:X,mcpServers:U,lspServers:B,status:"active",loadedAt:new Date}}async loadCommands(O,$){let Q=I.join(O,"commands"),Z=[];if(!await this.dirExists(Q))return Z;let J=await this.scanMarkdownFiles(Q);for(let K of J)try{let q=await this.parseCommandFile(K,Q,$);if(q)Z.push(q)}catch(q){S.warn(`Failed to load command from ${K}: ${q instanceof Error?q.message:String(q)}`)}return Z}async parseCommandFile(O,$,Q){let Z=await _.readFile(O,"utf-8"),{data:J,content:K}=KO(Z),W=I.relative($,O).split(I.sep),G=W.pop();if(!G)return null;let Y=G.replace(/\.md$/i,""),X=Y;if(W.length>0)X=[...W,Y].join("/");let U=z0(Q,X),B=this.normalizeCommandConfig(J);return{originalName:X,namespacedName:U,pluginName:Q,config:B,content:K.trim(),path:O}}normalizeCommandConfig(O){return{description:this.asString(O.description),allowedTools:this.parseStringArray(O["allowed-tools"]),argumentHint:this.asString(O["argument-hint"]),model:this.asString(O.model),disableModelInvocation:O["disable-model-invocation"]===!0}}async loadAgents(O,$){let Q=I.join(O,"agents"),Z=[];if(!await this.dirExists(Q))return Z;let J=await this.scanMarkdownFiles(Q);for(let K of J)try{let q=await this.parseAgentFile(K,Q,$);if(q)Z.push(q)}catch(q){S.warn(`Failed to load agent from ${K}: ${q instanceof Error?q.message:String(q)}`)}return Z}async parseAgentFile(O,$,Q){let Z=await _.readFile(O,"utf-8"),{data:J,content:K}=KO(Z),q=I.relative($,O),W=I.basename(q,".md"),G=J.name||W,Y=z0(Q,G),X={name:Y,description:this.asString(J.description)||"",tools:this.parseStringArray(J.tools),color:this.asString(J.color),model:this.asString(J.model),permissionMode:this.asString(J.permissionMode),skills:this.parseStringArray(J.skills),systemPrompt:K.trim(),source:`plugin:${Q}`};return{originalName:G,namespacedName:Y,pluginName:Q,config:X,path:O}}async loadSkills(O,$){let Q=I.join(O,"skills"),Z=[];if(!await this.dirExists(Q))return Z;let J=await _.readdir(Q,{withFileTypes:!0});for(let K of J){if(!K.isDirectory())continue;let q=I.join(Q,K.name),W=I.join(q,"SKILL.md");try{let G=await V0(W,"project");if(G.success&&G.content){let Y=G.content.metadata.name,X=z0($,Y);Z.push({originalName:Y,namespacedName:X,pluginName:$,metadata:{...G.content.metadata,name:X},path:q})}}catch(G){S.warn(`Failed to load skill from ${W}: ${G instanceof Error?G.message:String(G)}`)}}return Z}async loadHooks(O){let $=I.join(O,"hooks","hooks.json");try{let Q=await _.readFile($,"utf-8"),Z=JSON.parse(Q);return Z.hooks||Z}catch{return}}async loadMcpConfig(O,$){let Q=I.join(O,".mcp.json");try{let Z=await _.readFile(Q,"utf-8"),J=JSON.parse(Z),K=n1(J);if(!K.success){S.warn(`Invalid .mcp.json in ${O}: ${K.error}`);return}let q="mcpServers"in J?J.mcpServers:J,W={};for(let[G,Y]of Object.entries(q)){let X=qO($,G);W[X]=Y}return W}catch{return}}async loadLspConfig(O,$){let Q=I.join(O,".lsp.json");try{let Z=JSON.parse(await _.readFile(Q,"utf8")),J=Z&&typeof Z==="object"&&!Array.isArray(Z)&&"lspServers"in Z?Z.lspServers:Z,K=GO(J),q={};for(let[W,G]of Object.entries(K)){let Y=(X)=>X.replaceAll("${CLAUDE_PLUGIN_ROOT}",O).replaceAll("${BLADE_PLUGIN_ROOT}",O);q[`plugin:${$}:${W}`]={...G,command:Y(G.command),args:G.args?.map(Y),env:G.env?Object.fromEntries(Object.entries(G.env).map(([X,U])=>[X,Y(U)])):void 0}}return q}catch(Z){if(Z.code!=="ENOENT")S.warn(`Invalid .lsp.json in ${O}: ${Z instanceof Error?Z.message:String(Z)}`);return}}async scanMarkdownFiles(O){let $=[],Q=async(Z)=>{let J=await _.readdir(Z,{withFileTypes:!0});for(let K of J){let q=I.join(Z,K.name);if(K.isDirectory())await Q(q);else if(K.name.endsWith(".md"))$.push(q)}};return await Q(O),$}async dirExists(O){try{return(await _.stat(O)).isDirectory()}catch{return!1}}asString(O){if(typeof O==="string"&&O.trim())return O.trim();return}parseStringArray(O){if(!O)return;if(Array.isArray(O))return O.map(($)=>String($).trim()).filter(Boolean);if(typeof O==="string")return O.split(",").map(($)=>$.trim()).filter(Boolean);return}static getPluginDirs(O){let $=D$();return[{path:I.join($,".claude","plugins"),source:"user",type:"claude"},{path:I.join($,".blade","plugins"),source:"user",type:"blade"},{path:I.join(O,".claude","plugins"),source:"project",type:"claude"},{path:I.join(O,".blade","plugins"),source:"project",type:"blade"}]}async discoverPluginsInDir(O,$){let Q=[],Z=[];try{await _.access(O)}catch{return{plugins:Q,errors:Z}}let J=await _.readdir(O,{withFileTypes:!0});for(let K of J){if(!K.isDirectory())continue;let q=I.join(O,K.name);try{let W=await this.loadPlugin(q,$);Q.push(W)}catch(W){Z.push({path:q,error:W instanceof Error?W.message:String(W)})}}return{plugins:Q,errors:Z}}}class D{static instances=new Map;plugins=new Map;loader=new M0;initialized=!1;workspaceRoot="";cliPluginDirs=[];enabledSettings={};sourcePolicy={...S0.pluginSourcePolicy};marketplaces={};constructor(O){this.workspaceRoot=O}static getInstance(O=M()){let $=e0.resolve(O),Q=D.instances.get($);if(!Q)Q=new D($),D.instances.set($,Q);return Q}static resetInstance(){D.instances.clear()}static releaseInstance(O,$){let Q=e0.resolve(O),Z=D.instances.get(Q);if(!Z||$&&Z!==$)return!1;return D.instances.delete(Q)}static getExistingInstance(O=M()){return D.instances.get(e0.resolve(O))}static getInitializedInstances(){return Array.from(D.instances.values()).filter((O)=>O.isInitialized())}async initialize(O,$=[]){this.workspaceRoot=O,this.cliPluginDirs=$,this.enabledSettings=await I0.getInstance().loadWorkspacePluginSettings(O),await this.refreshPolicyContext();let Q=[],Z=[];for(let G of $)try{let Y=await this.loader.loadPlugin(G,"cli");this.plugins.set(Y.manifest.name,Y),Q.push(Y),S.info(`Loaded CLI plugin: ${Y.manifest.name} from ${G}`)}catch(Y){Z.push({path:G,error:Y instanceof Error?Y.message:String(Y)}),S.warn(`Failed to load CLI plugin from ${G}: ${Y}`)}let J=(await N.getInstance().getStatus(O)).state==="trusted",K=M0.getPluginDirs(O).filter((G)=>G.source!=="project"||J),q=!1,W=async()=>{if(q)return;q=!0;let G=r0(),Y=await G.listInstallationRecords();for(let X of Y)try{await G.verifyInstallation(X);let U=await this.loader.loadPlugin(X.installPath,"user");if(U.manifest.name!==X.name)throw Error(`Managed plugin identity mismatch: ${X.name}`);U.installation=Object.freeze({...X});let B=this.plugins.get(U.manifest.name);if(!B||B.source==="user")this.plugins.set(U.manifest.name,U),Q.push(U)}catch(U){Z.push({path:X.installPath,code:"IO_ERROR",error:U instanceof Error?U.message:String(U)})}};for(let{path:G,source:Y}of K){if(Y==="project")await W();let X=await this.loader.discoverPluginsInDir(G,Y);for(let U of X.plugins){let B=this.plugins.get(U.manifest.name);if(!B||B.source!=="cli")this.plugins.set(U.manifest.name,U),Q.push(U)}Z.push(...X.errors)}await W(),this.applyEnabledSettings();for(let G of this.plugins.values()){if(G.status!=="error")continue;Z.push({path:G.basePath,code:G.compatibilityIssues?.some((Y)=>Y.code==="source-policy")?"SOURCE_POLICY_BLOCKED":G.compatibilityIssues?.some((Y)=>Y.code==="blade-version")?"VERSION_INCOMPATIBLE":"DEPENDENCY_MISSING",error:G.error??"Plugin compatibility check failed"})}return this.initialized=!0,S.info(`Plugin system initialized: ${this.plugins.size} plugins loaded`+(Z.length>0?`, ${Z.length} errors`:"")),{plugins:Array.from(this.plugins.values()),errors:Z}}isInitialized(){return this.initialized}getWorkspaceRoot(){return this.workspaceRoot}getSourcePolicy(){return{...this.sourcePolicy,allowedGitHosts:[...this.sourcePolicy.allowedGitHosts],allowedMarketplaces:[...this.sourcePolicy.allowedMarketplaces],allowedLocalRoots:[...this.sourcePolicy.allowedLocalRoots]}}getAll(){return Array.from(this.plugins.values())}getActive(){return Array.from(this.plugins.values()).filter((O)=>O.status==="active")}get(O){return this.plugins.get(O)}has(O){return this.plugins.has(O)}async reapplyEnabledSettings(){this.enabledSettings=await I0.getInstance().loadWorkspacePluginSettings(this.workspaceRoot),await this.refreshPolicyContext(),this.applyEnabledSettings()}applyEnabledSettings(){for(let O of this.plugins.values()){if(O.compatibilityIssues=[],O.error=void 0,O.status=O.source==="cli"||this.enabledSettings[O.manifest.name]!==!1?"active":"inactive",O.status!=="active")continue;try{e(this.sourcePolicy,O.installation?.source??{type:"local",path:O.basePath},this.marketplaces,`Plugin "${O.manifest.name}"`)}catch($){if(!($ instanceof f))throw $;O.status="error",O.error=$.message,O.compatibilityIssues=[{code:"source-policy",message:$.message}]}}g1(Array.from(this.plugins.values()))}async refreshPolicyContext(){this.sourcePolicy=await I0.getInstance().loadWorkspacePluginSourcePolicy(this.workspaceRoot),this.marketplaces=Object.fromEntries((await r0().listMarketplaces()).map((O)=>[O.name,O]))}getBySource(){let O={cli:[],project:[],user:[]};for(let $ of this.plugins.values())O[$.source].push($);return O}getAllCommands(){let O=[];for(let $ of this.plugins.values())if($.status==="active")O.push(...$.commands);return O}getAllSkills(){let O=[];for(let $ of this.plugins.values())if($.status==="active")O.push(...$.skills);return O}getAllAgents(){let O=[];for(let $ of this.plugins.values())if($.status==="active")O.push(...$.agents);return O}findCommand(O){for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.commands)if(Z.namespacedName===O)return Z}let $=[];for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.commands)if(Z.originalName===O)$.push(Z)}if($.length===1)return $[0];return}findSkill(O){for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.skills)if(Z.namespacedName===O)return Z}let $=[];for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.skills)if(Z.originalName===O)$.push(Z)}if($.length===1)return $[0];return}findAgent(O){for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.agents)if(Z.namespacedName===O)return Z}let $=[];for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.agents)if(Z.originalName===O)$.push(Z)}if($.length===1)return $[0];return}hasCommandConflict(O){let $=0;for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.commands)if(Z.originalName===O){if($++,$>1)return!0}}return!1}getCommandProviders(O){let $=[];for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.commands)if(Z.originalName===O){$.push(Q.manifest.name);break}}return $}disable(O){let $=this.plugins.get(O);if($&&$.status==="active")return $.status="inactive",S.info(`Plugin "${O}" disabled`),!0;return!1}enable(O){let $=this.plugins.get(O);if($&&$.status==="inactive")return $.status="active",S.info(`Plugin "${O}" enabled`),!0;return!1}async refresh(){return S.info("Refreshing plugin list..."),this.plugins.clear(),this.initialized=!1,this.initialize(this.workspaceRoot,this.cliPluginDirs)}getStats(){let O=0,$=0,Q=0,Z=0,J=0;for(let K of this.plugins.values())if(K.status==="active")O++,Q+=K.commands.length,Z+=K.skills.length,J+=K.agents.length;else $++;return{total:this.plugins.size,active:O,inactive:$,commands:Q,skills:Z,agents:J}}formatPluginList(){if(this.getAll().length===0)return"没有已加载的插件。";let $=[],Q=this.getBySource();if(Q.cli.length>0){$.push("## CLI 指定的插件");for(let Z of Q.cli){let J=Z.status==="inactive"?" (禁用)":"";$.push(`- **${Z.manifest.name}** v${Z.manifest.version}${J}`),$.push(` ${Z.manifest.description}`)}$.push("")}if(Q.project.length>0){$.push("## 项目级插件");for(let Z of Q.project){let J=Z.status==="inactive"?" (禁用)":"";$.push(`- **${Z.manifest.name}** v${Z.manifest.version}${J}`),$.push(` ${Z.manifest.description}`)}$.push("")}if(Q.user.length>0){$.push("## 用户级插件");for(let Z of Q.user){let J=Z.status==="inactive"?" (禁用)":"";$.push(`- **${Z.manifest.name}** v${Z.manifest.version}${J}`),$.push(` ${Z.manifest.description}`)}}return $.join(`
724
- `)}}function Q0(O=M()){return D.getInstance(O)}var Z0=new Map,WO=Object.values(b0);function $1(O,$){let Q=LO.resolve(O),Z=Z0.get(Q);if(!Z||$&&Z.registry!==$)return!1;return J0.getInstance().loadConfig(Z.base,Q),Z0.delete(Q),!0}function O1(O){let $={...O};for(let Q of WO)$[Q]=(O[Q]??[]).map((Z)=>({...Z,matcher:Z.matcher?{...Z.matcher}:void 0,hooks:Z.hooks.map((J)=>({...J}))}));return $}class Q1{commandRegistry;hookManager;skillRegistry;subagentRegistry;workspaceRoot;constructor(O=M()){this.workspaceRoot=LO.resolve(O),this.commandRegistry=T.getInstance(this.workspaceRoot),this.hookManager=J0.getInstance(),this.skillRegistry=g({cwd:this.workspaceRoot}),this.subagentRegistry=o(this.workspaceRoot)}clearAllPluginResources(){this.commandRegistry.clearPluginCommands(),this.skillRegistry.clearPluginSkills(),this.subagentRegistry.clearPluginAgents(),$1(this.workspaceRoot,Q0(this.workspaceRoot)),S.debug("Cleared all plugin resources from subsystems")}async integrateAll(){let O=Q0(this.workspaceRoot),$=O.getActive(),Q=[],Z=[],J=0,K=0,q=0,W=0,G=0;for(let Y of $){let X=this.integratePlugin(Y);Q.push(X),J+=X.commandsRegistered,K+=X.skillsRegistered,q+=X.agentsRegistered,W+=X.mcpServersRegistered,G+=X.lspServersRegistered,Z.push(...X.errors)}if(this.integrateHooks($,O),J+K+q>0)S.info(`Plugin integration complete: ${J} commands, ${K} skills, ${q} agents, ${W} MCP servers, ${G} LSP servers`);return{plugins:Q,totalCommands:J,totalSkills:K,totalAgents:q,totalMcpServers:W,errors:Z}}integratePlugin(O){let $={pluginName:O.manifest.name,commandsRegistered:0,skillsRegistered:0,agentsRegistered:0,hooksRegistered:!1,mcpServersRegistered:0,lspServersRegistered:0,errors:[]};try{$.commandsRegistered=this.integrateCommands(O)}catch(Q){$.errors.push(`Failed to integrate commands: ${Q instanceof Error?Q.message:String(Q)}`)}try{$.skillsRegistered=this.integrateSkills(O)}catch(Q){$.errors.push(`Failed to integrate skills: ${Q instanceof Error?Q.message:String(Q)}`)}try{$.agentsRegistered=this.integrateAgents(O)}catch(Q){$.errors.push(`Failed to integrate agents: ${Q instanceof Error?Q.message:String(Q)}`)}$.hooksRegistered=O.hooks!==void 0;try{$.mcpServersRegistered=this.integrateMcp(O)}catch(Q){$.errors.push(`Failed to integrate MCP servers: ${Q instanceof Error?Q.message:String(Q)}`)}return $.lspServersRegistered=Object.keys(O.lspServers??{}).length,S.debug(`Integrated plugin "${O.manifest.name}": ${$.commandsRegistered} commands, ${$.skillsRegistered} skills, ${$.agentsRegistered} agents`),$}integrateCommands(O){let $=0;for(let Q of O.commands)this.commandRegistry.registerPluginCommand(Q),$++;return $}integrateSkills(O){let $=0;for(let Q of O.skills)this.skillRegistry.registerPluginSkill(Q),$++;return $}integrateAgents(O){let $=0;for(let Q of O.agents)this.subagentRegistry.register({...Q.config,name:Q.namespacedName}),$++;return $}integrateHooks(O,$){let Q=O.filter((q)=>q.hooks);if(Q.length===0){$1(this.workspaceRoot,$);return}let Z=O1(this.hookManager.getConfig(this.workspaceRoot));if(!Z0.has(this.workspaceRoot))Z0.set(this.workspaceRoot,{base:O1(Z),registry:$});let J=Z0.get(this.workspaceRoot)?.base??Z,K=O1(J);K.enabled=!0;for(let q of WO){let W=J.enabled?[...J[q]??[]]:[],G=[];for(let Y of Q)for(let X of Y.hooks?.[q]??[])G.push({...X,name:X.name?`plugin:${Y.manifest.name}:${X.name}`:`plugin:${Y.manifest.name}:${q}`,hooks:X.hooks.map((U)=>({...U,source:{kind:"plugin",pluginName:Y.manifest.name,pluginSource:Y.source,pluginRoot:Y.basePath}}))});K[q]=[...W,...G]}this.hookManager.loadConfig(K,this.workspaceRoot)}integrateMcp(O){return Object.keys(O.mcpServers??{}).length}}async function Z1(O=M()){return new Q1(O).integrateAll()}function A0(O=M()){new Q1(O).clearAllPluginResources()}function YO(O=M(),$){$1(O,$)}import{createHash as C$}from"node:crypto";import*as R from"node:fs/promises";import N$ from"node:os";import v from"node:path";import E$ from"gray-matter";var x0=32,XO=24576,HO=16384,FO=131072,T0=4,UO=80,VO=256,BO=/^[a-z0-9][a-z0-9._-]{0,63}$/,v$=k("Agent");function J1(O){for(let $ of O){let Q=$.codePointAt(0)??0;if(Q<=8||Q===11||Q===12||Q>=14&&Q<=31||Q===127||Q>=8203&&Q<=8207||Q>=8234&&Q<=8238||Q>=8288&&Q<=8303||Q===65279)return!0}return!1}function R$(O,$,Q){let Z=typeof O==="string"?O.trim():"",J=$.split(/\r?\n/).map((q)=>q.trim()).find(Boolean)?.replace(/^#+\s*/,"")??"",K=Z||J||Q;if(K.length>VO)throw Error(`Description exceeds ${VO} characters`);if(J1(K))throw Error("Description contains hidden control characters");return K}function y$(O,$){let Q=typeof O==="string"&&O.trim()?O.trim():$;if(Q.length>UO)throw Error(`Name exceeds ${UO} characters`);if(J1(Q))throw Error("Name contains hidden control characters");return Q}function f$(O){let Q=O.replace(/\.md$/i,"").split(v.sep);if(Q.length===0||Q.length>T0||Q.some((Z)=>!BO.test(Z)))throw Error(`Style path must use 1-${T0} lowercase safe segments`);return Q.join(":")}async function h$(O){let $;try{$=await R.lstat(O)}catch(K){if(K.code==="ENOENT")return[];throw K}if($.isSymbolicLink())throw Error(`Output style root cannot be a symlink: ${O}`);if(!$.isDirectory())return[];let Q=await R.realpath(O),Z=[],J=async(K,q)=>{if(q>T0)throw Error(`Output style directory exceeds depth ${T0}`);let W=await R.readdir(K,{withFileTypes:!0});W.sort((G,Y)=>G.name.localeCompare(Y.name));for(let G of W){let Y=v.join(K,G.name);if(G.isSymbolicLink())throw Error(`Output style path cannot be a symlink: ${Y}`);if(G.isDirectory()){await J(Y,q+1);continue}if(!G.isFile()||!G.name.toLowerCase().endsWith(".md"))continue;let X=await R.realpath(Y),U=v.relative(Q,X);if(!U||U.startsWith("..")||v.isAbsolute(U))throw Error(`Output style path escapes its source root: ${Y}`);if(Z.push(X),Z.length>x0)throw Error(`Output style catalog exceeds ${x0} files`)}};return await J(Q,1),Z}async function k$(O,$,Q){let Z=await R.lstat(Q);if(!Z.isFile()||Z.isSymbolicLink())throw Error("Output style must be a regular file");if(Z.size>XO)throw Error(`Output style exceeds ${XO} bytes`);let J=await R.readFile(Q,"utf8"),K=E$(J),q=K.content.trim(),W=Buffer.byteLength(q);if(W===0)throw Error("Output style prompt must not be empty");if(W>HO)throw Error(`Output style prompt exceeds ${HO} bytes`);if(J1(q))throw Error("Output style prompt contains hidden control characters");let G=v.relative($,Q),Y=f$(G);return{id:`${O.idPrefix}:${Y}`,name:y$(K.data.name,Y),description:R$(K.data.description,q,`Custom ${Y} communication style`),source:O.source,contentSha256:C$("sha256").update(q,"utf8").digest("hex"),prompt:q}}async function P$(O,$){let Q=await h$(O.directory);if(Q.length===0)return;let Z=await R.realpath(O.directory);for(let J of Q)try{let K=await k$(O,Z,J);$.set(K.id,K)}catch(K){v$.warn(`[CommunicationStyles] Ignoring ${O.source} style: ${K instanceof Error?K.message:String(K)}`)}}function m$(O,$,Q,Z){let J=[{directory:v.join(Z,".claude","output-styles"),source:"user",idPrefix:"user"},{directory:v.join(Z,".blade","output-styles"),source:"user",idPrefix:"user"}];if($)J.push({directory:v.join(O,".claude","output-styles"),source:"project",idPrefix:"project"},{directory:v.join(O,".blade","output-styles"),source:"project",idPrefix:"project"});for(let K of Q){if(K.status!=="active"||!BO.test(K.manifest.name))continue;J.push({directory:v.join(K.basePath,"output-styles"),source:"plugin",idPrefix:`plugin:${K.manifest.name}`})}return J}async function q1(O,$){let Q=new Map;for(let J of m$(v.resolve(O),$.projectTrusted,$.plugins??[],$.homeDirectory??N$.homedir()))await P$(J,Q);let Z=0;for(let J of Q.values())Z+=Buffer.byteLength(J.prompt??"");if(Q.size>x0)throw Error(`Output style catalog exceeds ${x0} styles`);if(Z>FO)throw Error(`Output style catalog exceeds ${FO} bytes`);return new jO([...Q.values()])}import{createHash as d$}from"node:crypto";import{existsSync as _0,realpathSync as p$}from"node:fs";import*as d from"node:fs/promises";import z from"node:path";import g$ from"fast-glob";import u$ from"gray-matter";import xO from"picomatch";var SO=128,zO=32768,MO=262144,c$=49152,l$=32768,s$=24,IO=16,n$=256,i$=k("Agent"),o$=["**/CLAUDE.md","**/.claude/CLAUDE.md","**/CLAUDE.local.md","**/AGENTS.md","**/AGENTS.override.md","**/BLADE.md","**/.claude/rules/**/*.md","**/.blade/rules/**/*.md"],a$=["**/.git/**","**/node_modules/**","**/.venv/**","**/dist/**","**/build/**","**/coverage/**","**/target/**"];function w0(O){return d$("sha256").update(O,"utf8").digest("hex")}function TO(O){for(let $ of O){let Q=$.codePointAt(0)??0;if(Q<=8||Q===11||Q===12||Q>=14&&Q<=31||Q===127||Q>=8203&&Q<=8207||Q>=8234&&Q<=8238||Q>=8288&&Q<=8303||Q===65279)return!0}return!1}function W1(O){return O.split(z.sep).join("/")}function K1(O){let $=z.resolve(O),Q=[];while(!0)try{return z.join(p$($),...Q.reverse())}catch(Z){if(Z.code!=="ENOENT")return z.resolve(O);let J=z.dirname($);if(J===$)return z.resolve(O);Q.push(z.basename($)),$=J}}function t$(O){let $=z.resolve(O),Q;while(!0){if(_0(z.join($,".git")))return $;if(!Q&&(_0(z.join($,".blade"))||_0(z.join($,".claude"))||_0(z.join($,"package.json"))))Q=$;let Z=z.dirname($);if(Z===$)return Q??z.resolve(O);$=Z}}function Y1(O){return Boolean(O)&&O!==".."&&!O.startsWith("../")}function G1(O,$){return O===""||$===O||$.startsWith(`${O}/`)}function bO(O){return O.replaceAll("&","&amp;").replaceAll('"',"&quot;").replaceAll("<","&lt;").replaceAll(">","&gt;")}function r$(O){let $=typeof O==="string"?O.split(/[,\n]/u):Array.isArray(O)?O:[],Q=[...new Set($.filter((Z)=>typeof Z==="string").map((Z)=>Z.trim().replaceAll("\\","/")).filter(Boolean))];if(Q.length===0||Q.every((Z)=>Z==="**"))return;if(Q.length>IO)throw Error(`paths exceeds ${IO} patterns`);for(let Z of Q){if(Z.length>n$||z.posix.isAbsolute(Z)||Z.split("/").includes("..")||TO(Z))throw Error(`Unsafe project rule path pattern: ${Z.slice(0,80)}`);xO(Z,{dot:!0})}return Q}function e$(O){if(O.endsWith("/CLAUDE.local.md")||O==="CLAUDE.local.md")return{source:"local",kind:"instruction",scopeDirectory:z.posix.dirname(O).replace(/^\.$/u,""),priority:90};for(let Z of[".claude/rules/",".blade/rules/"]){let J=O.indexOf(Z);if(J>=0)return{source:"project",kind:"rule",scopeDirectory:O.slice(0,J).replace(/\/$/u,""),priority:Z.startsWith(".blade")?80:70}}if(O.endsWith("/.claude/CLAUDE.md")||O===".claude/CLAUDE.md")return{source:"project",kind:"instruction",scopeDirectory:O.slice(0,-17).replace(/\/$/u,""),priority:30};let $=z.posix.basename(O),Q=$==="CLAUDE.md"?20:$==="AGENTS.md"?40:$==="AGENTS.override.md"?50:60;return{source:"project",kind:"instruction",scopeDirectory:z.posix.dirname(O).replace(/^\.$/u,""),priority:Q}}function L1(O,$){let Q=O.scopeDirectory?O.scopeDirectory.split("/").length:0,Z=$.scopeDirectory?$.scopeDirectory.split("/").length:0;return Q-Z||O.priority-$.priority||O.relativePath.localeCompare($.relativePath)}function O4(O){return{id:O.id,relativePath:O.relativePath,source:O.source,contentSha256:O.contentSha256}}function q0(O,$,Q){let Z=O.map((q)=>{let W=q.conditional?' conditional="true"':"";return`<instruction-file path="${bO(q.relativePath)}" source="${q.source}" sha256="${q.contentSha256}"${W}>
721
+ (${K} of ${Q} commands shown due to character budget)`;return{text:Z,includedCount:K,totalCount:Q}}snapshot(){let O=new x;return O.workspaceRoot=this.workspaceRoot,O.commands=new Map(Array.from(this.commands,([$,Q])=>[$,{...Q,config:{...Q.config,...Q.config.allowedTools?{allowedTools:[...Q.config.allowedTools]}:{}}}])),O.pluginCommands=new Map(Array.from(this.pluginCommands,([$,Q])=>[$,{...Q,config:{...Q.config,...Q.config.allowedTools?{allowedTools:[...Q.config.allowedTools]}:{}}}])),O.initialized=this.initialized,O.lastDiscoveryResult=this.lastDiscoveryResult?{commands:Array.from(O.commands.values()),scannedDirs:[...this.lastDiscoveryResult.scannedDirs],errors:this.lastDiscoveryResult.errors.map(($)=>({...$}))}:null,O}registerPluginCommand(O){this.pluginCommands.set(O.namespacedName,O)}findPluginCommand(O){let $=this.pluginCommands.get(O);if($)return $;let Q=[];for(let Z of this.pluginCommands.values())if(Z.originalName===O)Q.push(Z);if(Q.length===1)return Q[0];return}hasPluginCommand(O){return this.findPluginCommand(O)!==void 0}getAllPluginCommands(){return Array.from(this.pluginCommands.values())}async executePluginCommand(O,$){let Q=this.findPluginCommand(O);if(!Q)return null;let Z={name:Q.namespacedName,config:Q.config,content:Q.content,path:Q.path,source:"project",sourceDir:"blade"};return this.executor.execute(Z,$)}clearPluginCommands(){this.pluginCommands.clear()}getPluginCommandCount(){return this.pluginCommands.size}hasPluginCommandConflict(O){let $=0;for(let Q of this.pluginCommands.values())if(Q.originalName===O){if($++,$>1)return!0}return!1}getPluginCommandProviders(O){let $=[];for(let Q of this.pluginCommands.values())if(Q.originalName===O)$.push(Q.pluginName);return $}}import O1 from"node:path";import{satisfies as u0,validRange as d1}from"semver";var O$=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function l0(O){if(O.bladeVersion!==void 0&&(!O.bladeVersion.trim()||!d1(O.bladeVersion)))throw Error(`Invalid Blade version range in plugin "${O.name}": ${O.bladeVersion}`);for(let[$,Q]of Object.entries(O.dependencies??{})){if(!O$.test($))throw Error(`Invalid dependency name in plugin "${O.name}": ${$}`);if($===O.name)throw Error(`Plugin "${O.name}" cannot depend on itself`);if(!Q.trim()||!d1(Q))throw Error(`Invalid dependency range for ${$} in plugin "${O.name}": ${Q}`)}}function g1(O,$=c0()){if(l0(O),O.bladeVersion&&!u0($,O.bladeVersion))throw Error(`Plugin "${O.name}" requires Blade ${O.bladeVersion}, current ${$}`)}function p1(O,$){O.status="error",O.compatibilityIssues=[...O.compatibilityIssues??[],$],O.error=O.compatibilityIssues.map((Q)=>Q.message).join("; ")}function u1(O,$=c0()){let Q=[],Z=new Map(O.map((K)=>[K.manifest.name,K]));for(let K of O){if(K.status!=="active")continue;if(K.manifest.bladeVersion&&!u0($,K.manifest.bladeVersion)){let q={code:"blade-version",expected:K.manifest.bladeVersion,actual:$,message:`Requires Blade ${K.manifest.bladeVersion}, current ${$}`};p1(K,q),Q.push(q)}}let J=!0;while(J){J=!1;for(let K of O){if(K.status!=="active")continue;for(let[q,W]of Object.entries(K.manifest.dependencies??{})){let G=Z.get(q),Y;if(!G)Y={code:"dependency-missing",dependency:q,expected:W,message:`Missing dependency ${q}@${W}`};else if(!u0(G.manifest.version,W))Y={code:"dependency-version",dependency:q,expected:W,actual:G.manifest.version,message:`Dependency ${q} requires ${W}, found ${G.manifest.version}`};else if(G.status!=="active")Y={code:"dependency-inactive",dependency:q,expected:W,actual:G.status,message:`Dependency ${q} is ${G.status}`};if(!Y)continue;p1(K,Y),Q.push(Y),J=!0;break}}}return Q}import{execFile as j$}from"node:child_process";import{createHash as B$,randomUUID as OO}from"node:crypto";import{constants as O0,promises as F}from"node:fs";import{homedir as i0}from"node:os";import j from"node:path";import{promisify as S$}from"node:util";import{Mutex as z$}from"async-mutex";import{satisfies as o0}from"semver";import M$ from"write-file-atomic";import*as S0 from"node:fs/promises";import*as t1 from"node:path";var c=L.String({minLength:2,maxLength:64,pattern:"^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]{1,2}$"}),s0=L.String({pattern:"^\\d+\\.\\d+\\.\\d+(-[\\w.]+)?(\\+[\\w.]+)?$"}),$$=L.Object({name:L.String({minLength:1}),email:L.Optional(L.String({format:"email"})),url:L.Optional(L.String({format:"uri"}))}),s1=L.Object({name:c,description:L.String({minLength:1,maxLength:500}),version:s0,author:L.Optional($$),license:L.Optional(L.String()),repository:L.Optional(L.String({format:"uri"})),homepage:L.Optional(L.String({format:"uri"})),keywords:L.Optional(L.Array(L.String())),dependencies:L.Optional(L.Record(L.String(),L.String())),bladeVersion:L.Optional(L.String())}),Q$=L.Union([L.Object({type:L.Literal("git"),url:L.String({minLength:1}),ref:L.Optional(L.String({minLength:1}))},{additionalProperties:!1}),L.Object({type:L.Literal("local"),path:L.String({minLength:1})},{additionalProperties:!1}),L.Object({type:L.Literal("marketplace"),marketplace:c},{additionalProperties:!1})]),Z$=L.Object({name:c,source:Q$,installPath:L.String({minLength:1}),version:s0,revision:L.String({minLength:1,maxLength:128}),contentDigest:L.String({pattern:"^[a-f0-9]{64}$"}),installedAt:L.String({format:"date-time"}),updatedAt:L.String({format:"date-time"})},{additionalProperties:!1}),J$=L.Union([L.Object({type:L.Literal("git"),url:L.String({minLength:1}),ref:L.Optional(L.String({minLength:1}))},{additionalProperties:!1}),L.Object({type:L.Literal("local"),path:L.String({minLength:1})},{additionalProperties:!1})]),q$=L.Object({name:c,source:J$,installPath:L.String({minLength:1}),revision:L.String({minLength:1,maxLength:128}),contentDigest:L.String({pattern:"^[a-f0-9]{64}$"}),addedAt:L.String({format:"date-time"}),updatedAt:L.String({format:"date-time"})},{additionalProperties:!1}),K$=L.Object({version:L.Literal(1),installed:L.Record(L.String(),Z$),marketplaces:L.Record(L.String(),q$)},{additionalProperties:!1}),n1=L.Object({name:L.String({minLength:1}),email:L.Optional(L.String({format:"email"})),url:L.Optional(L.String({format:"uri"}))}),G$=L.Object({name:c,description:L.Optional(L.String({maxLength:500})),version:L.Optional(s0),author:L.Optional(L.Union([L.String({minLength:1}),n1])),source:L.Union([L.String({minLength:1}),L.Object({source:L.Literal("url"),url:L.String({minLength:1}),ref:L.Optional(L.String({minLength:1})),sha:L.Optional(L.String({pattern:"^[a-fA-F0-9]{40}$"}))})]),category:L.Optional(L.String()),homepage:L.Optional(L.String({format:"uri"})),tags:L.Optional(L.Array(L.String()))}),L$=L.Object({name:c,description:L.Optional(L.String({maxLength:500})),owner:L.Optional(n1),metadata:L.Optional(L.Object({description:L.Optional(L.String({maxLength:500})),version:L.Optional(L.String())})),plugins:L.Array(G$,{maxItems:5000})}),c1=L.Object({type:l1(["stdio","sse","http"]),command:L.Optional(L.String()),args:L.Optional(L.Array(L.String())),env:L.Optional(L.Record(L.String(),L.String())),cwd:L.Optional(L.String()),url:L.Optional(L.String({format:"uri"})),headers:L.Optional(L.Record(L.String(),L.String())),timeout:L.Optional(L.Integer({minimum:1000,maximum:1800000})),idleTimeout:L.Optional(L.Integer({minimum:1000,maximum:1800000})),sampling:L.Optional(L.Object({enabled:L.Boolean(),maxTokens:L.Optional(L.Integer({minimum:1,maximum:4096})),maxRequestsPerToolCall:L.Optional(L.Integer({minimum:1,maximum:8})),maxInputBytes:L.Optional(L.Integer({minimum:1,maximum:1048576}))})),oauth:L.Optional(L.Object({enabled:L.Optional(L.Boolean()),clientId:L.Optional(L.String({minLength:1,maxLength:4096})),scopes:L.Optional(L.Array(L.String({minLength:1,maxLength:128}),{maxItems:32})),callbackPort:L.Optional(L.Integer({minimum:1024,maximum:65535}))},{additionalProperties:!1})),healthCheck:L.Optional(L.Object({enabled:L.Optional(L.Boolean()),interval:L.Optional(L.Number({exclusiveMinimum:0})),timeout:L.Optional(L.Number({exclusiveMinimum:0})),failureThreshold:L.Optional(L.Number({exclusiveMinimum:0}))}))}),W$=L.Union([L.Object({mcpServers:L.Record(L.String(),c1)}),L.Record(L.String(),c1)]);function i1(O){return u(W$,O)}function o1(O){return u(K$,O)}function a1(O){return u(L$,O)}var Y$=[{dir:".blade-plugin",source:"blade"},{dir:".claude-plugin",source:"claude"}];async function r(O){for(let{dir:$,source:Q}of Y$){let Z=t1.join(O,$,"plugin.json");try{await S0.access(Z)}catch{continue}try{let J=await S0.readFile(Z,"utf-8"),K=JSON.parse(J),q=u(s1,K);if(!q.success){let W=q.error.issues.map((G)=>`${G.path.join(".")}: ${G.message}`).join("; ");throw Error(`Invalid plugin.json: ${W}`)}return l0(q.data),S.debug(`Parsed plugin manifest from ${Z}`),{manifest:q.data,source:Q,manifestPath:Z}}catch(J){if(J instanceof SyntaxError)throw Error(`Invalid JSON in ${Z}: ${J.message}`);throw J}}return null}import{realpathSync as X$}from"node:fs";import n0 from"node:path";var H$=/^[a-fA-F0-9]{40}$/;class f extends Error{code;constructor(O,$){super($);this.code=O;this.name="PluginSourcePolicyError"}}function F$(O,$){let Q=(J)=>{try{return X$.native(J)}catch{return n0.resolve(J)}},Z=n0.relative(Q(O),Q($));return Z===""||!Z.startsWith("..")&&!n0.isAbsolute(Z)}function U$(O){let $=O.match(/^[^@]+@([^:]+):/);if($?.[1])return $[1].toLowerCase();try{return new URL(O).hostname.toLowerCase()}catch{return}}function V$(O,$){if(!$.startsWith("*."))return O===$;let Q=$.slice(1);return O.endsWith(Q)&&O.length>Q.length}function r1(O,$,Q){if(O.requireGitCommitSha&&(!$.ref||!H$.test($.ref)))throw new f("PLUGIN_GIT_SHA_REQUIRED",`${Q} must pin a full 40-character Git commit SHA`);if(!O.restrictToAllowedSources)return;let Z=U$($.url);if(!Z||!O.allowedGitHosts.some((J)=>V$(Z,J)))throw new f("PLUGIN_SOURCE_BLOCKED",`${Q} Git host is not allowed by plugin source policy`)}function e1(O,$,Q){if(!O.restrictToAllowedSources)return;if(!O.allowedLocalRoots.some((Z)=>F$(Z,$)))throw new f("PLUGIN_SOURCE_BLOCKED",`${Q} local path is not allowed by plugin source policy`)}function l(O,$,Q="Marketplace"){if($.type==="git")r1(O,$,Q);else e1(O,$.path,Q)}function e(O,$,Q,Z="Plugin"){if($.type==="git"){r1(O,$,Z);return}if($.type==="local"){e1(O,$.path,Z);return}if(O.restrictToAllowedSources&&!O.allowedMarketplaces.includes($.marketplace))throw new f("PLUGIN_SOURCE_BLOCKED",`Marketplace "${$.marketplace}" is not allowed by plugin source policy`);let J=Q[$.marketplace];if(!J)throw new f("MARKETPLACE_NOT_FOUND",`Marketplace "${$.marketplace}" is not configured`);l(O,J.source,`Marketplace "${$.marketplace}"`)}var I$=S$(j$),b$=1,$O=2097152,QO=1e4,ZO=104857600,A$=120000,x$=15000,T$=600000,r0=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/,JO=/^[a-fA-F0-9]{40}$/,_$=[j.join(".blade-plugin","marketplace.json"),j.join(".claude-plugin","marketplace.json"),"marketplace.json"];class H extends Error{code;constructor(O,$){super($);this.code=O;this.name="PluginPackageError"}}function w$(){return{version:b$,installed:{},marketplaces:{}}}function s(O){return O.code==="ENOENT"}function n(O){if(O instanceof H||O instanceof f)return{code:O.code,message:O.message};return{code:"PLUGIN_PACKAGE_ERROR",message:O instanceof Error?O.message:String(O)}}function a0(O){return j.isAbsolute(O)||O.startsWith("./")||O.startsWith("../")||O==="~"||O.startsWith("~/")}function $0(O,$){let Q=j.relative(O,$);return Q===""||!Q.startsWith("..")&&!j.isAbsolute(Q)}function i(O,$="plugin"){if(!r0.test(O))throw new H("INVALID_PLUGIN_NAME",`Invalid ${$} name: ${O}`);return O}function D$(O){if(O.startsWith("git@"))return;let $=O.lastIndexOf("@");if($<=0||$===O.length-1)return;let Q=O.slice(0,$),Z=O.slice($+1);if(!r0.test(Q)||!r0.test(Z))return;return{pluginName:Q,marketplace:Z}}class KO{userPluginsDir;stateRoot;statePath;mutex=new z$;constructor(O,$){this.userPluginsDir=O??j.join(i0(),".blade","plugins"),this.stateRoot=$??j.join(j.dirname(this.userPluginsDir),"plugin-state"),this.statePath=j.join(this.stateRoot,"state.json")}async install(O,$={}){return this.runMutation(async()=>{let Q=[];try{this.requireSourceTrust($.trusted);let Z=await this.readState(),J=await this.resolvePluginSource(O,Z,$),K=this.effectivePolicy($.policy);if(e(K,J.recordSource,Z.marketplaces),J.expectedName&&Z.installed[J.expectedName])throw new H("PLUGIN_ALREADY_INSTALLED",`Plugin "${J.expectedName}" is already installed`);let q=await this.preparePluginClosure({state:Z,source:J.source,recordSource:J.recordSource,expectedName:J.expectedName,policy:K,updateRoot:!1});Q=q.prepared;let W=await this.commitPreparedPlugins(Z,Q),G=W.records.get(q.root.name);if(!G)throw new H("PLUGIN_PACKAGE_ERROR","Root plugin was not committed");let Y=Q.map((X)=>X.name).filter((X)=>X!==q.root.name);return S.info(`Installed managed plugin ${q.root.name} at revision ${G.revision}`),{success:!0,pluginName:q.root.name,pluginPath:G.installPath,manifest:q.root.manifest,installation:G,installedDependencies:Y,changed:W.changed.has(q.root.name)}}catch(Z){await this.cleanupPreparedPlugins(Q);let J=n(Z);return{success:!1,code:J.code,error:J.message}}})}async update(O,$={}){return this.runMutation(async()=>{let Q=[];try{this.requireSourceTrust($.trusted),i(O);let Z=await this.readState(),J=Z.installed[O];if(!J)throw new H("PLUGIN_NOT_MANAGED",`Plugin "${O}" is not managed by Blade's package store`);let K=this.effectivePolicy($.policy);e(K,J.source,Z.marketplaces);let q=await this.preparePluginClosure({state:Z,source:J.source,recordSource:J.source,expectedName:O,policy:K,updateRoot:!0});Q=q.prepared;let W=await this.commitPreparedPlugins(Z,Q),G=W.records.get(O);if(!G)throw new H("PLUGIN_PACKAGE_ERROR","Updated root plugin was not committed");let Y=Q.map((X)=>X.name).filter((X)=>X!==O&&W.changed.has(X));return S.info(`Updated managed plugin ${O} to revision ${G.revision}`),{success:!0,pluginName:O,pluginPath:G.installPath,manifest:q.root.manifest,installation:G,updatedDependencies:Y,changed:W.changed.has(O)}}catch(Z){await this.cleanupPreparedPlugins(Q);let J=n(Z);return{success:!1,pluginName:O,code:J.code,error:J.message}}})}async uninstall(O,$=!1){return this.runMutation(async()=>{try{if(i(O),!$)throw new H("CONFIRMATION_REQUIRED",`Uninstalling "${O}" requires explicit confirmation`);let Q=await this.readState(),Z=Q.installed[O];if(!Z)throw new H("PLUGIN_NOT_MANAGED",`Plugin "${O}" is not managed by Blade's package store`);return delete Q.installed[O],await this.writeState(Q),S.info(`Uninstalled managed plugin ${O}`),{success:!0,pluginName:O,installation:Z}}catch(Q){let Z=n(Q);return{success:!1,pluginName:O,code:Z.code,error:Z.message}}})}async listInstalled(){return Object.keys((await this.readState()).installed).sort()}async listInstallationRecords(){return Object.values((await this.readState()).installed).sort((O,$)=>O.name.localeCompare($.name))}async getInstallation(O){return(await this.readState()).installed[O]}async verifyInstallation(O){let $=await F.lstat(O.installPath);if(!$.isDirectory()||$.isSymbolicLink())throw new H("PLUGIN_PACKAGE_TAMPERED",`Managed plugin "${O.name}" has an invalid package path`);let Q=await F.realpath(this.stateRoot),Z=await F.realpath(O.installPath);if(!$0(Q,Z))throw new H("PLUGIN_PACKAGE_TAMPERED",`Managed plugin "${O.name}" has an invalid package path`);if(await this.digestTree(Z)!==O.contentDigest)throw new H("PLUGIN_PACKAGE_TAMPERED",`Managed plugin "${O.name}" failed content verification`);let K=await r(Z);if(!K||K.manifest.name!==O.name||K.manifest.version!==O.version)throw new H("PLUGIN_PACKAGE_TAMPERED",`Managed plugin "${O.name}" failed manifest verification`)}async addMarketplace(O,$={}){return this.runMutation(async()=>{let Q;try{let Z=await this.normalizeMarketplaceSource(O,$);l(this.effectivePolicy($.policy),Z);let J=await this.readState();Q=await this.materializeSource(Z);let K=await this.readMarketplaceManifest(Q.stagingPath),q=i(K.name,"marketplace");if(J.marketplaces[q])throw new H("MARKETPLACE_ALREADY_EXISTS",`Marketplace "${q}" is already configured`);let{revision:W,contentDigest:G}=Q,Y=await this.publishPackage("marketplaces",q,Q);Q=void 0;let X=new Date().toISOString(),U={name:q,source:Z,installPath:Y,revision:W,contentDigest:G,addedAt:X,updatedAt:X};return J.marketplaces[q]=U,await this.writeState(J),{success:!0,marketplace:U,manifest:K,changed:!0}}catch(Z){if(Q)await F.rm(Q.stagingPath,{recursive:!0,force:!0});let J=n(Z);return{success:!1,code:J.code,error:J.message}}})}async refreshMarketplace(O,$){return this.runMutation(async()=>{let Q;try{i(O,"marketplace");let Z=await this.readState(),J=Z.marketplaces[O];if(!J)throw new H("MARKETPLACE_NOT_FOUND",`Marketplace "${O}" is not configured`);l(this.effectivePolicy($),J.source,`Marketplace "${O}"`),Q=await this.materializeSource(J.source);let K=await this.readMarketplaceManifest(Q.stagingPath);if(K.name!==O)throw new H("MARKETPLACE_IDENTITY_MISMATCH",`Marketplace "${O}" now declares "${K.name}"`);if(J.revision===Q.revision&&J.contentDigest===Q.contentDigest)return await F.rm(Q.stagingPath,{recursive:!0,force:!0}),Q=void 0,{success:!0,marketplace:J,manifest:K,changed:!1};let{revision:q,contentDigest:W}=Q,G=await this.publishPackage("marketplaces",O,Q);Q=void 0;let Y={...J,installPath:G,revision:q,contentDigest:W,updatedAt:new Date().toISOString()};return Z.marketplaces[O]=Y,await this.writeState(Z),{success:!0,marketplace:Y,manifest:K,changed:!0}}catch(Z){if(Q)await F.rm(Q.stagingPath,{recursive:!0,force:!0});let J=n(Z);return{success:!1,code:J.code,error:J.message}}})}async removeMarketplace(O,$=!1){return this.runMutation(async()=>{try{if(i(O,"marketplace"),!$)throw new H("CONFIRMATION_REQUIRED",`Removing marketplace "${O}" requires explicit confirmation`);let Q=await this.readState(),Z=Q.marketplaces[O];if(!Z)throw new H("MARKETPLACE_NOT_FOUND",`Marketplace "${O}" is not configured`);let J=Object.values(Q.installed).filter((K)=>K.source.type==="marketplace"&&K.source.marketplace===O).map((K)=>K.name).sort();if(J.length>0)throw new H("MARKETPLACE_IN_USE",`Marketplace "${O}" still owns installed plugins: ${J.join(", ")}`);return delete Q.marketplaces[O],await this.writeState(Q),{success:!0,marketplace:Z,changed:!0}}catch(Q){let Z=n(Q);return{success:!1,code:Z.code,error:Z.message}}})}async listMarketplaces(){return Object.values((await this.readState()).marketplaces).sort((O,$)=>O.name.localeCompare($.name))}async listCatalogs(){let O=await this.listMarketplaces();return Promise.all(O.map(async($)=>({marketplace:$,manifest:await this.readMarketplaceManifest($.installPath)})))}async runMutation(O){return this.mutex.runExclusive(async()=>{let $=await this.acquireStoreLock();try{return await O()}finally{await $()}})}async acquireStoreLock(){await this.ensureStoreDirectory();let O=j.join(this.stateRoot,".operation.lock"),$=OO(),Q=Date.now()+x$;while(Date.now()<Q)try{let Z=await F.open(O,O0.O_CREAT|O0.O_EXCL|O0.O_WRONLY,384);return await Z.writeFile(`${JSON.stringify({version:1,pid:process.pid,token:$,createdAt:new Date().toISOString()})}
722
+ `,"utf8"),await Z.close(),async()=>{try{if(JSON.parse(await F.readFile(O,"utf8")).token===$)await F.unlink(O)}catch(J){if(!s(J))S.warn(`Failed to release plugin package lock: ${J}`)}}}catch(Z){if(Z.code!=="EEXIST")throw Z;await this.removeStaleStoreLock(O),await new Promise((J)=>setTimeout(J,50))}throw new H("PLUGIN_STORE_BUSY","Plugin package store is busy; retry the operation")}async removeStaleStoreLock(O){try{let $=await F.lstat(O);if(!$.isFile()||$.isSymbolicLink())throw new H("PLUGIN_STORE_INVALID","Plugin package lock must be a regular file");if(process.getuid&&$.uid!==process.getuid()||($.mode&511)!==384)throw new H("PLUGIN_STORE_INVALID","Plugin package lock ownership or permissions are invalid");if(Date.now()-$.mtimeMs<T$)return;await F.unlink(O)}catch($){if(!s($)&&$ instanceof H)throw $}}requireSourceTrust(O){if(O!==!0)throw new H("SOURCE_TRUST_REQUIRED","Plugin installation or update requires explicit source trust")}effectivePolicy(O){return O??z0.pluginSourcePolicy}async preparePluginClosure(O){let $=[],Q=new Map,Z=[],J=(q,W,G,Y)=>{if(!o0(W,G))throw new H("DEPENDENCY_VERSION_MISMATCH",`Plugin "${Y}" requires ${q}@${G}, found ${W}`)},K=async(q)=>{let W=q.expectedName?O.state.installed[q.expectedName]:void 0;if(W&&!q.root&&q.requiredRange){if(o0(W.version,q.requiredRange))return W;if(q.recordSource.type!=="marketplace"||W.source.type!=="marketplace"||W.source.marketplace!==q.recordSource.marketplace)J(W.name,W.version,q.requiredRange,q.requiredBy??"dependency");q={...q,source:W.source,recordSource:W.source}}if(W&&q.root&&!O.updateRoot)throw new H("PLUGIN_ALREADY_INSTALLED",`Plugin "${W.name}" is already installed`);if(q.expectedName){let B=Q.get(q.expectedName);if(B){if(q.requiredRange)J(B.name,B.manifest.version,q.requiredRange,q.requiredBy??"dependency");return B}if(Z.includes(q.expectedName))throw new H("DEPENDENCY_CYCLE",`Plugin dependency cycle: ${[...Z,q.expectedName].join(" -> ")}`)}let G=await this.materializePluginSource(q.source,O.state,q.expectedName,O.policy),Y=await r(G.stagingPath);if(!Y)throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),new H("INVALID_PLUGIN","Plugin manifest was not found");let X=i(Y.manifest.name);if(q.expectedName&&q.expectedName!==X)throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),new H("PLUGIN_IDENTITY_MISMATCH",`Requested "${q.expectedName}" but source declares "${X}"`);if(Z.includes(X))throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),new H("DEPENDENCY_CYCLE",`Plugin dependency cycle: ${[...Z,X].join(" -> ")}`);if(q.root&&O.state.installed[X]&&!O.updateRoot)throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),new H("PLUGIN_ALREADY_INSTALLED",`Plugin "${X}" is already installed`);try{g1(Y.manifest)}catch(B){throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),new H("VERSION_INCOMPATIBLE",B instanceof Error?B.message:String(B))}let U={name:X,source:q.recordSource,manifest:Y.manifest,materialized:G,existing:O.state.installed[X]};Z.push(X);try{for(let[B,p]of Object.entries(Y.manifest.dependencies??{}).sort(([G0],[y])=>G0.localeCompare(y))){let G0=Q.get(B);if(G0){J(B,G0.manifest.version,p,X);continue}let y=O.state.installed[B];if(y&&o0(y.version,p))continue;if(q.recordSource.type!=="marketplace")throw new H(y?"DEPENDENCY_VERSION_MISMATCH":"DEPENDENCY_MISSING",y?`Plugin "${X}" requires ${B}@${p}, found ${y.version}`:`Plugin "${X}" requires missing dependency ${B}@${p}; direct sources cannot auto-install dependencies`);let E0=await K({source:y?.source.type==="marketplace"&&y.source.marketplace===q.recordSource.marketplace?y.source:{type:"marketplace",marketplace:q.recordSource.marketplace},recordSource:{type:"marketplace",marketplace:q.recordSource.marketplace},expectedName:B,requiredRange:p,requiredBy:X,root:!1});J(B,"manifest"in E0?E0.manifest.version:E0.version,p,X)}}catch(B){throw await F.rm(G.stagingPath,{recursive:!0,force:!0}),B}finally{Z.pop()}return Q.set(X,U),$.push(U),U};try{let q=await K({source:O.source,recordSource:O.recordSource,expectedName:O.expectedName,root:!0});if(!("manifest"in q))throw new H("PLUGIN_PACKAGE_ERROR","Root plugin unexpectedly resolved to an existing dependency");return{root:q,prepared:$}}catch(q){throw await this.cleanupPreparedPlugins($),q}}async commitPreparedPlugins(O,$){let Q=new Map,Z=new Set,J=new Date().toISOString();for(let K of $){let q=K.existing;if(q?.revision===K.materialized.revision&&q.contentDigest===K.materialized.contentDigest){await F.rm(K.materialized.stagingPath,{recursive:!0,force:!0}),Q.set(K.name,q);continue}let W=await this.publishPackage("packages",K.name,K.materialized),G={name:K.name,source:K.source,installPath:W,version:K.manifest.version,revision:K.materialized.revision,contentDigest:K.materialized.contentDigest,installedAt:q?.installedAt??J,updatedAt:J};O.installed[K.name]=G,Q.set(K.name,G),Z.add(K.name)}if(Z.size>0)await this.writeState(O);return{records:Q,changed:Z}}async cleanupPreparedPlugins(O){await Promise.all(O.map(($)=>F.rm($.materialized.stagingPath,{recursive:!0,force:!0})))}async resolvePluginSource(O,$,Q){let Z=O.trim();if(!Z)throw new H("INVALID_SOURCE","Plugin source is required");let J=D$(Z);if(J){if(!$.marketplaces[J.marketplace])throw new H("MARKETPLACE_NOT_FOUND",`Marketplace "${J.marketplace}" is not configured`);return{source:{type:"marketplace",marketplace:J.marketplace},recordSource:{type:"marketplace",marketplace:J.marketplace},expectedName:J.pluginName}}if(!a0(Z)&&!this.looksLikeGitSource(Z)){let q=[];for(let W of await this.catalogsFromState($))if(W.manifest.plugins.some((G)=>G.name===Z))q.push({pluginName:Z,marketplace:W.marketplace.name});if(q.length===1)return{source:{type:"marketplace",marketplace:q[0].marketplace},recordSource:{type:"marketplace",marketplace:q[0].marketplace},expectedName:Z};if(q.length>1)throw new H("AMBIGUOUS_PLUGIN_SOURCE",`Plugin "${Z}" exists in multiple marketplaces; use name@marketplace`)}if(a0(Z)){let W={type:"local",path:await this.resolveLocalSource(Z,Q.workspaceRoot)};return{source:W,recordSource:W}}let K=this.normalizeGitSource(Z,Q.ref);return{source:K,recordSource:K}}async materializePluginSource(O,$,Q,Z){if(O.type!=="marketplace")return this.materializeSource(O);let J=$.marketplaces[O.marketplace];if(!J)throw new H("MARKETPLACE_NOT_FOUND",`Marketplace "${O.marketplace}" is not configured`);let K=await this.readMarketplaceManifest(J.installPath),q=Q?K.plugins.filter((W)=>W.name===Q):K.plugins;if(q.length!==1)throw new H("MARKETPLACE_PLUGIN_NOT_FOUND",Q?`Plugin "${Q}" was not found in marketplace "${O.marketplace}"`:`Marketplace "${O.marketplace}" requires an explicit plugin name`);return this.materializeMarketplaceEntry(J,q[0],Z)}async materializeMarketplaceEntry(O,$,Q){if(typeof $.source!=="string"){let q=this.normalizeGitSource($.source.url,$.source.sha??$.source.ref);return l(Q,q,`Plugin "${$.name}"`),this.materializeSource(q)}if($.source.startsWith("https://")||$.source.startsWith("ssh://")||$.source.startsWith("git@")){let q=this.normalizeGitSource($.source);return l(Q,q,`Plugin "${$.name}"`),this.materializeSource(q)}let Z=await F.realpath(O.installPath),J=j.resolve(Z,$.source);if(!$0(Z,J)||J===Z)throw new H("MARKETPLACE_PATH_ESCAPE",`Plugin "${$.name}" source escapes its marketplace`);let K=await F.realpath(J);if(!$0(Z,K))throw new H("MARKETPLACE_PATH_ESCAPE",`Plugin "${$.name}" source escapes its marketplace`);return this.materializeSource({type:"local",path:K})}async normalizeMarketplaceSource(O,$){let Q=O.trim();if(!Q)throw new H("INVALID_SOURCE","Marketplace source is required");if(a0(Q))return{type:"local",path:await this.resolveLocalSource(Q,$.workspaceRoot)};return this.normalizeGitSource(Q,$.ref)}normalizeGitSource(O,$){let Q=O;if(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(O))Q=`https://github.com/${O}.git`;else if(O.startsWith("git@")){if(!/^git@[A-Za-z0-9.-]+:[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+(?:\.git)?$/.test(O))throw new H("INVALID_SOURCE","Invalid SSH Git source")}else{let Z;try{Z=new URL(O)}catch{throw new H("INVALID_SOURCE","Invalid Git source")}if(Z.protocol!=="https:"&&Z.protocol!=="ssh:")throw new H("UNSAFE_GIT_PROTOCOL","Git sources must use HTTPS or SSH");if(Z.password||Z.protocol==="https:"&&Z.username)throw new H("GIT_CREDENTIALS_IN_URL","Git credentials must not be embedded in plugin source URLs");if(Z.hash||Z.search)throw new H("INVALID_SOURCE","Use the ref option instead of URL query or fragment parameters");Q=Z.toString()}if($&&(!$.trim()||$.startsWith("-")||$.includes("\x00")))throw new H("INVALID_GIT_REF","Invalid Git ref");return{type:"git",url:Q,...$?{ref:$}:{}}}looksLikeGitSource(O){return O.startsWith("https://")||O.startsWith("ssh://")||O.startsWith("git@")||/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(O)}async resolveLocalSource(O,$){let Q=O==="~"?i0():O.startsWith("~/")?j.join(i0(),O.slice(2)):O,Z=j.resolve($??process.cwd(),Q);this.assertAllowedLocalSource(Z);let J;try{J=await F.realpath(Z)}catch{throw new H("LOCAL_SOURCE_NOT_FOUND",`Local source does not exist: ${O}`)}let K=await F.lstat(J);if(!K.isDirectory()||K.isSymbolicLink())throw new H("INVALID_LOCAL_SOURCE","Local plugin sources must be regular directories");return this.assertAllowedLocalSource(J),J}assertAllowedLocalSource(O){try{qO(O,"sourcePath")}catch{throw new H("INVALID_LOCAL_SOURCE","Local plugin source must reference a local workspace")}}async materializeSource(O){if(O.type==="local")this.assertAllowedLocalSource(O.path);await this.ensureStoreDirectory();let $=j.join(this.stateRoot,"staging",OO());if(await F.mkdir(j.dirname($),{recursive:!0,mode:448}),O.type==="git"){await this.cloneGitSource(O,$);let Z=await this.runGit(["rev-parse","HEAD"],$);if(O.ref&&JO.test(O.ref)&&Z.toLowerCase()!==O.ref.toLowerCase())throw await F.rm($,{recursive:!0,force:!0}),new H("GIT_PIN_MISMATCH","Plugin checkout does not match the requested Git commit SHA");await F.rm(j.join($,".git"),{recursive:!0,force:!0});let J=await this.digestTree($);return{stagingPath:$,revision:Z,contentDigest:J}}await this.copyLocalSource(O.path,$);let Q=await this.digestTree($);return{stagingPath:$,revision:`local-${Q.slice(0,40)}`,contentDigest:Q}}async cloneGitSource(O,$){try{if(O.ref&&JO.test(O.ref))await F.mkdir($,{recursive:!0,mode:448}),await this.runGit(["init"],$),await this.runGit(["remote","add","origin",O.url],$),await this.runGit(["fetch","--depth","1","origin",O.ref],$),await this.runGit(["checkout","--detach","FETCH_HEAD"],$);else{let Q=["clone","--depth","1","--no-tags"];if(O.ref)Q.push("--branch",O.ref);Q.push("--",O.url,$),await this.runGit(Q)}}catch(Q){throw await F.rm($,{recursive:!0,force:!0}),new H("GIT_CLONE_FAILED",`Failed to clone plugin source: ${this.sanitizeError(Q)}`)}}async runGit(O,$){let Q=await I$("git",O,{cwd:$,encoding:"utf8",timeout:A$,maxBuffer:4194304,env:{...process.env,GIT_TERMINAL_PROMPT:"0"}}),Z=typeof Q==="string"?Q:Q.stdout;if(Z===void 0)throw Error("Git process returned an invalid result");return String(Z).trim()}sanitizeError(O){return(O instanceof Error?O.message:String(O)).replaceAll(this.stateRoot,"<plugin-store>").slice(0,500)}async copyLocalSource(O,$){await this.digestTree(O),await F.cp(O,$,{recursive:!0,force:!1,errorOnExist:!0,filter:(Q)=>{return!j.relative(O,Q).split(j.sep).includes(".git")}})}async digestTree(O){let $=[],Q=0,Z=async(K)=>{let q=await F.readdir(K,{withFileTypes:!0});q.sort((W,G)=>W.name.localeCompare(G.name));for(let W of q){if(W.name===".git")continue;let G=j.join(K,W.name),Y=j.relative(O,G),X=await F.lstat(G);if(X.isSymbolicLink())throw new H("PACKAGE_SYMLINK_FORBIDDEN",`Plugin packages may not contain symbolic links: ${Y}`);if(X.isDirectory()){await Z(G);continue}if(!X.isFile())throw new H("PACKAGE_ENTRY_FORBIDDEN",`Plugin packages may contain only files and directories: ${Y}`);if(Q+=X.size,$.push({relative:Y,absolute:G,executable:(X.mode&73)!==0}),$.length>QO||Q>ZO)throw new H("PACKAGE_TOO_LARGE",`Plugin package exceeds ${QO} files or ${ZO} bytes`)}};await Z(O);let J=B$("sha256");for(let K of $)J.update(K.relative),J.update("\x00"),J.update(K.executable?"x":"-"),J.update("\x00"),J.update(await F.readFile(K.absolute)),J.update("\x00");return J.digest("hex")}async publishPackage(O,$,Q){let Z=j.join(this.stateRoot,O,$,Q.contentDigest);await F.mkdir(j.dirname(Z),{recursive:!0,mode:448});try{let J=await F.lstat(Z);if(!J.isDirectory()||J.isSymbolicLink())throw new H("PACKAGE_STORE_CONFLICT","Plugin package destination is not a regular directory");return await F.rm(Q.stagingPath,{recursive:!0,force:!0}),Z}catch(J){if(!s(J))throw J}return await F.rename(Q.stagingPath,Z),Z}async readMarketplaceManifest(O){for(let $ of _$){let Q=j.join(O,$);try{let Z=await F.lstat(Q);if(!Z.isFile()||Z.isSymbolicLink()||Z.size>$O)throw new H("INVALID_MARKETPLACE","Marketplace manifest must be a regular bounded file");let J=JSON.parse(await F.readFile(Q,"utf8")),K=a1(J);if(!K.success)throw new H("INVALID_MARKETPLACE",`Invalid marketplace manifest: ${K.error.issues.map((W)=>`${W.path.join(".")}: ${W.message}`).join("; ")}`);let q=new Set;for(let W of K.data.plugins){if(q.has(W.name))throw new H("INVALID_MARKETPLACE",`Marketplace contains duplicate plugin: ${W.name}`);q.add(W.name)}return K.data}catch(Z){if(s(Z))continue;if(Z instanceof SyntaxError)throw new H("INVALID_MARKETPLACE","Marketplace manifest contains invalid JSON");throw Z}}throw new H("INVALID_MARKETPLACE","Marketplace manifest was not found")}async catalogsFromState(O){let $=Object.values(O.marketplaces).sort((Q,Z)=>Q.name.localeCompare(Z.name));return Promise.all($.map(async(Q)=>({marketplace:Q,manifest:await this.readMarketplaceManifest(Q.installPath)})))}async readState(){let O;try{O=await F.open(this.statePath,O0.O_RDONLY|O0.O_NOFOLLOW)}catch($){if(s($))return w$();throw new H("PLUGIN_STATE_INVALID","Plugin package state must be a regular file")}try{let $=await O.stat();if(!$.isFile()||$.size>$O)throw new H("PLUGIN_STATE_INVALID","Plugin package state is invalid");if(process.getuid&&$.uid!==process.getuid())throw new H("PLUGIN_STATE_INVALID","Plugin package state must be owned by the current user");if(($.mode&511)!==384)throw new H("PLUGIN_STATE_INVALID","Plugin package state permissions must be 0600");let Q=JSON.parse(await O.readFile("utf8")),Z=o1(Q);if(!Z.success)throw new H("PLUGIN_STATE_INVALID","Plugin package state schema is invalid");let J=Z.data;for(let[K,q]of Object.entries(J.installed)){let W=j.join(this.stateRoot,"packages",K);if(K!==q.name||!j.isAbsolute(q.installPath)||!$0(W,q.installPath)||j.basename(q.installPath)!==q.contentDigest||q.source.type==="local"&&!j.isAbsolute(q.source.path))throw new H("PLUGIN_STATE_INVALID","Plugin package state contains an invalid installation");if(q.source.type==="git"){let G=this.normalizeGitSource(q.source.url,q.source.ref);if(G.url!==q.source.url||G.ref!==q.source.ref)throw new H("PLUGIN_STATE_INVALID","Plugin package state contains an invalid Git source")}}for(let[K,q]of Object.entries(J.marketplaces)){let W=j.join(this.stateRoot,"marketplaces",K);if(K!==q.name||!j.isAbsolute(q.installPath)||!$0(W,q.installPath)||j.basename(q.installPath)!==q.contentDigest||q.source.type==="local"&&!j.isAbsolute(q.source.path))throw new H("PLUGIN_STATE_INVALID","Plugin package state contains an invalid marketplace");if(q.source.type==="git"){let G=this.normalizeGitSource(q.source.url,q.source.ref);if(G.url!==q.source.url||G.ref!==q.source.ref)throw new H("PLUGIN_STATE_INVALID","Plugin package state contains an invalid Marketplace Git source")}}for(let K of Object.values(J.installed))if(K.source.type==="marketplace"&&!J.marketplaces[K.source.marketplace])throw new H("PLUGIN_STATE_INVALID","Plugin package state references a missing marketplace");return J}catch($){if($ instanceof SyntaxError)throw new H("PLUGIN_STATE_INVALID","Plugin package state contains invalid JSON");throw $}finally{await O.close()}}async writeState(O){await this.ensureStoreDirectory(),await M$(this.statePath,`${JSON.stringify(O,null,2)}
723
+ `,{mode:384,encoding:"utf8"}),await F.chmod(this.statePath,384)}async ensureStoreDirectory(){try{let O=await F.lstat(this.stateRoot);if(!O.isDirectory()||O.isSymbolicLink())throw new H("PLUGIN_STORE_INVALID","Plugin package store must be a regular directory");if(process.getuid&&O.uid!==process.getuid())throw new H("PLUGIN_STORE_INVALID","Plugin package store must be owned by the current user");if((O.mode&511)!==448)throw new H("PLUGIN_STORE_INVALID","Plugin package store permissions must be 0700")}catch(O){if(!s(O))throw O;await F.mkdir(this.stateRoot,{recursive:!0,mode:448}),await F.chmod(this.stateRoot,448)}}}var t0=null;function e0(O,$){if(!t0)t0=new KO(O,$);return t0}import*as _ from"node:fs/promises";import{homedir as C$}from"node:os";import*as I from"node:path";import LO from"gray-matter";function M0(O,$){return`${O}:${$}`}function GO(O,$){return`${O}__${$}`}class I0{async loadPlugin(O,$,Q={}){let Z=await r(O);if(!Z)throw Error(`Not a valid plugin directory: ${O}`);let{manifest:J,source:K}=Z,q=J.name;S.debug(`Loading plugin "${q}" from ${O}`);let W=Q.skipCommands?[]:await this.loadCommands(O,q),G=Q.skipAgents?[]:await this.loadAgents(O,q),Y=Q.skipSkills?[]:await this.loadSkills(O,q),X=Q.skipHooks?void 0:await this.loadHooks(O),U=Q.skipMcp?void 0:await this.loadMcpConfig(O,q),B=Q.skipLsp?void 0:await this.loadLspConfig(O,q);return S.debug(`Plugin "${q}" loaded: ${W.length} commands, ${G.length} agents, ${Y.length} skills`),{manifest:J,basePath:O,source:$,manifestSource:K,commands:W,agents:G,skills:Y,hooks:X,mcpServers:U,lspServers:B,status:"active",loadedAt:new Date}}async loadCommands(O,$){let Q=I.join(O,"commands"),Z=[];if(!await this.dirExists(Q))return Z;let J=await this.scanMarkdownFiles(Q);for(let K of J)try{let q=await this.parseCommandFile(K,Q,$);if(q)Z.push(q)}catch(q){S.warn(`Failed to load command from ${K}: ${q instanceof Error?q.message:String(q)}`)}return Z}async parseCommandFile(O,$,Q){let Z=await _.readFile(O,"utf-8"),{data:J,content:K}=LO(Z),W=I.relative($,O).split(I.sep),G=W.pop();if(!G)return null;let Y=G.replace(/\.md$/i,""),X=Y;if(W.length>0)X=[...W,Y].join("/");let U=M0(Q,X),B=this.normalizeCommandConfig(J);return{originalName:X,namespacedName:U,pluginName:Q,config:B,content:K.trim(),path:O}}normalizeCommandConfig(O){return{description:this.asString(O.description),allowedTools:this.parseStringArray(O["allowed-tools"]),argumentHint:this.asString(O["argument-hint"]),model:this.asString(O.model),disableModelInvocation:O["disable-model-invocation"]===!0}}async loadAgents(O,$){let Q=I.join(O,"agents"),Z=[];if(!await this.dirExists(Q))return Z;let J=await this.scanMarkdownFiles(Q);for(let K of J)try{let q=await this.parseAgentFile(K,Q,$);if(q)Z.push(q)}catch(q){S.warn(`Failed to load agent from ${K}: ${q instanceof Error?q.message:String(q)}`)}return Z}async parseAgentFile(O,$,Q){let Z=await _.readFile(O,"utf-8"),{data:J,content:K}=LO(Z),q=I.relative($,O),W=I.basename(q,".md"),G=J.name||W,Y=M0(Q,G),X={name:Y,description:this.asString(J.description)||"",tools:this.parseStringArray(J.tools),color:this.asString(J.color),model:this.asString(J.model),permissionMode:this.asString(J.permissionMode),skills:this.parseStringArray(J.skills),systemPrompt:K.trim(),source:`plugin:${Q}`};return{originalName:G,namespacedName:Y,pluginName:Q,config:X,path:O}}async loadSkills(O,$){let Q=I.join(O,"skills"),Z=[];if(!await this.dirExists(Q))return Z;let J=await _.readdir(Q,{withFileTypes:!0});for(let K of J){if(!K.isDirectory())continue;let q=I.join(Q,K.name),W=I.join(q,"SKILL.md");try{let G=await V0(W,"project");if(G.success&&G.content){let Y=G.content.metadata.name,X=M0($,Y);Z.push({originalName:Y,namespacedName:X,pluginName:$,metadata:{...G.content.metadata,name:X},path:q})}}catch(G){S.warn(`Failed to load skill from ${W}: ${G instanceof Error?G.message:String(G)}`)}}return Z}async loadHooks(O){let $=I.join(O,"hooks","hooks.json");try{let Q=await _.readFile($,"utf-8"),Z=JSON.parse(Q);return Z.hooks||Z}catch{return}}async loadMcpConfig(O,$){let Q=I.join(O,".mcp.json");try{let Z=await _.readFile(Q,"utf-8"),J=JSON.parse(Z),K=i1(J);if(!K.success){S.warn(`Invalid .mcp.json in ${O}: ${K.error}`);return}let q="mcpServers"in J?J.mcpServers:J,W={};for(let[G,Y]of Object.entries(q)){let X=GO($,G);W[X]=Y}return W}catch{return}}async loadLspConfig(O,$){let Q=I.join(O,".lsp.json");try{let Z=JSON.parse(await _.readFile(Q,"utf8")),J=Z&&typeof Z==="object"&&!Array.isArray(Z)&&"lspServers"in Z?Z.lspServers:Z,K=WO(J),q={};for(let[W,G]of Object.entries(K)){let Y=(X)=>X.replaceAll("${CLAUDE_PLUGIN_ROOT}",O).replaceAll("${BLADE_PLUGIN_ROOT}",O);q[`plugin:${$}:${W}`]={...G,command:Y(G.command),args:G.args?.map(Y),env:G.env?Object.fromEntries(Object.entries(G.env).map(([X,U])=>[X,Y(U)])):void 0}}return q}catch(Z){if(Z.code!=="ENOENT")S.warn(`Invalid .lsp.json in ${O}: ${Z instanceof Error?Z.message:String(Z)}`);return}}async scanMarkdownFiles(O){let $=[],Q=async(Z)=>{let J=await _.readdir(Z,{withFileTypes:!0});for(let K of J){let q=I.join(Z,K.name);if(K.isDirectory())await Q(q);else if(K.name.endsWith(".md"))$.push(q)}};return await Q(O),$}async dirExists(O){try{return(await _.stat(O)).isDirectory()}catch{return!1}}asString(O){if(typeof O==="string"&&O.trim())return O.trim();return}parseStringArray(O){if(!O)return;if(Array.isArray(O))return O.map(($)=>String($).trim()).filter(Boolean);if(typeof O==="string")return O.split(",").map(($)=>$.trim()).filter(Boolean);return}static getPluginDirs(O){let $=C$();return[{path:I.join($,".claude","plugins"),source:"user",type:"claude"},{path:I.join($,".blade","plugins"),source:"user",type:"blade"},{path:I.join(O,".claude","plugins"),source:"project",type:"claude"},{path:I.join(O,".blade","plugins"),source:"project",type:"blade"}]}async discoverPluginsInDir(O,$){let Q=[],Z=[];try{await _.access(O)}catch{return{plugins:Q,errors:Z}}let J=await _.readdir(O,{withFileTypes:!0});for(let K of J){if(!K.isDirectory())continue;let q=I.join(O,K.name);try{let W=await this.loadPlugin(q,$);Q.push(W)}catch(W){Z.push({path:q,error:W instanceof Error?W.message:String(W)})}}return{plugins:Q,errors:Z}}}class C{static instances=new Map;plugins=new Map;loader=new I0;initialized=!1;workspaceRoot="";cliPluginDirs=[];enabledSettings={};sourcePolicy={...z0.pluginSourcePolicy};marketplaces={};constructor(O){this.workspaceRoot=O}static getInstance(O=M()){let $=O1.resolve(O),Q=C.instances.get($);if(!Q)Q=new C($),C.instances.set($,Q);return Q}static resetInstance(){C.instances.clear()}static releaseInstance(O,$){let Q=O1.resolve(O),Z=C.instances.get(Q);if(!Z||$&&Z!==$)return!1;return C.instances.delete(Q)}static getExistingInstance(O=M()){return C.instances.get(O1.resolve(O))}static getInitializedInstances(){return Array.from(C.instances.values()).filter((O)=>O.isInitialized())}async initialize(O,$=[]){this.workspaceRoot=O,this.cliPluginDirs=$,this.enabledSettings=await b0.getInstance().loadWorkspacePluginSettings(O),await this.refreshPolicyContext();let Q=[],Z=[];for(let G of $)try{let Y=await this.loader.loadPlugin(G,"cli");this.plugins.set(Y.manifest.name,Y),Q.push(Y),S.info(`Loaded CLI plugin: ${Y.manifest.name} from ${G}`)}catch(Y){Z.push({path:G,error:Y instanceof Error?Y.message:String(Y)}),S.warn(`Failed to load CLI plugin from ${G}: ${Y}`)}let J=(await N.getInstance().getStatus(O)).state==="trusted",K=I0.getPluginDirs(O).filter((G)=>G.source!=="project"||J),q=!1,W=async()=>{if(q)return;q=!0;let G=e0(),Y=await G.listInstallationRecords();for(let X of Y)try{await G.verifyInstallation(X);let U=await this.loader.loadPlugin(X.installPath,"user");if(U.manifest.name!==X.name)throw Error(`Managed plugin identity mismatch: ${X.name}`);U.installation=Object.freeze({...X});let B=this.plugins.get(U.manifest.name);if(!B||B.source==="user")this.plugins.set(U.manifest.name,U),Q.push(U)}catch(U){Z.push({path:X.installPath,code:"IO_ERROR",error:U instanceof Error?U.message:String(U)})}};for(let{path:G,source:Y}of K){if(Y==="project")await W();let X=await this.loader.discoverPluginsInDir(G,Y);for(let U of X.plugins){let B=this.plugins.get(U.manifest.name);if(!B||B.source!=="cli")this.plugins.set(U.manifest.name,U),Q.push(U)}Z.push(...X.errors)}await W(),this.applyEnabledSettings();for(let G of this.plugins.values()){if(G.status!=="error")continue;Z.push({path:G.basePath,code:G.compatibilityIssues?.some((Y)=>Y.code==="source-policy")?"SOURCE_POLICY_BLOCKED":G.compatibilityIssues?.some((Y)=>Y.code==="blade-version")?"VERSION_INCOMPATIBLE":"DEPENDENCY_MISSING",error:G.error??"Plugin compatibility check failed"})}return this.initialized=!0,S.info(`Plugin system initialized: ${this.plugins.size} plugins loaded`+(Z.length>0?`, ${Z.length} errors`:"")),{plugins:Array.from(this.plugins.values()),errors:Z}}isInitialized(){return this.initialized}getWorkspaceRoot(){return this.workspaceRoot}getSourcePolicy(){return{...this.sourcePolicy,allowedGitHosts:[...this.sourcePolicy.allowedGitHosts],allowedMarketplaces:[...this.sourcePolicy.allowedMarketplaces],allowedLocalRoots:[...this.sourcePolicy.allowedLocalRoots]}}getAll(){return Array.from(this.plugins.values())}getActive(){return Array.from(this.plugins.values()).filter((O)=>O.status==="active")}get(O){return this.plugins.get(O)}has(O){return this.plugins.has(O)}async reapplyEnabledSettings(){this.enabledSettings=await b0.getInstance().loadWorkspacePluginSettings(this.workspaceRoot),await this.refreshPolicyContext(),this.applyEnabledSettings()}applyEnabledSettings(){for(let O of this.plugins.values()){if(O.compatibilityIssues=[],O.error=void 0,O.status=O.source==="cli"||this.enabledSettings[O.manifest.name]!==!1?"active":"inactive",O.status!=="active")continue;try{e(this.sourcePolicy,O.installation?.source??{type:"local",path:O.basePath},this.marketplaces,`Plugin "${O.manifest.name}"`)}catch($){if(!($ instanceof f))throw $;O.status="error",O.error=$.message,O.compatibilityIssues=[{code:"source-policy",message:$.message}]}}u1(Array.from(this.plugins.values()))}async refreshPolicyContext(){this.sourcePolicy=await b0.getInstance().loadWorkspacePluginSourcePolicy(this.workspaceRoot),this.marketplaces=Object.fromEntries((await e0().listMarketplaces()).map((O)=>[O.name,O]))}getBySource(){let O={cli:[],project:[],user:[]};for(let $ of this.plugins.values())O[$.source].push($);return O}getAllCommands(){let O=[];for(let $ of this.plugins.values())if($.status==="active")O.push(...$.commands);return O}getAllSkills(){let O=[];for(let $ of this.plugins.values())if($.status==="active")O.push(...$.skills);return O}getAllAgents(){let O=[];for(let $ of this.plugins.values())if($.status==="active")O.push(...$.agents);return O}findCommand(O){for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.commands)if(Z.namespacedName===O)return Z}let $=[];for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.commands)if(Z.originalName===O)$.push(Z)}if($.length===1)return $[0];return}findSkill(O){for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.skills)if(Z.namespacedName===O)return Z}let $=[];for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.skills)if(Z.originalName===O)$.push(Z)}if($.length===1)return $[0];return}findAgent(O){for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.agents)if(Z.namespacedName===O)return Z}let $=[];for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.agents)if(Z.originalName===O)$.push(Z)}if($.length===1)return $[0];return}hasCommandConflict(O){let $=0;for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.commands)if(Z.originalName===O){if($++,$>1)return!0}}return!1}getCommandProviders(O){let $=[];for(let Q of this.plugins.values()){if(Q.status!=="active")continue;for(let Z of Q.commands)if(Z.originalName===O){$.push(Q.manifest.name);break}}return $}disable(O){let $=this.plugins.get(O);if($&&$.status==="active")return $.status="inactive",S.info(`Plugin "${O}" disabled`),!0;return!1}enable(O){let $=this.plugins.get(O);if($&&$.status==="inactive")return $.status="active",S.info(`Plugin "${O}" enabled`),!0;return!1}async refresh(){return S.info("Refreshing plugin list..."),this.plugins.clear(),this.initialized=!1,this.initialize(this.workspaceRoot,this.cliPluginDirs)}getStats(){let O=0,$=0,Q=0,Z=0,J=0;for(let K of this.plugins.values())if(K.status==="active")O++,Q+=K.commands.length,Z+=K.skills.length,J+=K.agents.length;else $++;return{total:this.plugins.size,active:O,inactive:$,commands:Q,skills:Z,agents:J}}formatPluginList(){if(this.getAll().length===0)return"没有已加载的插件。";let $=[],Q=this.getBySource();if(Q.cli.length>0){$.push("## CLI 指定的插件");for(let Z of Q.cli){let J=Z.status==="inactive"?" (禁用)":"";$.push(`- **${Z.manifest.name}** v${Z.manifest.version}${J}`),$.push(` ${Z.manifest.description}`)}$.push("")}if(Q.project.length>0){$.push("## 项目级插件");for(let Z of Q.project){let J=Z.status==="inactive"?" (禁用)":"";$.push(`- **${Z.manifest.name}** v${Z.manifest.version}${J}`),$.push(` ${Z.manifest.description}`)}$.push("")}if(Q.user.length>0){$.push("## 用户级插件");for(let Z of Q.user){let J=Z.status==="inactive"?" (禁用)":"";$.push(`- **${Z.manifest.name}** v${Z.manifest.version}${J}`),$.push(` ${Z.manifest.description}`)}}return $.join(`
724
+ `)}}function Q0(O=M()){return C.getInstance(O)}var Z0=new Map,XO=Object.values(A0);function Q1(O,$){let Q=YO.resolve(O),Z=Z0.get(Q);if(!Z||$&&Z.registry!==$)return!1;return J0.getInstance().loadConfig(Z.base,Q),Z0.delete(Q),!0}function $1(O){let $={...O};for(let Q of XO)$[Q]=(O[Q]??[]).map((Z)=>({...Z,matcher:Z.matcher?{...Z.matcher}:void 0,hooks:Z.hooks.map((J)=>({...J}))}));return $}class Z1{commandRegistry;hookManager;skillRegistry;subagentRegistry;workspaceRoot;constructor(O=M()){this.workspaceRoot=YO.resolve(O),this.commandRegistry=x.getInstance(this.workspaceRoot),this.hookManager=J0.getInstance(),this.skillRegistry=g({cwd:this.workspaceRoot}),this.subagentRegistry=o(this.workspaceRoot)}clearAllPluginResources(){this.commandRegistry.clearPluginCommands(),this.skillRegistry.clearPluginSkills(),this.subagentRegistry.clearPluginAgents(),Q1(this.workspaceRoot,Q0(this.workspaceRoot)),S.debug("Cleared all plugin resources from subsystems")}async integrateAll(){let O=Q0(this.workspaceRoot),$=O.getActive(),Q=[],Z=[],J=0,K=0,q=0,W=0,G=0;for(let Y of $){let X=this.integratePlugin(Y);Q.push(X),J+=X.commandsRegistered,K+=X.skillsRegistered,q+=X.agentsRegistered,W+=X.mcpServersRegistered,G+=X.lspServersRegistered,Z.push(...X.errors)}if(this.integrateHooks($,O),J+K+q>0)S.info(`Plugin integration complete: ${J} commands, ${K} skills, ${q} agents, ${W} MCP servers, ${G} LSP servers`);return{plugins:Q,totalCommands:J,totalSkills:K,totalAgents:q,totalMcpServers:W,errors:Z}}integratePlugin(O){let $={pluginName:O.manifest.name,commandsRegistered:0,skillsRegistered:0,agentsRegistered:0,hooksRegistered:!1,mcpServersRegistered:0,lspServersRegistered:0,errors:[]};try{$.commandsRegistered=this.integrateCommands(O)}catch(Q){$.errors.push(`Failed to integrate commands: ${Q instanceof Error?Q.message:String(Q)}`)}try{$.skillsRegistered=this.integrateSkills(O)}catch(Q){$.errors.push(`Failed to integrate skills: ${Q instanceof Error?Q.message:String(Q)}`)}try{$.agentsRegistered=this.integrateAgents(O)}catch(Q){$.errors.push(`Failed to integrate agents: ${Q instanceof Error?Q.message:String(Q)}`)}$.hooksRegistered=O.hooks!==void 0;try{$.mcpServersRegistered=this.integrateMcp(O)}catch(Q){$.errors.push(`Failed to integrate MCP servers: ${Q instanceof Error?Q.message:String(Q)}`)}return $.lspServersRegistered=Object.keys(O.lspServers??{}).length,S.debug(`Integrated plugin "${O.manifest.name}": ${$.commandsRegistered} commands, ${$.skillsRegistered} skills, ${$.agentsRegistered} agents`),$}integrateCommands(O){let $=0;for(let Q of O.commands)this.commandRegistry.registerPluginCommand(Q),$++;return $}integrateSkills(O){let $=0;for(let Q of O.skills)this.skillRegistry.registerPluginSkill(Q),$++;return $}integrateAgents(O){let $=0;for(let Q of O.agents)this.subagentRegistry.register({...Q.config,name:Q.namespacedName}),$++;return $}integrateHooks(O,$){let Q=O.filter((q)=>q.hooks);if(Q.length===0){Q1(this.workspaceRoot,$);return}let Z=$1(this.hookManager.getConfig(this.workspaceRoot));if(!Z0.has(this.workspaceRoot))Z0.set(this.workspaceRoot,{base:$1(Z),registry:$});let J=Z0.get(this.workspaceRoot)?.base??Z,K=$1(J);K.enabled=!0;for(let q of XO){let W=J.enabled?[...J[q]??[]]:[],G=[];for(let Y of Q)for(let X of Y.hooks?.[q]??[])G.push({...X,name:X.name?`plugin:${Y.manifest.name}:${X.name}`:`plugin:${Y.manifest.name}:${q}`,hooks:X.hooks.map((U)=>({...U,source:{kind:"plugin",pluginName:Y.manifest.name,pluginSource:Y.source,pluginRoot:Y.basePath}}))});K[q]=[...W,...G]}this.hookManager.loadConfig(K,this.workspaceRoot)}integrateMcp(O){return Object.keys(O.mcpServers??{}).length}}async function J1(O=M()){return new Z1(O).integrateAll()}function x0(O=M()){new Z1(O).clearAllPluginResources()}function HO(O=M(),$){Q1(O,$)}import{createHash as N$}from"node:crypto";import*as R from"node:fs/promises";import E$ from"node:os";import v from"node:path";import v$ from"gray-matter";var T0=32,FO=24576,UO=16384,VO=131072,_0=4,jO=80,BO=256,zO=/^[a-z0-9][a-z0-9._-]{0,63}$/,R$=P("Agent");function q1(O){for(let $ of O){let Q=$.codePointAt(0)??0;if(Q<=8||Q===11||Q===12||Q>=14&&Q<=31||Q===127||Q>=8203&&Q<=8207||Q>=8234&&Q<=8238||Q>=8288&&Q<=8303||Q===65279)return!0}return!1}function y$(O,$,Q){let Z=typeof O==="string"?O.trim():"",J=$.split(/\r?\n/).map((q)=>q.trim()).find(Boolean)?.replace(/^#+\s*/,"")??"",K=Z||J||Q;if(K.length>BO)throw Error(`Description exceeds ${BO} characters`);if(q1(K))throw Error("Description contains hidden control characters");return K}function f$(O,$){let Q=typeof O==="string"&&O.trim()?O.trim():$;if(Q.length>jO)throw Error(`Name exceeds ${jO} characters`);if(q1(Q))throw Error("Name contains hidden control characters");return Q}function h$(O){let Q=O.replace(/\.md$/i,"").split(v.sep);if(Q.length===0||Q.length>_0||Q.some((Z)=>!zO.test(Z)))throw Error(`Style path must use 1-${_0} lowercase safe segments`);return Q.join(":")}async function k$(O){let $;try{$=await R.lstat(O)}catch(K){if(K.code==="ENOENT")return[];throw K}if($.isSymbolicLink())throw Error(`Output style root cannot be a symlink: ${O}`);if(!$.isDirectory())return[];let Q=await R.realpath(O),Z=[],J=async(K,q)=>{if(q>_0)throw Error(`Output style directory exceeds depth ${_0}`);let W=await R.readdir(K,{withFileTypes:!0});W.sort((G,Y)=>G.name.localeCompare(Y.name));for(let G of W){let Y=v.join(K,G.name);if(G.isSymbolicLink())throw Error(`Output style path cannot be a symlink: ${Y}`);if(G.isDirectory()){await J(Y,q+1);continue}if(!G.isFile()||!G.name.toLowerCase().endsWith(".md"))continue;let X=await R.realpath(Y),U=v.relative(Q,X);if(!U||U.startsWith("..")||v.isAbsolute(U))throw Error(`Output style path escapes its source root: ${Y}`);if(Z.push(X),Z.length>T0)throw Error(`Output style catalog exceeds ${T0} files`)}};return await J(Q,1),Z}async function P$(O,$,Q){let Z=await R.lstat(Q);if(!Z.isFile()||Z.isSymbolicLink())throw Error("Output style must be a regular file");if(Z.size>FO)throw Error(`Output style exceeds ${FO} bytes`);let J=await R.readFile(Q,"utf8"),K=v$(J),q=K.content.trim(),W=Buffer.byteLength(q);if(W===0)throw Error("Output style prompt must not be empty");if(W>UO)throw Error(`Output style prompt exceeds ${UO} bytes`);if(q1(q))throw Error("Output style prompt contains hidden control characters");let G=v.relative($,Q),Y=h$(G);return{id:`${O.idPrefix}:${Y}`,name:f$(K.data.name,Y),description:y$(K.data.description,q,`Custom ${Y} communication style`),source:O.source,contentSha256:N$("sha256").update(q,"utf8").digest("hex"),prompt:q}}async function m$(O,$){let Q=await k$(O.directory);if(Q.length===0)return;let Z=await R.realpath(O.directory);for(let J of Q)try{let K=await P$(O,Z,J);$.set(K.id,K)}catch(K){R$.warn(`[CommunicationStyles] Ignoring ${O.source} style: ${K instanceof Error?K.message:String(K)}`)}}function d$(O,$,Q,Z){let J=[{directory:v.join(Z,".claude","output-styles"),source:"user",idPrefix:"user"},{directory:v.join(Z,".blade","output-styles"),source:"user",idPrefix:"user"}];if($)J.push({directory:v.join(O,".claude","output-styles"),source:"project",idPrefix:"project"},{directory:v.join(O,".blade","output-styles"),source:"project",idPrefix:"project"});for(let K of Q){if(K.status!=="active"||!zO.test(K.manifest.name))continue;J.push({directory:v.join(K.basePath,"output-styles"),source:"plugin",idPrefix:`plugin:${K.manifest.name}`})}return J}async function K1(O,$){let Q=new Map;for(let J of d$(v.resolve(O),$.projectTrusted,$.plugins??[],$.homeDirectory??E$.homedir()))await m$(J,Q);let Z=0;for(let J of Q.values())Z+=Buffer.byteLength(J.prompt??"");if(Q.size>T0)throw Error(`Output style catalog exceeds ${T0} styles`);if(Z>VO)throw Error(`Output style catalog exceeds ${VO} bytes`);return new SO([...Q.values()])}import{createHash as p$}from"node:crypto";import{existsSync as w0,realpathSync as g$}from"node:fs";import*as d from"node:fs/promises";import z from"node:path";import u$ from"fast-glob";import c$ from"gray-matter";import _O from"picomatch";var MO=128,IO=32768,bO=262144,l$=49152,s$=32768,n$=24,AO=16,i$=256,o$=P("Agent"),a$=["**/CLAUDE.md","**/.claude/CLAUDE.md","**/CLAUDE.local.md","**/AGENTS.md","**/AGENTS.override.md","**/BLADE.md","**/.claude/rules/**/*.md","**/.blade/rules/**/*.md"],t$=["**/.git/**","**/node_modules/**","**/.venv/**","**/dist/**","**/build/**","**/coverage/**","**/target/**"];function D0(O){return p$("sha256").update(O,"utf8").digest("hex")}function wO(O){for(let $ of O){let Q=$.codePointAt(0)??0;if(Q<=8||Q===11||Q===12||Q>=14&&Q<=31||Q===127||Q>=8203&&Q<=8207||Q>=8234&&Q<=8238||Q>=8288&&Q<=8303||Q===65279)return!0}return!1}function Y1(O){return O.split(z.sep).join("/")}function G1(O){let $=z.resolve(O),Q=[];while(!0)try{return z.join(g$($),...Q.reverse())}catch(Z){if(Z.code!=="ENOENT")return z.resolve(O);let J=z.dirname($);if(J===$)return z.resolve(O);Q.push(z.basename($)),$=J}}function r$(O){let $=z.resolve(O),Q;while(!0){if(w0(z.join($,".git")))return $;if(!Q&&(w0(z.join($,".blade"))||w0(z.join($,".claude"))||w0(z.join($,"package.json"))))Q=$;let Z=z.dirname($);if(Z===$)return Q??z.resolve(O);$=Z}}function X1(O){return Boolean(O)&&O!==".."&&!O.startsWith("../")}function L1(O,$){return O===""||$===O||$.startsWith(`${O}/`)}function xO(O){return O.replaceAll("&","&amp;").replaceAll('"',"&quot;").replaceAll("<","&lt;").replaceAll(">","&gt;")}function e$(O){let $=typeof O==="string"?O.split(/[,\n]/u):Array.isArray(O)?O:[],Q=[...new Set($.filter((Z)=>typeof Z==="string").map((Z)=>Z.trim().replaceAll("\\","/")).filter(Boolean))];if(Q.length===0||Q.every((Z)=>Z==="**"))return;if(Q.length>AO)throw Error(`paths exceeds ${AO} patterns`);for(let Z of Q){if(Z.length>i$||z.posix.isAbsolute(Z)||Z.split("/").includes("..")||wO(Z))throw Error(`Unsafe project rule path pattern: ${Z.slice(0,80)}`);_O(Z,{dot:!0})}return Q}function O4(O){if(O.endsWith("/CLAUDE.local.md")||O==="CLAUDE.local.md")return{source:"local",kind:"instruction",scopeDirectory:z.posix.dirname(O).replace(/^\.$/u,""),priority:90};for(let Z of[".claude/rules/",".blade/rules/"]){let J=O.indexOf(Z);if(J>=0)return{source:"project",kind:"rule",scopeDirectory:O.slice(0,J).replace(/\/$/u,""),priority:Z.startsWith(".blade")?80:70}}if(O.endsWith("/.claude/CLAUDE.md")||O===".claude/CLAUDE.md")return{source:"project",kind:"instruction",scopeDirectory:O.slice(0,-17).replace(/\/$/u,""),priority:30};let $=z.posix.basename(O),Q=$==="CLAUDE.md"?20:$==="AGENTS.md"?40:$==="AGENTS.override.md"?50:60;return{source:"project",kind:"instruction",scopeDirectory:z.posix.dirname(O).replace(/^\.$/u,""),priority:Q}}function W1(O,$){let Q=O.scopeDirectory?O.scopeDirectory.split("/").length:0,Z=$.scopeDirectory?$.scopeDirectory.split("/").length:0;return Q-Z||O.priority-$.priority||O.relativePath.localeCompare($.relativePath)}function $4(O){return{id:O.id,relativePath:O.relativePath,source:O.source,contentSha256:O.contentSha256}}function q0(O,$,Q){let Z=O.map((q)=>{let W=q.conditional?' conditional="true"':"";return`<instruction-file path="${xO(q.relativePath)}" source="${q.source}" sha256="${q.contentSha256}"${W}>
725
725
  ${q.content}
726
- </instruction-file>`}),J=Q==="contextual-project-instructions"&&$.length>0?` trigger-paths="${bO($.join(","))}"`:"",K=Z.length>0?`<${Q}${J}>
726
+ </instruction-file>`}),J=Q==="contextual-project-instructions"&&$.length>0?` trigger-paths="${xO($.join(","))}"`:"",K=Z.length>0?`<${Q}${J}>
727
727
  ${Z.join(`
728
728
 
729
729
  `)}
730
- </${Q}>`:"";return{content:K,files:[...O],references:O.map(O4),triggerPaths:[...$],contentBytes:Buffer.byteLength(K,"utf8"),provenanceSha256:w0(O.map((q)=>`${q.id}:${q.contentSha256}`).join(`
731
- `))}}function AO(O,$){let Q=$,Z=[];for(let J=O.length-1;J>=0;J-=1){let K=O[J];if(!K)continue;let q=Buffer.byteLength(K.content,"utf8");if(q>Q)continue;Z.push(K),Q-=q}return Z.reverse()}class m{projectRoot;catalogSha256;definitions;byId;constructor(O,$=[]){this.projectRoot=O;this.projectRoot=K1(O),this.definitions=Object.freeze([...$].sort(L1).map((Q)=>Object.freeze({...Q}))),this.byId=new Map(this.definitions.map((Q)=>[Q.id,Q])),this.catalogSha256=w0(this.definitions.map((Q)=>`${Q.id}:${Q.contentSha256}`).join(`
732
- `))}static empty(O){return new m(O)}list(){return this.definitions.map((O)=>({id:O.id,relativePath:O.relativePath,source:O.source,kind:O.kind,conditional:O.conditional,contentSha256:O.contentSha256}))}snapshot(){return new m(this.projectRoot,this.definitions.map((O)=>({...O,patterns:O.patterns?[...O.patterns]:void 0})))}staticRules(O,$=c$){if(this.definitions.length===0)return q0([],[],"project-instructions");let Q=this.relativeSourcePath(O),Z=this.definitions.filter((J)=>!J.conditional&&G1(J.scopeDirectory,Q));return q0(AO(Z,$),[],"project-instructions")}contextualRules(O,$,Q,Z=l$){if(this.definitions.length===0)return q0([],[],"contextual-project-instructions");let J=this.relativeSourcePath(O),K=[...new Set($.map((G)=>W1(z.relative(this.projectRoot,K1(G)))).filter(Y1))].sort(),q=new Map;for(let G of K)for(let Y of this.definitions){if(Q.has(Y.id))continue;if(!G1(Y.scopeDirectory,G))continue;if(Y.conditional){let X=z.posix.relative(Y.scopeDirectory||".",G);if(!Y.patterns?.some((U)=>xO(U,{dot:!0})(X)))continue}else if(G1(Y.scopeDirectory,J))continue;q.set(Y.id,Y)}let W=AO([...q.values()].sort(L1),Z);return q0(W,K,"contextual-project-instructions")}hydrate(O){let $=O.map((Q)=>{let Z=this.byId.get(Q.id);if(!Z||Z.contentSha256!==Q.contentSha256||Z.relativePath!==Q.relativePath||Z.source!==Q.source)throw Error(`Project rule provenance mismatch: ${Q.relativePath}`);return Z});return q0([...new Map($.map((Q)=>[Q.id,Q])).values()].sort(L1),[],"contextual-project-instructions")}relativeSourcePath(O){let $=W1(z.relative(this.projectRoot,K1(O)));if($&&!Y1($))throw Error("Project instruction source is outside the catalog root");return $}}async function $4(O,$){let Q=await d.lstat($);if(!Q.isFile()||Q.isSymbolicLink())throw Error("Project rule must be a regular file");if(Q.size>zO)throw Error(`Project rule exceeds ${zO} bytes`);let Z=await d.realpath($),J=W1(z.relative(O,Z));if(!Y1(J))throw Error("Project rule escapes its repository root");let K=await d.readFile(Z,"utf8");if(TO(K))throw Error("Project rule contains hidden control characters");let q=u$(K),W=q.content.trim();if(!W)throw Error("Project rule content must not be empty");let G=r$(q.data.paths),Y=e$(J),X=w0(JSON.stringify({relativePath:J,patterns:G??[],content:W}));return{id:`${Y.source}:${w0(J).slice(0,20)}`,relativePath:J,source:Y.source,kind:Y.kind,scopeDirectory:Y.scopeDirectory,priority:Y.priority,conditional:Boolean(G),...G?{patterns:G}:{},content:W,contentSha256:X}}async function _O(O,$){let Q=t$(O);if(!$.projectTrusted)return m.empty(Q);let Z=await d.realpath(Q),J=g$.stream([...o$],{cwd:Z,absolute:!0,dot:!0,deep:s$,onlyFiles:!0,followSymbolicLinks:!1,unique:!0,ignore:[...a$]}),K=[];for await(let Y of J)if(K.push(Y.toString()),K.length>SO)throw Error(`Project rule catalog exceeds ${SO} files`);K.sort();let q=new Set(K.filter((Y)=>z.basename(Y)==="AGENTS.override.md").map((Y)=>z.dirname(Y))),W=[],G=0;for(let Y of K){if(z.basename(Y)==="AGENTS.md"&&q.has(z.dirname(Y)))continue;try{let X=await $4(Z,Y);if(G+=Buffer.byteLength(X.content,"utf8"),G>MO)throw Error(`Project rule catalog exceeds ${MO} bytes`);W.push(X)}catch(X){i$.warn(`[ProjectRules] Ignoring rule: ${X instanceof Error?X.message:String(X)}`)}}return new m(Z,W)}var DO=32,D0=64;class CO extends Error{capacity=D0;constructor(){super(`Workspace agent resource capacity is full (${D0})`);this.name="WorkspaceAgentResourceCapacityError"}}var x=new Map,X1=0,NO=[];async function Q4(O){let $=await N.getInstance().getStatus(O.workspaceRoot);O.communicationStyles=await q1(O.workspaceRoot,{projectTrusted:$.state==="trusted",plugins:O.plugins.getActive()})}function Z4(O){let $={...O};for(let Q of Object.values(b0))$[Q]=(O[Q]??[]).map((Z)=>({...Z,matcher:Z.matcher?{...Z.matcher}:void 0,hooks:Z.hooks.map((J)=>({...J}))}));return $}function J5(O){NO=[...new Set(O.map(($)=>H1.resolve($)))]}function EO(O,$){YO(O,$.plugins),C.releaseInstance(O,$.subagents),P.releaseInstance({cwd:O},$.skills),T.releaseInstance(O,$.commands),D.releaseInstance(O,$.plugins)}function vO(O){EO(O.workspaceRoot,O)}function K0(){while(x.size>DO){let O=!1;for(let[$,Q]of x){if(!Q.resources||Q.users>0)continue;if(x.get($)!==Q)continue;x.delete($),vO(Q.resources),O=!0;break}if(!O)return}}function J4(O){setImmediate(()=>{O.users=Math.max(0,O.users-1),K0()}).unref?.()}async function q4(O,$){let Q=await N.getInstance().getStatus(O),Z=o(O),J=g({cwd:O}),K=T.getInstance(O),q=Q0(O);try{if(Z.getAllNames().length===0)Z.loadFromStandardLocations(Q.state==="trusted");await Promise.all([J.initialize(),K.isInitialized()?void 0:K.initialize(O),q.isInitialized()?void 0:q.initialize(O,[...$.cliPluginDirs??NO])]),A0(O),await Z1(O);let W=await q1(O,{projectTrusted:Q.state==="trusted",plugins:q.getActive()}),G=await _O(O,{projectTrusted:Q.state==="trusted"});return{workspaceRoot:O,subagents:Z,skills:J,commands:K,plugins:q,communicationStyles:W,projectRules:G}}catch(W){throw EO(O,{subagents:Z,skills:J,commands:K,plugins:q}),W}}function K4(O,$){let Q={generation:X1,users:0};return Q.promise=q4(O,$).then((Z)=>{if(Q.generation!==X1||x.get(O)!==Q)return vO(Z),Z;return Q.resources=Z,K0(),Z},(Z)=>{if(x.get(O)===Q)x.delete(O);throw Z}),x.set(O,Q),Q}async function RO(O,$){let Q=H1.resolve(O),Z=x.get(Q);if(!Z){if(K0(),x.size>=D0)throw new CO;Z=K4(Q,$)}else x.delete(Q),x.set(Q,Z);Z.users++;let J;try{J=await Z.promise}catch(K){throw Z.users=Math.max(0,Z.users-1),K0(),K}return{entry:Z,resources:J}}async function yO(O,$){if(!$)return;A0(O.workspaceRoot),await Z1(O.workspaceRoot),await Q4(O)}async function q5(O,$={}){let Q=await RO(O,$);try{return await yO(Q.resources,$.reconcilePlugins),Q.resources}finally{J4(Q.entry)}}async function K5(O,$,Q={}){let Z=await RO(O,Q);try{return await yO(Z.resources,Q.reconcilePlugins),await $(Z.resources)}finally{Z.entry.users=Math.max(0,Z.entry.users-1),K0()}}function G5(){let O=0,$=0;for(let Q of x.values()){if(Q.resources)O++;$+=Q.users}return{capacity:DO,activeCapacity:D0,entries:x.size,initialized:O,inFlight:x.size-O,activeUsers:$}}function L5(O){let $="projectRoot"in O?O.projectRoot:O.workspaceRoot;return{projectRoot:H1.resolve($),subagents:O.subagents.snapshot(),skills:O.skills.snapshot(),commands:O.commands.snapshot(),communicationStyles:O.communicationStyles?.snapshot()??wO.snapshot(),projectRules:O.projectRules?.snapshot()??m.empty($),hooks:Z4("hooks"in O&&O.hooks?O.hooks:J0.getInstance().getConfig($))}}function W5(){X1++;for(let[O,$]of x)if($.resources)A0(O);x.clear(),C.resetInstances(),P.resetInstance(),T.resetInstance(),D.resetInstance()}
733
- export{Y4 as zf,X4 as Af,H4 as Bf,M1 as Cf,B4 as Df,S4 as Ef,o as Ff,y4 as Gf,w1 as Hf,g as If,T as Jf,r0 as Kf,M0 as Lf,D as Mf,Q0 as Nf,Z1 as Of,A0 as Pf,m as Qf,DO as Rf,D0 as Sf,CO as Tf,Q4 as Uf,J5 as Vf,q5 as Wf,K5 as Xf,G5 as Yf,L5 as Zf,W5 as _f};
730
+ </${Q}>`:"";return{content:K,files:[...O],references:O.map($4),triggerPaths:[...$],contentBytes:Buffer.byteLength(K,"utf8"),provenanceSha256:D0(O.map((q)=>`${q.id}:${q.contentSha256}`).join(`
731
+ `))}}function TO(O,$){let Q=$,Z=[];for(let J=O.length-1;J>=0;J-=1){let K=O[J];if(!K)continue;let q=Buffer.byteLength(K.content,"utf8");if(q>Q)continue;Z.push(K),Q-=q}return Z.reverse()}class m{projectRoot;catalogSha256;definitions;byId;constructor(O,$=[]){this.projectRoot=O;this.projectRoot=G1(O),this.definitions=Object.freeze([...$].sort(W1).map((Q)=>Object.freeze({...Q}))),this.byId=new Map(this.definitions.map((Q)=>[Q.id,Q])),this.catalogSha256=D0(this.definitions.map((Q)=>`${Q.id}:${Q.contentSha256}`).join(`
732
+ `))}static empty(O){return new m(O)}list(){return this.definitions.map((O)=>({id:O.id,relativePath:O.relativePath,source:O.source,kind:O.kind,conditional:O.conditional,contentSha256:O.contentSha256}))}snapshot(){return new m(this.projectRoot,this.definitions.map((O)=>({...O,patterns:O.patterns?[...O.patterns]:void 0})))}staticRules(O,$=l$){if(this.definitions.length===0)return q0([],[],"project-instructions");let Q=this.relativeSourcePath(O),Z=this.definitions.filter((J)=>!J.conditional&&L1(J.scopeDirectory,Q));return q0(TO(Z,$),[],"project-instructions")}contextualRules(O,$,Q,Z=s$){if(this.definitions.length===0)return q0([],[],"contextual-project-instructions");let J=this.relativeSourcePath(O),K=[...new Set($.map((G)=>Y1(z.relative(this.projectRoot,G1(G)))).filter(X1))].sort(),q=new Map;for(let G of K)for(let Y of this.definitions){if(Q.has(Y.id))continue;if(!L1(Y.scopeDirectory,G))continue;if(Y.conditional){let X=z.posix.relative(Y.scopeDirectory||".",G);if(!Y.patterns?.some((U)=>_O(U,{dot:!0})(X)))continue}else if(L1(Y.scopeDirectory,J))continue;q.set(Y.id,Y)}let W=TO([...q.values()].sort(W1),Z);return q0(W,K,"contextual-project-instructions")}hydrate(O){let $=O.map((Q)=>{let Z=this.byId.get(Q.id);if(!Z||Z.contentSha256!==Q.contentSha256||Z.relativePath!==Q.relativePath||Z.source!==Q.source)throw Error(`Project rule provenance mismatch: ${Q.relativePath}`);return Z});return q0([...new Map($.map((Q)=>[Q.id,Q])).values()].sort(W1),[],"contextual-project-instructions")}relativeSourcePath(O){let $=Y1(z.relative(this.projectRoot,G1(O)));if($&&!X1($))throw Error("Project instruction source is outside the catalog root");return $}}async function Q4(O,$){let Q=await d.lstat($);if(!Q.isFile()||Q.isSymbolicLink())throw Error("Project rule must be a regular file");if(Q.size>IO)throw Error(`Project rule exceeds ${IO} bytes`);let Z=await d.realpath($),J=Y1(z.relative(O,Z));if(!X1(J))throw Error("Project rule escapes its repository root");let K=await d.readFile(Z,"utf8");if(wO(K))throw Error("Project rule contains hidden control characters");let q=c$(K),W=q.content.trim();if(!W)throw Error("Project rule content must not be empty");let G=e$(q.data.paths),Y=O4(J),X=D0(JSON.stringify({relativePath:J,patterns:G??[],content:W}));return{id:`${Y.source}:${D0(J).slice(0,20)}`,relativePath:J,source:Y.source,kind:Y.kind,scopeDirectory:Y.scopeDirectory,priority:Y.priority,conditional:Boolean(G),...G?{patterns:G}:{},content:W,contentSha256:X}}async function DO(O,$){let Q=r$(O);if(!$.projectTrusted)return m.empty(Q);let Z=await d.realpath(Q),J=u$.stream([...a$],{cwd:Z,absolute:!0,dot:!0,deep:n$,onlyFiles:!0,followSymbolicLinks:!1,unique:!0,ignore:[...t$]}),K=[];for await(let Y of J)if(K.push(Y.toString()),K.length>MO)throw Error(`Project rule catalog exceeds ${MO} files`);K.sort();let q=new Set(K.filter((Y)=>z.basename(Y)==="AGENTS.override.md").map((Y)=>z.dirname(Y))),W=[],G=0;for(let Y of K){if(z.basename(Y)==="AGENTS.md"&&q.has(z.dirname(Y)))continue;try{let X=await Q4(Z,Y);if(G+=Buffer.byteLength(X.content,"utf8"),G>bO)throw Error(`Project rule catalog exceeds ${bO} bytes`);W.push(X)}catch(X){o$.warn(`[ProjectRules] Ignoring rule: ${X instanceof Error?X.message:String(X)}`)}}return new m(Z,W)}var CO=32,C0=64;class NO extends Error{capacity=C0;constructor(){super(`Workspace agent resource capacity is full (${C0})`);this.name="WorkspaceAgentResourceCapacityError"}}var T=new Map,H1=0,EO=[];async function Z4(O){let $=await N.getInstance().getStatus(O.workspaceRoot);O.communicationStyles=await K1(O.workspaceRoot,{projectTrusted:$.state==="trusted",plugins:O.plugins.getActive()})}function J4(O){let $={...O};for(let Q of Object.values(A0))$[Q]=(O[Q]??[]).map((Z)=>({...Z,matcher:Z.matcher?{...Z.matcher}:void 0,hooks:Z.hooks.map((J)=>({...J}))}));return $}function K5(O){EO=[...new Set(O.map(($)=>N0.resolve($)))]}function vO(O,$){HO(O,$.plugins),w.releaseInstance(O,$.subagents),h.releaseInstance({cwd:O},$.skills),x.releaseInstance(O,$.commands),C.releaseInstance(O,$.plugins)}function RO(O){vO(O.workspaceRoot,O)}function K0(){while(T.size>CO){let O=!1;for(let[$,Q]of T){if(!Q.resources||Q.users>0)continue;if(T.get($)!==Q)continue;T.delete($),RO(Q.resources),O=!0;break}if(!O)return}}function q4(O){setImmediate(()=>{O.users=Math.max(0,O.users-1),K0()}).unref?.()}async function K4(O,$){let Q=await N.getInstance().getStatus(O),Z=o(O),J=g({cwd:O}),K=x.getInstance(O),q=Q0(O);try{if(Z.getAllNames().length===0)Z.loadFromStandardLocations(Q.state==="trusted");await Promise.all([J.initialize(),K.isInitialized()?void 0:K.initialize(O),q.isInitialized()?void 0:q.initialize(O,[...$.cliPluginDirs??EO])]),x0(O),await J1(O);let W=await K1(O,{projectTrusted:Q.state==="trusted",plugins:q.getActive()}),G=await DO(O,{projectTrusted:Q.state==="trusted"});return{workspaceRoot:O,subagents:Z,skills:J,commands:K,plugins:q,communicationStyles:W,projectRules:G}}catch(W){throw vO(O,{subagents:Z,skills:J,commands:K,plugins:q}),W}}function G4(O,$){let Q={generation:H1,users:0};return Q.promise=K4(O,$).then((Z)=>{if(Q.generation!==H1||T.get(O)!==Q)return RO(Z),Z;return Q.resources=Z,K0(),Z},(Z)=>{if(T.get(O)===Q)T.delete(O);throw Z}),T.set(O,Q),Q}async function yO(O,$){let Q=N0.resolve(O),Z=T.get(Q);if(!Z){if(K0(),T.size>=C0)throw new NO;Z=G4(Q,$)}else T.delete(Q),T.set(Q,Z);Z.users++;let J;try{J=await Z.promise}catch(K){throw Z.users=Math.max(0,Z.users-1),K0(),K}return{entry:Z,resources:J}}async function fO(O,$){if(!$)return;x0(O.workspaceRoot),await J1(O.workspaceRoot),await Z4(O)}async function G5(O,$={}){let Q=await yO(O,$);try{return await fO(Q.resources,$.reconcilePlugins),Q.resources}finally{q4(Q.entry)}}async function L5(O,$,Q={}){let Z=await yO(O,Q);try{return await fO(Z.resources,Q.reconcilePlugins),await $(Z.resources)}finally{Z.entry.users=Math.max(0,Z.entry.users-1),K0()}}function W5(){let O=0,$=0;for(let Q of T.values()){if(Q.resources)O++;$+=Q.users}return{capacity:CO,activeCapacity:C0,entries:T.size,initialized:O,inFlight:T.size-O,activeUsers:$}}function Y5(O){let $="projectRoot"in O?O.projectRoot:O.workspaceRoot;return{projectRoot:N0.resolve($),subagents:O.subagents.snapshot(),skills:O.skills.snapshot(),commands:O.commands.snapshot(),communicationStyles:O.communicationStyles?.snapshot()??F1.snapshot(),projectRules:O.projectRules?.snapshot()??m.empty($),hooks:J4("hooks"in O&&O.hooks?O.hooks:J0.getInstance().getConfig($))}}function X5(O){let $=N0.resolve(O);return{projectRoot:$,subagents:new w,skills:new h,commands:x.empty($),hooks:{enabled:!1},communicationStyles:F1.snapshot(),projectRules:m.empty($)}}function H5(){H1++;for(let[O,$]of T)if($.resources)x0(O);T.clear(),w.resetInstances(),h.resetInstance(),x.resetInstance(),C.resetInstance()}
733
+ export{X4 as ig,H4 as jg,F4 as kg,I1 as lg,S4 as mg,z4 as ng,o as og,f4 as pg,D1 as qg,g as rg,x as sg,e0 as tg,I0 as ug,C as vg,Q0 as wg,J1 as xg,x0 as yg,m as zg,CO as Ag,C0 as Bg,NO as Cg,Z4 as Dg,K5 as Eg,G5 as Fg,L5 as Gg,W5 as Hg,Y5 as Ig,X5 as Jg,H5 as Kg};
@@ -0,0 +1 @@
1
+ import{$f as a,ag as b,bg as c}from"./chunk-mvm1rzc4.js";import"./chunk-edtxcqxa.js";import"./chunk-dfjmvj3d.js";import"./chunk-tkydv9k8.js";import"./chunk-pj69j4zp.js";import"./chunk-zkzhm39s.js";export{b as resolveModelConfig,c as getModelDisplayName,a as getModelApiKeyEnvironmentVariable};