agentstudio 0.4.2 → 0.4.3

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 (280) hide show
  1. package/config/engineConfig.d.ts +15 -0
  2. package/config/engineConfig.d.ts.map +1 -1
  3. package/config/engineConfig.js +30 -0
  4. package/config/engineConfig.js.map +1 -1
  5. package/config/index.d.ts.map +1 -1
  6. package/config/index.js +14 -0
  7. package/config/index.js.map +1 -1
  8. package/config/paths.d.ts +5 -0
  9. package/config/paths.d.ts.map +1 -1
  10. package/config/paths.js +6 -1
  11. package/config/paths.js.map +1 -1
  12. package/engines/claude/__tests__/supportedModels.test.d.ts +6 -4
  13. package/engines/claude/__tests__/supportedModels.test.d.ts.map +1 -1
  14. package/engines/claude/__tests__/supportedModels.test.js +55 -13
  15. package/engines/claude/__tests__/supportedModels.test.js.map +1 -1
  16. package/engines/claude/aguiAdapter.d.ts.map +1 -1
  17. package/engines/claude/aguiAdapter.js +8 -0
  18. package/engines/claude/aguiAdapter.js.map +1 -1
  19. package/engines/claude/claudeEngine.d.ts +36 -3
  20. package/engines/claude/claudeEngine.d.ts.map +1 -1
  21. package/engines/claude/claudeEngine.js +132 -13
  22. package/engines/claude/claudeEngine.js.map +1 -1
  23. package/index.d.ts.map +1 -1
  24. package/index.js +29 -2
  25. package/index.js.map +1 -1
  26. package/middleware/callChain.d.ts +10 -0
  27. package/middleware/callChain.d.ts.map +1 -0
  28. package/middleware/callChain.js +24 -0
  29. package/middleware/callChain.js.map +1 -0
  30. package/middleware/requestId.d.ts +8 -0
  31. package/middleware/requestId.d.ts.map +1 -0
  32. package/middleware/requestId.js +18 -0
  33. package/middleware/requestId.js.map +1 -0
  34. package/package.json +1 -1
  35. package/prompts/gameDevSystemPrompt.d.ts +15 -0
  36. package/prompts/gameDevSystemPrompt.d.ts.map +1 -0
  37. package/prompts/gameDevSystemPrompt.js +37 -0
  38. package/prompts/gameDevSystemPrompt.js.map +1 -0
  39. package/prompts/vibeGamingPrompt.d.ts +13 -0
  40. package/prompts/vibeGamingPrompt.d.ts.map +1 -0
  41. package/prompts/vibeGamingPrompt.js +125 -0
  42. package/prompts/vibeGamingPrompt.js.map +1 -0
  43. package/public/assets/{AgentsPage-BsZdkqzM.js → AgentsPage-CHee5mUh.js} +1 -1
  44. package/public/assets/{Button-CMTSYiKV.js → Button-D5qiS7CR.js} +1 -1
  45. package/public/assets/ChatPage-B7-rn9mH.js +478 -0
  46. package/public/assets/{CommandForm-DwGvE9A_.js → CommandForm-CMfgHNm5.js} +1 -1
  47. package/public/assets/{CommandsPage-qDWzq8xp.js → CommandsPage-B4rjtVWk.js} +1 -1
  48. package/public/assets/{CursorConfigPage-DpUdJzRi.js → CursorConfigPage-DQ-3b3ti.js} +1 -1
  49. package/public/assets/{DashboardPage-BhqKOzob.js → DashboardPage-BowdW2Xj.js} +1 -1
  50. package/public/assets/{EngineGate-BjHJu955.js → EngineGate-DYNvEEbW.js} +1 -1
  51. package/public/assets/{FileBrowser-DboOOM_v.js → FileBrowser-DHyCacM6.js} +1 -1
  52. package/public/assets/{FileExplorer-x5R0Tcmk.js → FileExplorer-BprfeAH_.js} +1 -1
  53. package/public/assets/GeneralSettingsPage-C6hJ_zTw.js +1 -0
  54. package/public/assets/{HooksPage-DDGc0GGV.js → HooksPage-BwE2Zm3X.js} +1 -1
  55. package/public/assets/{LandingPage-CvY4n9Rh.js → LandingPage-DKvwbGX1.js} +1 -1
  56. package/public/assets/{LoginPage-C-PZfjYC.js → LoginPage-BpZhqRAN.js} +1 -1
  57. package/public/assets/{McpAdminSettingsPage-CIILVzB8.js → McpAdminSettingsPage-DuvsM5TX.js} +1 -1
  58. package/public/assets/{McpPage-B4nQUJag.js → McpPage-Hu8vyMhX.js} +1 -1
  59. package/public/assets/{MemorySettingsPage-eu6tsuUh.js → MemorySettingsPage-gIWSsrES.js} +1 -1
  60. package/public/assets/{ModelsPage-Bb5vSsuc.js → ModelsPage-Cosb3hHI.js} +1 -1
  61. package/public/assets/PluginsPage-CuNui9NV.js +12 -0
  62. package/public/assets/{ProjectSelector-CybrDbBY.js → ProjectSelector-CyBlHb2H.js} +1 -1
  63. package/public/assets/{ProjectsPage-DRl-0B4G.js → ProjectsPage-DYhCvH07.js} +1 -1
  64. package/public/assets/{RulesPage-DUt33RkX.js → RulesPage-C32P_Aqz.js} +1 -1
  65. package/public/assets/{ScheduledTasksPage-CTDYYRIN.js → ScheduledTasksPage-ixn5qoiD.js} +1 -1
  66. package/public/assets/SettingsLayout-C_7jR0Te.js +1 -0
  67. package/public/assets/{SkillsPage-Lzw8I9vR.js → SkillsPage-C-WS4N1Y.js} +1 -1
  68. package/public/assets/{SubagentForm-BzzeWg0W.js → SubagentForm-BbxljQUp.js} +1 -1
  69. package/public/assets/{SubagentsPage-bX2XWdJ0.js → SubagentsPage-D66TBaeN.js} +1 -1
  70. package/public/assets/{SystemInfoPage-nEIQbtwG.js → SystemInfoPage-DXVUncTe.js} +1 -1
  71. package/public/assets/{TelemetrySettingsPage-q167I4G9.js → TelemetrySettingsPage-Cp3vOu7X.js} +1 -1
  72. package/public/assets/{ToastTestPage-j224d3QR.js → ToastTestPage-03up9yZR.js} +1 -1
  73. package/public/assets/{ToolsList-CTsQr53G.js → ToolsList-BZFBEuvQ.js} +1 -1
  74. package/public/assets/UnifiedToolSelector-DJN7ASu1.js +1 -0
  75. package/public/assets/{VersionSettingsPage-BwpwiLyl.js → VersionSettingsPage-DppWaX--.js} +1 -1
  76. package/public/assets/{VoiceSettingsPage-d3l9AWBn.js → VoiceSettingsPage-BWJLeedX.js} +1 -1
  77. package/public/assets/{WebSocketTunnelPage-BqEUE7mr.js → WebSocketTunnelPage-BPeSTgEZ.js} +1 -1
  78. package/public/assets/{_basePickBy-DHabY031.js → _basePickBy-0UeYrifO.js} +1 -1
  79. package/public/assets/{_baseUniq-B1lmu3qr.js → _baseUniq-Q0NUbuSr.js} +1 -1
  80. package/public/assets/{agents-KlPdWQ8K.js → agents-DR9EZMs5.js} +1 -1
  81. package/public/assets/{arc-6sRLTBcr.js → arc-BV8erW1-.js} +1 -1
  82. package/public/assets/{architectureDiagram-VXUJARFQ-kwdTmjuB.js → architectureDiagram-VXUJARFQ-BIodTu6s.js} +1 -1
  83. package/public/assets/{blockDiagram-VD42YOAC-CYO9EYkJ.js → blockDiagram-VD42YOAC-4H3KjsGf.js} +1 -1
  84. package/public/assets/{c4Diagram-YG6GDRKO-gAp3--Ee.js → c4Diagram-YG6GDRKO-J2ovCYEr.js} +1 -1
  85. package/public/assets/channel-gveiJv4S.js +1 -0
  86. package/public/assets/{chunk-4BX2VUAB-DQVsL-J6.js → chunk-4BX2VUAB-D7Mc44O6.js} +1 -1
  87. package/public/assets/{chunk-55IACEB6-DVsfnY5X.js → chunk-55IACEB6-CMASo37Z.js} +1 -1
  88. package/public/assets/{chunk-B4BG7PRW-BNmOvuIn.js → chunk-B4BG7PRW-2T3W2IB6.js} +1 -1
  89. package/public/assets/{chunk-DI55MBZ5-BkucWe8Y.js → chunk-DI55MBZ5-FR9qswmO.js} +1 -1
  90. package/public/assets/{chunk-FMBD7UC4-BsvfEdnB.js → chunk-FMBD7UC4-Bz2LO9q3.js} +1 -1
  91. package/public/assets/{chunk-QN33PNHL-DSecsNtM.js → chunk-QN33PNHL-D7mfK9Pm.js} +1 -1
  92. package/public/assets/{chunk-QZHKN3VN-DhvrZSqy.js → chunk-QZHKN3VN-AkuNbqQU.js} +1 -1
  93. package/public/assets/{chunk-TZMSLE5B-BqQ674GC.js → chunk-TZMSLE5B-DtY3rhWy.js} +1 -1
  94. package/public/assets/classDiagram-2ON5EDUG-f-lJUj27.js +1 -0
  95. package/public/assets/classDiagram-v2-WZHVMYZB-f-lJUj27.js +1 -0
  96. package/public/assets/clone-D5-Tsf9e.js +1 -0
  97. package/public/assets/{cose-bilkent-S5V4N54A-D9ZC6LmB.js → cose-bilkent-S5V4N54A-BuEw-qDX.js} +1 -1
  98. package/public/assets/{dagre-6UL2VRFP-s7YD2ZcY.js → dagre-6UL2VRFP-D-NrLBGh.js} +1 -1
  99. package/public/assets/{diagram-PSM6KHXK-C7jhP5tx.js → diagram-PSM6KHXK-BFjWOHNz.js} +1 -1
  100. package/public/assets/{diagram-QEK2KX5R-B348GmS1.js → diagram-QEK2KX5R-C0YlDb8t.js} +1 -1
  101. package/public/assets/{diagram-S2PKOQOG-Cu-zjwc9.js → diagram-S2PKOQOG-BLKbR12g.js} +1 -1
  102. package/public/assets/{erDiagram-Q2GNP2WA-tM4HKBpy.js → erDiagram-Q2GNP2WA-Cov6xnUk.js} +1 -1
  103. package/public/assets/{flowDiagram-NV44I4VS-DjCIshpi.js → flowDiagram-NV44I4VS-DTMKSJI1.js} +1 -1
  104. package/public/assets/{ganttDiagram-LVOFAZNH-Q6plkI5G.js → ganttDiagram-LVOFAZNH-DR0bcfHY.js} +1 -1
  105. package/public/assets/{gitGraphDiagram-NY62KEGX-B3Uw90Yt.js → gitGraphDiagram-NY62KEGX-CvxYSabY.js} +1 -1
  106. package/public/assets/{graph-Bp0jlxBT.js → graph-BYXvelIL.js} +1 -1
  107. package/public/assets/{index-f67nhEoX.js → index-BIGPvi1D.js} +44 -44
  108. package/public/assets/infoDiagram-F6ZHWCRC-CL9g-UgS.js +2 -0
  109. package/public/assets/{journeyDiagram-XKPGCS4Q-CgQogtHU.js → journeyDiagram-XKPGCS4Q-Df8G0pW8.js} +1 -1
  110. package/public/assets/{kanban-definition-3W4ZIXB7-Cv7kVxyy.js → kanban-definition-3W4ZIXB7-DhoP7TG_.js} +1 -1
  111. package/public/assets/{layout-6bkH32V1.js → layout-CgO4Vp_y.js} +1 -1
  112. package/public/assets/{linear-DWoZ6Tbm.js → linear-CaY74pOB.js} +1 -1
  113. package/public/assets/{mindmap-definition-VGOIOE7T-D5wd9HsH.js → mindmap-definition-VGOIOE7T-CVK2y0WQ.js} +1 -1
  114. package/public/assets/{pieDiagram-ADFJNKIX-8vPxErLm.js → pieDiagram-ADFJNKIX-BQt_waQk.js} +1 -1
  115. package/public/assets/{quadrantDiagram-AYHSOK5B-Pn0NZ9k7.js → quadrantDiagram-AYHSOK5B-DvLFoDeH.js} +1 -1
  116. package/public/assets/{requirementDiagram-UZGBJVZJ-C7u8MiN1.js → requirementDiagram-UZGBJVZJ-C4lqjEUP.js} +1 -1
  117. package/public/assets/{sankeyDiagram-TZEHDZUN-C660O4mw.js → sankeyDiagram-TZEHDZUN-BKIDyl6M.js} +1 -1
  118. package/public/assets/{sequenceDiagram-WL72ISMW-pXBA2_3B.js → sequenceDiagram-WL72ISMW-BeyhJ61U.js} +1 -1
  119. package/public/assets/{stateDiagram-FKZM4ZOC-CxZMM1Lf.js → stateDiagram-FKZM4ZOC-CKyn6eKl.js} +1 -1
  120. package/public/assets/stateDiagram-v2-4FDKWEC3-DogBVcJE.js +1 -0
  121. package/public/assets/{table-Clz57edU.js → table-BgVewkB5.js} +1 -1
  122. package/public/assets/{timeline-definition-IT6M3QCI-Crg44TaP.js → timeline-definition-IT6M3QCI-Cm5SIAmT.js} +1 -1
  123. package/public/assets/tools-crrPnehB.js +1 -0
  124. package/public/assets/{treemap-KMMF4GRG-bFxwBWXw.js → treemap-KMMF4GRG-CUMeoVWM.js} +1 -1
  125. package/public/assets/{ui-components-DjgDPiqV.js → ui-components-D1pZO0y-.js} +1 -1
  126. package/public/assets/{useAgents-8KXN6U61.js → useAgents-M4lcWvy0.js} +1 -1
  127. package/public/assets/{useClaudeVersions-DicHLV6A.js → useClaudeVersions-CKT_fq1t.js} +1 -1
  128. package/public/assets/{useCommands-DbSH48ba.js → useCommands-vaoVPEDI.js} +1 -1
  129. package/public/assets/{useProjects-Bbh6hJMM.js → useProjects-D1ElB-WS.js} +1 -1
  130. package/public/assets/{useSessions-DOa4-xiB.js → useSessions-Dp1kUl43.js} +1 -1
  131. package/public/assets/{xychartDiagram-PRI3JC2R-DG3KmjD-.js → xychartDiagram-PRI3JC2R-Cy-SHDyX.js} +1 -1
  132. package/public/index.html +4 -4
  133. package/routes/a2a.d.ts.map +1 -1
  134. package/routes/a2a.js +27 -7
  135. package/routes/a2a.js.map +1 -1
  136. package/routes/agents.d.ts.map +1 -1
  137. package/routes/agents.js +234 -38
  138. package/routes/agents.js.map +1 -1
  139. package/routes/agui.d.ts.map +1 -1
  140. package/routes/agui.js +44 -1
  141. package/routes/agui.js.map +1 -1
  142. package/routes/gitVersions.d.ts.map +1 -1
  143. package/routes/gitVersions.js +80 -1
  144. package/routes/gitVersions.js.map +1 -1
  145. package/routes/marketplaceSkills.d.ts +18 -0
  146. package/routes/marketplaceSkills.d.ts.map +1 -0
  147. package/routes/marketplaceSkills.js +190 -0
  148. package/routes/marketplaceSkills.js.map +1 -0
  149. package/routes/plugins.d.ts.map +1 -1
  150. package/routes/plugins.js +48 -7
  151. package/routes/plugins.js.map +1 -1
  152. package/routes/projects.d.ts.map +1 -1
  153. package/routes/projects.js +34 -0
  154. package/routes/projects.js.map +1 -1
  155. package/schemas/a2a.d.ts +35 -4
  156. package/schemas/a2a.d.ts.map +1 -1
  157. package/schemas/a2a.js +9 -1
  158. package/schemas/a2a.js.map +1 -1
  159. package/services/__tests__/agentImporter.test.js +197 -0
  160. package/services/__tests__/agentImporter.test.js.map +1 -1
  161. package/services/__tests__/pluginInstaller.test.js +2 -1
  162. package/services/__tests__/pluginInstaller.test.js.map +1 -1
  163. package/services/agentImporter.d.ts +7 -0
  164. package/services/agentImporter.d.ts.map +1 -1
  165. package/services/agentImporter.js +57 -4
  166. package/services/agentImporter.js.map +1 -1
  167. package/services/builtinMarketplaceService.d.ts +56 -0
  168. package/services/builtinMarketplaceService.d.ts.map +1 -0
  169. package/services/builtinMarketplaceService.js +328 -0
  170. package/services/builtinMarketplaceService.js.map +1 -0
  171. package/services/claudeSession.d.ts.map +1 -1
  172. package/services/claudeSession.js +15 -4
  173. package/services/claudeSession.js.map +1 -1
  174. package/services/claudeVersionStorage.js +6 -6
  175. package/services/claudeVersionStorage.js.map +1 -1
  176. package/services/gitVersionService.d.ts +22 -0
  177. package/services/gitVersionService.d.ts.map +1 -1
  178. package/services/gitVersionService.js +117 -19
  179. package/services/gitVersionService.js.map +1 -1
  180. package/services/marketplaceSkillService.d.ts +129 -0
  181. package/services/marketplaceSkillService.d.ts.map +1 -0
  182. package/services/marketplaceSkillService.js +358 -0
  183. package/services/marketplaceSkillService.js.map +1 -0
  184. package/services/marketplaceUpdateService.d.ts.map +1 -1
  185. package/services/marketplaceUpdateService.js +29 -2
  186. package/services/marketplaceUpdateService.js.map +1 -1
  187. package/services/pluginCopyInstall.d.ts +60 -0
  188. package/services/pluginCopyInstall.d.ts.map +1 -0
  189. package/services/pluginCopyInstall.js +290 -0
  190. package/services/pluginCopyInstall.js.map +1 -0
  191. package/services/pluginInstallStrategy.d.ts +39 -0
  192. package/services/pluginInstallStrategy.d.ts.map +1 -0
  193. package/services/pluginInstallStrategy.js +50 -0
  194. package/services/pluginInstallStrategy.js.map +1 -0
  195. package/services/pluginInstaller.d.ts +10 -0
  196. package/services/pluginInstaller.d.ts.map +1 -1
  197. package/services/pluginInstaller.js +70 -20
  198. package/services/pluginInstaller.js.map +1 -1
  199. package/services/pluginParser.d.ts +17 -1
  200. package/services/pluginParser.d.ts.map +1 -1
  201. package/services/pluginParser.js +161 -84
  202. package/services/pluginParser.js.map +1 -1
  203. package/services/pluginPaths.d.ts +3 -3
  204. package/services/pluginPaths.d.ts.map +1 -1
  205. package/services/pluginPaths.js +33 -14
  206. package/services/pluginPaths.js.map +1 -1
  207. package/services/pluginScanner.js +2 -2
  208. package/services/pluginScanner.js.map +1 -1
  209. package/services/pluginSymlink.d.ts +10 -0
  210. package/services/pluginSymlink.d.ts.map +1 -1
  211. package/services/pluginSymlink.js +117 -1
  212. package/services/pluginSymlink.js.map +1 -1
  213. package/services/preSendGuard/__tests__/preSendGuard.test.d.ts +2 -0
  214. package/services/preSendGuard/__tests__/preSendGuard.test.d.ts.map +1 -0
  215. package/services/preSendGuard/__tests__/preSendGuard.test.js +102 -0
  216. package/services/preSendGuard/__tests__/preSendGuard.test.js.map +1 -0
  217. package/services/preSendGuard/configResolver.d.ts +8 -0
  218. package/services/preSendGuard/configResolver.d.ts.map +1 -0
  219. package/services/preSendGuard/configResolver.js +181 -0
  220. package/services/preSendGuard/configResolver.js.map +1 -0
  221. package/services/preSendGuard/index.d.ts +9 -0
  222. package/services/preSendGuard/index.d.ts.map +1 -0
  223. package/services/preSendGuard/index.js +165 -0
  224. package/services/preSendGuard/index.js.map +1 -0
  225. package/services/preSendGuard/providers/httpAuditProvider.d.ts +3 -0
  226. package/services/preSendGuard/providers/httpAuditProvider.d.ts.map +1 -0
  227. package/services/preSendGuard/providers/httpAuditProvider.js +98 -0
  228. package/services/preSendGuard/providers/httpAuditProvider.js.map +1 -0
  229. package/services/preSendGuard/providers/noopProvider.d.ts +3 -0
  230. package/services/preSendGuard/providers/noopProvider.d.ts.map +1 -0
  231. package/services/preSendGuard/providers/noopProvider.js +13 -0
  232. package/services/preSendGuard/providers/noopProvider.js.map +1 -0
  233. package/services/runFinishedHooks.d.ts +29 -0
  234. package/services/runFinishedHooks.d.ts.map +1 -0
  235. package/services/runFinishedHooks.js +57 -0
  236. package/services/runFinishedHooks.js.map +1 -0
  237. package/testing/index.d.ts +18 -0
  238. package/testing/index.d.ts.map +1 -0
  239. package/testing/index.js +25 -0
  240. package/testing/index.js.map +1 -0
  241. package/testing/mockSdkQuery.d.ts +49 -0
  242. package/testing/mockSdkQuery.d.ts.map +1 -0
  243. package/testing/mockSdkQuery.js +209 -0
  244. package/testing/mockSdkQuery.js.map +1 -0
  245. package/testing/scenarioLoader.d.ts +71 -0
  246. package/testing/scenarioLoader.d.ts.map +1 -0
  247. package/testing/scenarioLoader.js +224 -0
  248. package/testing/scenarioLoader.js.map +1 -0
  249. package/types/a2a.d.ts +5 -0
  250. package/types/a2a.d.ts.map +1 -1
  251. package/types/agents.d.ts +32 -0
  252. package/types/agents.d.ts.map +1 -1
  253. package/types/agents.js +1 -0
  254. package/types/agents.js.map +1 -1
  255. package/types/engine.d.ts +6 -0
  256. package/types/engine.d.ts.map +1 -1
  257. package/types/plugins.d.ts +12 -2
  258. package/types/plugins.d.ts.map +1 -1
  259. package/types/preSendGuard.d.ts +51 -0
  260. package/types/preSendGuard.d.ts.map +1 -0
  261. package/types/preSendGuard.js +3 -0
  262. package/types/preSendGuard.js.map +1 -0
  263. package/utils/__tests__/claudeUtils.test.js +89 -1
  264. package/utils/__tests__/claudeUtils.test.js.map +1 -1
  265. package/utils/claudeUtils.d.ts +1 -1
  266. package/utils/claudeUtils.d.ts.map +1 -1
  267. package/utils/claudeUtils.js +92 -37
  268. package/utils/claudeUtils.js.map +1 -1
  269. package/public/assets/ChatPage-D8buVhfb.js +0 -478
  270. package/public/assets/GeneralSettingsPage-DYdwai51.js +0 -1
  271. package/public/assets/PluginsPage-DD92Xk6X.js +0 -12
  272. package/public/assets/SettingsLayout-LGC-0pQl.js +0 -1
  273. package/public/assets/UnifiedToolSelector-BP6fuyzG.js +0 -1
  274. package/public/assets/channel-D9wyZF1L.js +0 -1
  275. package/public/assets/classDiagram-2ON5EDUG-DwEqkkEb.js +0 -1
  276. package/public/assets/classDiagram-v2-WZHVMYZB-DwEqkkEb.js +0 -1
  277. package/public/assets/clone-3wFPaI2j.js +0 -1
  278. package/public/assets/infoDiagram-F6ZHWCRC-HUfwv_JT.js +0 -2
  279. package/public/assets/stateDiagram-v2-4FDKWEC3-CmurzrWf.js +0 -1
  280. package/public/assets/tools-BZTR2NP1.js +0 -1
@@ -0,0 +1,290 @@
1
+ "use strict";
2
+ /**
3
+ * Plugin Copy Install Service
4
+ *
5
+ * Installs plugin components via file copy for the cursor-cli engine.
6
+ * Unlike pluginSymlink.ts (which uses symlinks for claude-sdk),
7
+ * this service copies files directly to the target directories.
8
+ *
9
+ * Key differences from symlink approach:
10
+ * - Skills: copied to ~/.cursor/skills-cursor/ (or builtinSkillsDir)
11
+ * - MCP: accumulated and written as unified mcp.json
12
+ * - Rules/Commands: copied with pluginName-id naming pattern
13
+ * - Clean-before-install: clears target directories before installation
14
+ *
15
+ * This logic is ported from as-mate's marketplace-service.ts.
16
+ */
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || (function () {
34
+ var ownKeys = function(o) {
35
+ ownKeys = Object.getOwnPropertyNames || function (o) {
36
+ var ar = [];
37
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
38
+ return ar;
39
+ };
40
+ return ownKeys(o);
41
+ };
42
+ return function (mod) {
43
+ if (mod && mod.__esModule) return mod;
44
+ var result = {};
45
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
46
+ __setModuleDefault(result, mod);
47
+ return result;
48
+ };
49
+ })();
50
+ Object.defineProperty(exports, "__esModule", { value: true });
51
+ exports.pluginCopyInstall = void 0;
52
+ const fs = __importStar(require("fs"));
53
+ const path = __importStar(require("path"));
54
+ const engineConfig_js_1 = require("../config/engineConfig.js");
55
+ /**
56
+ * Plugin Copy Install Service
57
+ * Installs plugins via file copy (for cursor-cli engine)
58
+ */
59
+ class PluginCopyInstall {
60
+ // MCP config accumulator: collects MCP configs across all plugins
61
+ mcpConfigAccumulator = {};
62
+ /**
63
+ * Install all components of a plugin via file copy
64
+ */
65
+ async createSymlinks(parsedPlugin) {
66
+ const { components, marketplaceName, pluginName } = parsedPlugin;
67
+ // Install commands
68
+ for (const command of components.commands) {
69
+ await this.installCommand(command, pluginName);
70
+ }
71
+ // Install agents
72
+ for (const agent of components.agents) {
73
+ await this.installAgent(agent, pluginName);
74
+ }
75
+ // Install skills
76
+ for (const skill of components.skills) {
77
+ const skillDir = path.dirname(skill.path); // Remove SKILL.md to get directory
78
+ await this.installSkill(skillDir, skill.name, pluginName);
79
+ }
80
+ // Collect MCP server configs (will be written out later via flushMCPConfig)
81
+ for (const mcpServer of components.mcpServers) {
82
+ await this.collectMCPServer(mcpServer, pluginName);
83
+ }
84
+ }
85
+ /**
86
+ * Remove installed plugin components
87
+ */
88
+ async removeSymlinks(parsedPlugin) {
89
+ const { components, marketplaceName, pluginName } = parsedPlugin;
90
+ const paths = (0, engineConfig_js_1.getEnginePaths)();
91
+ // Remove commands
92
+ for (const command of components.commands) {
93
+ const targetPath = path.join(paths.commandsDir, `${command.name}.md`);
94
+ this.safeRemove(targetPath);
95
+ }
96
+ // Remove agents
97
+ for (const agent of components.agents) {
98
+ const targetPath = path.join(paths.agentsDir, `${agent.name}.md`);
99
+ this.safeRemove(targetPath);
100
+ }
101
+ // Remove skills
102
+ for (const skill of components.skills) {
103
+ const skillsDir = paths.builtinSkillsDir || paths.skillsDir;
104
+ const targetPath = path.join(skillsDir, skill.name);
105
+ this.safeRemoveDir(targetPath);
106
+ }
107
+ // Note: MCP config entries are not individually removed;
108
+ // they'll be rebuilt on next full install
109
+ }
110
+ /**
111
+ * Clean target directories before a full marketplace install.
112
+ * Called before installPlugins to ensure a clean state.
113
+ *
114
+ * For cursor-cli engine, this performs:
115
+ * - Complete removal of skills directory (user customizations should be in workspace)
116
+ * - Removal of marketplace-installed rules (files containing '-' with .mdc extension)
117
+ * - Removal of marketplace-installed commands (files containing '-' with .md extension)
118
+ * - Reset of MCP config accumulator
119
+ */
120
+ cleanBeforeInstall() {
121
+ const paths = (0, engineConfig_js_1.getEnginePaths)();
122
+ const skillsDir = paths.builtinSkillsDir || paths.skillsDir;
123
+ // Clear skills directory completely
124
+ if (fs.existsSync(skillsDir)) {
125
+ fs.rmSync(skillsDir, { recursive: true, force: true });
126
+ console.log(`[PluginCopyInstall] Skills directory cleared: ${skillsDir}`);
127
+ }
128
+ // Clear marketplace-installed rules (pattern: contains '-' and ends with .mdc)
129
+ if (fs.existsSync(paths.rulesDir)) {
130
+ const files = fs.readdirSync(paths.rulesDir);
131
+ for (const file of files) {
132
+ if (file.includes('-') && file.endsWith('.mdc')) {
133
+ fs.rmSync(path.join(paths.rulesDir, file), { force: true });
134
+ }
135
+ }
136
+ console.log(`[PluginCopyInstall] Marketplace rules cleared: ${paths.rulesDir}`);
137
+ }
138
+ // Clear marketplace-installed commands (pattern: contains '-' and ends with .md)
139
+ if (fs.existsSync(paths.commandsDir)) {
140
+ const files = fs.readdirSync(paths.commandsDir);
141
+ for (const file of files) {
142
+ if (file.includes('-') && file.endsWith('.md')) {
143
+ fs.rmSync(path.join(paths.commandsDir, file), { force: true });
144
+ }
145
+ }
146
+ console.log(`[PluginCopyInstall] Marketplace commands cleared: ${paths.commandsDir}`);
147
+ }
148
+ // Reset MCP accumulator
149
+ this.mcpConfigAccumulator = {};
150
+ }
151
+ /**
152
+ * Flush accumulated MCP config to mcp.json (overwrite mode).
153
+ * Should be called after all plugins have been installed.
154
+ */
155
+ flushMCPConfig() {
156
+ const paths = (0, engineConfig_js_1.getEnginePaths)();
157
+ const mcpConfigPath = paths.mcpConfigPath;
158
+ if (Object.keys(this.mcpConfigAccumulator).length === 0) {
159
+ console.log('[PluginCopyInstall] No MCP servers to configure');
160
+ return;
161
+ }
162
+ const mcpConfig = { mcpServers: this.mcpConfigAccumulator };
163
+ fs.mkdirSync(path.dirname(mcpConfigPath), { recursive: true });
164
+ fs.writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2));
165
+ console.log(`[PluginCopyInstall] MCP config written (${Object.keys(this.mcpConfigAccumulator).length} servers): ${mcpConfigPath}`);
166
+ }
167
+ /**
168
+ * Check if copy-installed files exist for a plugin
169
+ */
170
+ async checkSymlinks(parsedPlugin) {
171
+ const { components } = parsedPlugin;
172
+ const paths = (0, engineConfig_js_1.getEnginePaths)();
173
+ for (const command of components.commands) {
174
+ const targetPath = path.join(paths.commandsDir, `${command.name}.md`);
175
+ if (fs.existsSync(targetPath))
176
+ return true;
177
+ }
178
+ for (const agent of components.agents) {
179
+ const targetPath = path.join(paths.agentsDir, `${agent.name}.md`);
180
+ if (fs.existsSync(targetPath))
181
+ return true;
182
+ }
183
+ for (const skill of components.skills) {
184
+ const skillsDir = paths.builtinSkillsDir || paths.skillsDir;
185
+ const targetPath = path.join(skillsDir, skill.name);
186
+ if (fs.existsSync(targetPath))
187
+ return true;
188
+ }
189
+ return false;
190
+ }
191
+ // ==========================================================================
192
+ // Private installation methods
193
+ // ==========================================================================
194
+ async installCommand(command, pluginName) {
195
+ const paths = (0, engineConfig_js_1.getEnginePaths)();
196
+ const targetPath = path.join(paths.commandsDir, `${command.name}.md`);
197
+ try {
198
+ fs.mkdirSync(paths.commandsDir, { recursive: true });
199
+ fs.copyFileSync(command.path, targetPath);
200
+ console.log(`[PluginCopyInstall] Command installed: ${command.name} -> ${targetPath}`);
201
+ }
202
+ catch (error) {
203
+ console.error(`[PluginCopyInstall] Failed to install command ${command.name}:`, error);
204
+ }
205
+ }
206
+ async installAgent(agent, pluginName) {
207
+ const paths = (0, engineConfig_js_1.getEnginePaths)();
208
+ const targetPath = path.join(paths.agentsDir, `${agent.name}.md`);
209
+ try {
210
+ fs.mkdirSync(paths.agentsDir, { recursive: true });
211
+ fs.copyFileSync(agent.path, targetPath);
212
+ console.log(`[PluginCopyInstall] Agent installed: ${agent.name} -> ${targetPath}`);
213
+ }
214
+ catch (error) {
215
+ console.error(`[PluginCopyInstall] Failed to install agent ${agent.name}:`, error);
216
+ }
217
+ }
218
+ async installSkill(sourceDir, skillName, pluginName) {
219
+ const paths = (0, engineConfig_js_1.getEnginePaths)();
220
+ // For cursor-cli, use builtinSkillsDir (~/.cursor/skills-cursor/) if available
221
+ const skillsDir = paths.builtinSkillsDir || paths.skillsDir;
222
+ const targetDir = path.join(skillsDir, skillName);
223
+ try {
224
+ fs.mkdirSync(skillsDir, { recursive: true });
225
+ // Overwrite mode: remove existing then copy
226
+ if (fs.existsSync(targetDir)) {
227
+ fs.rmSync(targetDir, { recursive: true, force: true });
228
+ }
229
+ fs.cpSync(sourceDir, targetDir, { recursive: true });
230
+ console.log(`[PluginCopyInstall] Skill installed: ${skillName} -> ${targetDir}`);
231
+ }
232
+ catch (error) {
233
+ console.error(`[PluginCopyInstall] Failed to install skill ${skillName}:`, error);
234
+ }
235
+ }
236
+ async collectMCPServer(mcpComponent, pluginName) {
237
+ try {
238
+ const mcpDir = path.dirname(mcpComponent.path);
239
+ const manifestPath = mcpComponent.path;
240
+ if (!fs.existsSync(manifestPath)) {
241
+ console.warn(`[PluginCopyInstall] MCP manifest not found: ${manifestPath}`);
242
+ return;
243
+ }
244
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
245
+ // Build entry file path
246
+ const entryFile = manifest.cursorEntry
247
+ ? path.join(mcpDir, manifest.cursorEntry)
248
+ : path.join(mcpDir, 'dist', 'index.js');
249
+ this.mcpConfigAccumulator[mcpComponent.name] = {
250
+ command: process.execPath, // Use current Node.js path
251
+ args: [entryFile],
252
+ env: {
253
+ MCP_PLUGIN: pluginName,
254
+ ...(manifest.env || {}),
255
+ },
256
+ };
257
+ console.log(`[PluginCopyInstall] MCP server collected: ${mcpComponent.name} (entry: ${entryFile})`);
258
+ }
259
+ catch (error) {
260
+ console.error(`[PluginCopyInstall] Failed to collect MCP server ${mcpComponent.name}:`, error);
261
+ }
262
+ }
263
+ // ==========================================================================
264
+ // Utility methods
265
+ // ==========================================================================
266
+ safeRemove(filePath) {
267
+ try {
268
+ if (fs.existsSync(filePath)) {
269
+ fs.unlinkSync(filePath);
270
+ console.log(`[PluginCopyInstall] Removed: ${filePath}`);
271
+ }
272
+ }
273
+ catch (error) {
274
+ console.error(`[PluginCopyInstall] Failed to remove ${filePath}:`, error);
275
+ }
276
+ }
277
+ safeRemoveDir(dirPath) {
278
+ try {
279
+ if (fs.existsSync(dirPath)) {
280
+ fs.rmSync(dirPath, { recursive: true, force: true });
281
+ console.log(`[PluginCopyInstall] Removed directory: ${dirPath}`);
282
+ }
283
+ }
284
+ catch (error) {
285
+ console.error(`[PluginCopyInstall] Failed to remove directory ${dirPath}:`, error);
286
+ }
287
+ }
288
+ }
289
+ exports.pluginCopyInstall = new PluginCopyInstall();
290
+ //# sourceMappingURL=pluginCopyInstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginCopyInstall.js","sourceRoot":"","sources":["../../src/services/pluginCopyInstall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Plugin Install Strategy
3
+ *
4
+ * Routes plugin installation to the appropriate engine-specific installer:
5
+ * - cursor-cli: Uses pluginCopyInstall (file copy + MCP json merge)
6
+ * - claude-sdk: Uses pluginSymlink (symbolic links)
7
+ *
8
+ * This module provides a unified interface so callers don't need to
9
+ * know which engine is active.
10
+ */
11
+ import type { ParsedPlugin } from '../types/plugins.js';
12
+ /**
13
+ * Common interface for plugin installation
14
+ */
15
+ export interface PluginInstaller {
16
+ createSymlinks(parsedPlugin: ParsedPlugin): Promise<void>;
17
+ removeSymlinks(parsedPlugin: ParsedPlugin): Promise<void>;
18
+ checkSymlinks(parsedPlugin: ParsedPlugin): Promise<boolean>;
19
+ }
20
+ /**
21
+ * Get the plugin installer for the current engine.
22
+ *
23
+ * - cursor-cli: returns pluginCopyInstall (file copy mode)
24
+ * - claude-sdk: returns pluginSymlink (symlink mode)
25
+ */
26
+ export declare function getPluginInstaller(): PluginInstaller;
27
+ /**
28
+ * Clean target directories before a full marketplace install.
29
+ * Only applicable for cursor-cli engine (copy mode).
30
+ * For claude-sdk (symlink mode), this is a no-op.
31
+ */
32
+ export declare function cleanBeforeInstall(): void;
33
+ /**
34
+ * Flush accumulated MCP config after all plugins are installed.
35
+ * Only applicable for cursor-cli engine (writes unified mcp.json).
36
+ * For claude-sdk, this is a no-op.
37
+ */
38
+ export declare function flushMCPConfig(): void;
39
+ //# sourceMappingURL=pluginInstallStrategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginInstallStrategy.d.ts","sourceRoot":"","sources":["../../src/services/pluginInstallStrategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,cAAc,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,aAAa,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAKrC"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /**
3
+ * Plugin Install Strategy
4
+ *
5
+ * Routes plugin installation to the appropriate engine-specific installer:
6
+ * - cursor-cli: Uses pluginCopyInstall (file copy + MCP json merge)
7
+ * - claude-sdk: Uses pluginSymlink (symbolic links)
8
+ *
9
+ * This module provides a unified interface so callers don't need to
10
+ * know which engine is active.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.getPluginInstaller = getPluginInstaller;
14
+ exports.cleanBeforeInstall = cleanBeforeInstall;
15
+ exports.flushMCPConfig = flushMCPConfig;
16
+ const engineConfig_js_1 = require("../config/engineConfig.js");
17
+ const pluginSymlink_js_1 = require("./pluginSymlink.js");
18
+ const pluginCopyInstall_js_1 = require("./pluginCopyInstall.js");
19
+ /**
20
+ * Get the plugin installer for the current engine.
21
+ *
22
+ * - cursor-cli: returns pluginCopyInstall (file copy mode)
23
+ * - claude-sdk: returns pluginSymlink (symlink mode)
24
+ */
25
+ function getPluginInstaller() {
26
+ return (0, engineConfig_js_1.isCursorEngine)() ? pluginCopyInstall_js_1.pluginCopyInstall : pluginSymlink_js_1.pluginSymlink;
27
+ }
28
+ /**
29
+ * Clean target directories before a full marketplace install.
30
+ * Only applicable for cursor-cli engine (copy mode).
31
+ * For claude-sdk (symlink mode), this is a no-op.
32
+ */
33
+ function cleanBeforeInstall() {
34
+ if ((0, engineConfig_js_1.isCursorEngine)()) {
35
+ pluginCopyInstall_js_1.pluginCopyInstall.cleanBeforeInstall();
36
+ }
37
+ // claude-sdk symlink mode doesn't need pre-cleaning
38
+ }
39
+ /**
40
+ * Flush accumulated MCP config after all plugins are installed.
41
+ * Only applicable for cursor-cli engine (writes unified mcp.json).
42
+ * For claude-sdk, this is a no-op.
43
+ */
44
+ function flushMCPConfig() {
45
+ if ((0, engineConfig_js_1.isCursorEngine)()) {
46
+ pluginCopyInstall_js_1.pluginCopyInstall.flushMCPConfig();
47
+ }
48
+ // claude-sdk doesn't need unified MCP config
49
+ }
50
+ //# sourceMappingURL=pluginInstallStrategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginInstallStrategy.js","sourceRoot":"","sources":["../../src/services/pluginInstallStrategy.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAsBH,gDAEC;AAOD,gDAKC;AAOD,wCAKC;AA9CD,+DAA2D;AAC3D,yDAAmD;AACnD,iEAA2D;AAY3D;;;;;GAKG;AACH,SAAgB,kBAAkB;IAChC,OAAO,IAAA,gCAAc,GAAE,CAAC,CAAC,CAAC,wCAAiB,CAAC,CAAC,CAAC,gCAAa,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB;IAChC,IAAI,IAAA,gCAAc,GAAE,EAAE,CAAC;QACrB,wCAAiB,CAAC,kBAAkB,EAAE,CAAC;IACzC,CAAC;IACD,oDAAoD;AACtD,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc;IAC5B,IAAI,IAAA,gCAAc,GAAE,EAAE,CAAC;QACrB,wCAAiB,CAAC,cAAc,EAAE,CAAC;IACrC,CAAC;IACD,6CAA6C;AAC/C,CAAC"}
@@ -24,6 +24,16 @@ declare class PluginInstaller {
24
24
  * Sync an archive-based marketplace
25
25
  */
26
26
  private syncArchiveMarketplace;
27
+ /**
28
+ * Sync a local marketplace by re-copying from the source directory.
29
+ * Also re-installs plugins and re-imports agents.
30
+ */
31
+ private syncLocalMarketplace;
32
+ /**
33
+ * Check if a local marketplace source directory has changed compared to the installed copy.
34
+ * Compares marketplace.json version field and file modification times.
35
+ */
36
+ private checkLocalUpdates;
27
37
  /**
28
38
  * Remove a marketplace
29
39
  */
@@ -1 +1 @@
1
- {"version":3,"file":"pluginInstaller.d.ts","sourceRoot":"","sources":["../../src/services/pluginInstaller.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EAErB,4BAA4B,EAC7B,MAAM,kBAAkB,CAAC;AAwB1B;;;GAGG;AACH,cAAM,eAAe;IACnB;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAgEpF;;OAEG;IACG,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAiF9E;;OAEG;YACW,kBAAkB;IAShC;;OAEG;YACW,kBAAkB;IAmChC;;OAEG;YACW,sBAAsB;IAmCpC;;OAEG;IACG,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBlE;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAoDhF;;OAEG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqBpF;;OAEG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWjF;;OAEG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlF;;OAEG;YACW,gBAAgB;IAsB9B;;OAEG;YACW,oBAAoB;IAiBlC;;OAEG;YACW,aAAa;IA0B3B;;OAEG;YACW,eAAe;IAM7B;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;;OAGG;YACW,eAAe;IA2C7B;;;OAGG;YACW,yBAAyB;IA+DvC;;OAEG;YACW,uBAAuB;IAWrC;;OAEG;YACW,uBAAuB;IAerC;;OAEG;YACW,sBAAsB;IAgBpC;;OAEG;IACG,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,4BAA4B,CAAC;IA0FrF;;OAEG;YACW,eAAe;IAa7B;;OAEG;YACW,uBAAuB;IAerC;;OAEG;YACW,mBAAmB;IAsBjC;;OAEG;IACG,yBAAyB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAerD;AAED,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
1
+ {"version":3,"file":"pluginInstaller.d.ts","sourceRoot":"","sources":["../../src/services/pluginInstaller.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EAErB,4BAA4B,EAC7B,MAAM,kBAAkB,CAAC;AAwB1B;;;GAGG;AACH,cAAM,eAAe;IACnB;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA8DpF;;OAEG;IACG,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA0E9E;;OAEG;YACW,kBAAkB;IAShC;;OAEG;YACW,kBAAkB;IAmChC;;OAEG;YACW,sBAAsB;IAmCpC;;;OAGG;YACW,oBAAoB;IAmBlC;;;OAGG;YACW,iBAAiB;IAyC/B;;OAEG;IACG,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBlE;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAoDhF;;OAEG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqBpF;;OAEG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWjF;;OAEG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlF;;OAEG;YACW,gBAAgB;IAsB9B;;OAEG;YACW,oBAAoB;IAiBlC;;OAEG;YACW,aAAa;IA0B3B;;OAEG;YACW,eAAe;IAM7B;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;;OAGG;YACW,eAAe;IA2C7B;;;OAGG;YACW,yBAAyB;IA+DvC;;OAEG;YACW,uBAAuB;IAWrC;;OAEG;YACW,uBAAuB;IAerC;;OAEG;YACW,sBAAsB;IAgBpC;;OAEG;IACG,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,4BAA4B,CAAC;IAgGrF;;OAEG;YACW,eAAe;IAa7B;;OAEG;YACW,uBAAuB;IAerC;;OAEG;YACW,mBAAmB;IAsBjC;;OAEG;IACG,yBAAyB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAerD;AAED,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
@@ -43,7 +43,7 @@ const promises_1 = require("stream/promises");
43
43
  const fs_1 = require("fs");
44
44
  const pluginPaths_1 = require("./pluginPaths");
45
45
  const pluginParser_1 = require("./pluginParser");
46
- const pluginSymlink_1 = require("./pluginSymlink");
46
+ const pluginInstallStrategy_1 = require("./pluginInstallStrategy");
47
47
  const pluginScanner_1 = require("./pluginScanner");
48
48
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
49
49
  /**
@@ -77,9 +77,6 @@ class PluginInstaller {
77
77
  else if (type === 'cos') {
78
78
  await this.downloadFromCOS(source, marketplacePath, cosConfig);
79
79
  }
80
- else if (type === 'archive') {
81
- await this.downloadAndExtractArchive(source, marketplacePath);
82
- }
83
80
  // Save marketplace metadata for sync operations
84
81
  await this.saveMarketplaceMetadata(marketplacePath, {
85
82
  type,
@@ -139,16 +136,9 @@ class PluginInstaller {
139
136
  case 'cos':
140
137
  await this.syncCOSMarketplace(marketplacePath, metadata);
141
138
  break;
142
- case 'archive':
143
- await this.syncArchiveMarketplace(marketplacePath, metadata);
144
- break;
145
139
  case 'local':
146
- // Local marketplaces cannot be synced remotely
147
- return {
148
- success: false,
149
- error: 'Local marketplace cannot be synced. Use the original source path.',
150
- syncedAt: new Date().toISOString(),
151
- };
140
+ await this.syncLocalMarketplace(marketplacePath, metadata);
141
+ break;
152
142
  default:
153
143
  return {
154
144
  success: false,
@@ -267,6 +257,60 @@ class PluginInstaller {
267
257
  throw error;
268
258
  }
269
259
  }
260
+ /**
261
+ * Sync a local marketplace by re-copying from the source directory.
262
+ * Also re-installs plugins and re-imports agents.
263
+ */
264
+ async syncLocalMarketplace(marketplacePath, metadata) {
265
+ const sourcePath = metadata.source;
266
+ if (!sourcePath || !fs.existsSync(sourcePath)) {
267
+ throw new Error(`Source path does not exist or is not set: ${sourcePath}`);
268
+ }
269
+ // Preserve metadata before re-copy
270
+ const metadataBackup = { ...metadata, updatedAt: new Date().toISOString() };
271
+ // Re-copy from source (overwrites existing files)
272
+ await this.copyLocalMarketplace(sourcePath, marketplacePath);
273
+ // Restore metadata (copyLocalMarketplace may overwrite .agentstudio-metadata.json)
274
+ await this.saveMarketplaceMetadata(marketplacePath, metadataBackup);
275
+ console.log(`Synced local marketplace from ${sourcePath} to ${marketplacePath}`);
276
+ }
277
+ /**
278
+ * Check if a local marketplace source directory has changed compared to the installed copy.
279
+ * Compares marketplace.json version field and file modification times.
280
+ */
281
+ async checkLocalUpdates(marketplacePath, metadata) {
282
+ const sourcePath = metadata.source;
283
+ if (!sourcePath || !fs.existsSync(sourcePath)) {
284
+ return { hasUpdate: false };
285
+ }
286
+ // Strategy 1: Compare manifest versions
287
+ const localManifest = await this.loadMarketplaceManifest(marketplacePath);
288
+ const sourceManifestPath = path.join(sourcePath, '.claude-plugin', 'marketplace.json');
289
+ if (fs.existsSync(sourceManifestPath)) {
290
+ try {
291
+ const sourceContent = fs.readFileSync(sourceManifestPath, 'utf-8');
292
+ const sourceManifest = JSON.parse(sourceContent);
293
+ if (sourceManifest.version && localManifest?.version) {
294
+ if (sourceManifest.version !== localManifest.version) {
295
+ return { hasUpdate: true, remoteVersion: sourceManifest.version };
296
+ }
297
+ }
298
+ }
299
+ catch {
300
+ // Fall through to mtime check
301
+ }
302
+ }
303
+ // Strategy 2: Compare manifest file mtime
304
+ const localManifestPath = path.join(marketplacePath, '.claude-plugin', 'marketplace.json');
305
+ if (fs.existsSync(sourceManifestPath) && fs.existsSync(localManifestPath)) {
306
+ const sourceStat = fs.statSync(sourceManifestPath);
307
+ const localStat = fs.statSync(localManifestPath);
308
+ if (sourceStat.mtimeMs > localStat.mtimeMs) {
309
+ return { hasUpdate: true };
310
+ }
311
+ }
312
+ return { hasUpdate: false };
313
+ }
270
314
  /**
271
315
  * Remove a marketplace
272
316
  */
@@ -307,15 +351,15 @@ class PluginInstaller {
307
351
  // Parse plugin
308
352
  const parsedPlugin = await pluginParser_1.pluginParser.parsePlugin(pluginPath, marketplaceName, pluginName);
309
353
  // Check if plugin is valid
310
- const validation = await pluginParser_1.pluginParser.validatePlugin(pluginPath, pluginName);
354
+ const validation = await pluginParser_1.pluginParser.validatePlugin(pluginPath, pluginName, marketplaceName);
311
355
  if (!validation.valid) {
312
356
  return {
313
357
  success: false,
314
358
  error: `Plugin validation failed: ${validation.errors.join(', ')}`,
315
359
  };
316
360
  }
317
- // Create symlinks
318
- await pluginSymlink_1.pluginSymlink.createSymlinks(parsedPlugin);
361
+ // Install plugin components (symlinks for claude-sdk, file copy for cursor-cli)
362
+ await (0, pluginInstallStrategy_1.getPluginInstaller)().createSymlinks(parsedPlugin);
319
363
  // Get installed plugin info
320
364
  const installedPlugin = await pluginScanner_1.pluginScanner.scanPlugin(marketplaceName, pluginName);
321
365
  if (!installedPlugin) {
@@ -348,8 +392,8 @@ class PluginInstaller {
348
392
  }
349
393
  // Parse plugin to get components
350
394
  const parsedPlugin = await pluginParser_1.pluginParser.parsePlugin(pluginPath, marketplaceName, pluginName);
351
- // Remove symlinks
352
- await pluginSymlink_1.pluginSymlink.removeSymlinks(parsedPlugin);
395
+ // Remove installed plugin components
396
+ await (0, pluginInstallStrategy_1.getPluginInstaller)().removeSymlinks(parsedPlugin);
353
397
  return true;
354
398
  }
355
399
  catch (error) {
@@ -636,14 +680,20 @@ class PluginInstaller {
636
680
  case 'github':
637
681
  hasUpdate = await this.checkGitUpdates(marketplacePath);
638
682
  break;
639
- case 'cos':
640
- case 'archive':
683
+ case 'local': {
684
+ const localResult = await this.checkLocalUpdates(marketplacePath, metadata);
685
+ hasUpdate = localResult.hasUpdate;
686
+ remoteVersion = localResult.remoteVersion;
687
+ break;
688
+ }
689
+ case 'cos': {
641
690
  const remoteManifest = await this.fetchRemoteManifest(metadata.source);
642
691
  if (remoteManifest) {
643
692
  remoteVersion = remoteManifest.version;
644
693
  hasUpdate = remoteVersion !== localVersion;
645
694
  }
646
695
  break;
696
+ }
647
697
  }
648
698
  // Update metadata with check timestamp
649
699
  if (metadata.autoUpdate) {