opkg 0.9.2 → 0.9.4

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 (404) hide show
  1. package/.claude/agents/code-reviewer.md +171 -0
  2. package/.claude/commands/commit-push-pr.md +20 -0
  3. package/.claude/commands/{specs/read.md → read-specs.md} +1 -1
  4. package/.claude/commands/{specs/update.md → update-specs.md} +4 -0
  5. package/.claude/skills/code-review-excellence/SKILL.md +538 -0
  6. package/README.md +2 -2
  7. package/package.json +3 -1
  8. package/packages/cli/dist/add-IJAPFHIX.js +624 -0
  9. package/packages/cli/dist/add-IJAPFHIX.js.map +7 -0
  10. package/packages/cli/dist/add-LLUNFLJI.js +624 -0
  11. package/packages/cli/dist/add-LLUNFLJI.js.map +7 -0
  12. package/packages/cli/dist/add-U44SL3OR.js +624 -0
  13. package/packages/cli/dist/add-U44SL3OR.js.map +7 -0
  14. package/packages/cli/dist/chunk-23VBP5L6.js +371 -0
  15. package/packages/cli/dist/chunk-23VBP5L6.js.map +7 -0
  16. package/packages/cli/dist/chunk-2SVHLF5C.js +1419 -0
  17. package/packages/cli/dist/chunk-2SVHLF5C.js.map +7 -0
  18. package/packages/cli/dist/chunk-37256POU.js +99 -0
  19. package/packages/cli/dist/chunk-37256POU.js.map +7 -0
  20. package/packages/cli/dist/chunk-3PZRVA6O.js +196 -0
  21. package/packages/cli/dist/chunk-3PZRVA6O.js.map +7 -0
  22. package/packages/cli/dist/chunk-427DCURL.js +155 -0
  23. package/packages/cli/dist/chunk-427DCURL.js.map +7 -0
  24. package/packages/cli/dist/chunk-4B5HJLP2.js +48 -0
  25. package/packages/cli/dist/chunk-4B5HJLP2.js.map +7 -0
  26. package/packages/cli/dist/chunk-4OWT3YEG.js +413 -0
  27. package/packages/cli/dist/chunk-4OWT3YEG.js.map +7 -0
  28. package/packages/cli/dist/chunk-4RIBTBXI.js +568 -0
  29. package/packages/cli/dist/chunk-4RIBTBXI.js.map +7 -0
  30. package/packages/cli/dist/chunk-4X2EJHJN.js +63 -0
  31. package/packages/cli/dist/chunk-4X2EJHJN.js.map +7 -0
  32. package/packages/cli/dist/chunk-6CYW66HD.js +1136 -0
  33. package/packages/cli/dist/chunk-6CYW66HD.js.map +7 -0
  34. package/packages/cli/dist/chunk-6DITYAFA.js +172 -0
  35. package/packages/cli/dist/chunk-6DITYAFA.js.map +7 -0
  36. package/packages/cli/dist/chunk-7KEAKEVZ.js +568 -0
  37. package/packages/cli/dist/chunk-7KEAKEVZ.js.map +7 -0
  38. package/packages/cli/dist/chunk-ABFUD25D.js +61 -0
  39. package/packages/cli/dist/chunk-ABFUD25D.js.map +7 -0
  40. package/packages/cli/dist/chunk-AR7GJCG6.js +274 -0
  41. package/packages/cli/dist/chunk-AR7GJCG6.js.map +7 -0
  42. package/packages/cli/dist/chunk-AYTGQCXH.js +86 -0
  43. package/packages/cli/dist/chunk-AYTGQCXH.js.map +7 -0
  44. package/packages/cli/dist/chunk-BROJ6OUT.js +631 -0
  45. package/packages/cli/dist/chunk-BROJ6OUT.js.map +7 -0
  46. package/packages/cli/dist/chunk-BVVSU7QD.js +23 -0
  47. package/packages/cli/dist/chunk-BVVSU7QD.js.map +7 -0
  48. package/packages/cli/dist/chunk-C6FY55UP.js +108 -0
  49. package/packages/cli/dist/chunk-C6FY55UP.js.map +7 -0
  50. package/packages/cli/dist/chunk-CVA64SXK.js +1136 -0
  51. package/packages/cli/dist/chunk-CVA64SXK.js.map +7 -0
  52. package/packages/cli/dist/chunk-D3O7LY2Q.js +1151 -0
  53. package/packages/cli/dist/chunk-D3O7LY2Q.js.map +7 -0
  54. package/packages/cli/dist/chunk-D6LEPODL.js +413 -0
  55. package/packages/cli/dist/chunk-D6LEPODL.js.map +7 -0
  56. package/packages/cli/dist/chunk-DEC24S7E.js +186 -0
  57. package/packages/cli/dist/chunk-DEC24S7E.js.map +7 -0
  58. package/packages/cli/dist/chunk-FMVVJH5M.js +371 -0
  59. package/packages/cli/dist/chunk-FMVVJH5M.js.map +7 -0
  60. package/packages/cli/dist/chunk-GDVFS3YP.js +130 -0
  61. package/packages/cli/dist/chunk-GDVFS3YP.js.map +7 -0
  62. package/packages/cli/dist/chunk-GEP2G5HF.js +31 -0
  63. package/packages/cli/dist/chunk-GEP2G5HF.js.map +7 -0
  64. package/packages/cli/dist/chunk-GSWHZBT2.js +62 -0
  65. package/packages/cli/dist/chunk-GSWHZBT2.js.map +7 -0
  66. package/packages/cli/dist/chunk-HTYHJA3B.js +61 -0
  67. package/packages/cli/dist/chunk-HTYHJA3B.js.map +7 -0
  68. package/packages/cli/dist/chunk-HYKYECAE.js +222 -0
  69. package/packages/cli/dist/chunk-HYKYECAE.js.map +7 -0
  70. package/packages/cli/dist/chunk-I7FEAHB4.js +100 -0
  71. package/packages/cli/dist/chunk-I7FEAHB4.js.map +7 -0
  72. package/packages/cli/dist/chunk-IHVZ5AUJ.js +107 -0
  73. package/packages/cli/dist/chunk-IHVZ5AUJ.js.map +7 -0
  74. package/packages/cli/dist/chunk-KI7FDU3H.js +99 -0
  75. package/packages/cli/dist/chunk-KI7FDU3H.js.map +7 -0
  76. package/packages/cli/dist/chunk-L5GRJQBS.js +32 -0
  77. package/packages/cli/dist/chunk-L5GRJQBS.js.map +7 -0
  78. package/packages/cli/dist/chunk-LHEAUDJL.js +302 -0
  79. package/packages/cli/dist/chunk-LHEAUDJL.js.map +7 -0
  80. package/packages/cli/dist/chunk-MIURCESJ.js +48 -0
  81. package/packages/cli/dist/chunk-MIURCESJ.js.map +7 -0
  82. package/packages/cli/dist/chunk-N43IXOND.js +732 -0
  83. package/packages/cli/dist/chunk-N43IXOND.js.map +7 -0
  84. package/packages/cli/dist/chunk-OUZRMGPV.js +274 -0
  85. package/packages/cli/dist/chunk-OUZRMGPV.js.map +7 -0
  86. package/packages/cli/dist/chunk-PSQXKAL4.js +371 -0
  87. package/packages/cli/dist/chunk-PSQXKAL4.js.map +7 -0
  88. package/packages/cli/dist/chunk-PUDRKDVZ.js +1419 -0
  89. package/packages/cli/dist/chunk-PUDRKDVZ.js.map +7 -0
  90. package/packages/cli/dist/chunk-RAKMX654.js +631 -0
  91. package/packages/cli/dist/chunk-RAKMX654.js.map +7 -0
  92. package/packages/cli/dist/chunk-RSFLK2TP.js +195 -0
  93. package/packages/cli/dist/chunk-RSFLK2TP.js.map +7 -0
  94. package/packages/cli/dist/chunk-S26PR2BS.js +99 -0
  95. package/packages/cli/dist/chunk-S26PR2BS.js.map +7 -0
  96. package/packages/cli/dist/chunk-U7FW7SXX.js +568 -0
  97. package/packages/cli/dist/chunk-U7FW7SXX.js.map +7 -0
  98. package/packages/cli/dist/chunk-VKM6K5TN.js +413 -0
  99. package/packages/cli/dist/chunk-VKM6K5TN.js.map +7 -0
  100. package/packages/cli/dist/chunk-VKNJG4JN.js +253 -0
  101. package/packages/cli/dist/chunk-VKNJG4JN.js.map +7 -0
  102. package/packages/cli/dist/chunk-VQ2KY6CK.js +113 -0
  103. package/packages/cli/dist/chunk-VQ2KY6CK.js.map +7 -0
  104. package/packages/cli/dist/chunk-VQDTXLOX.js +1312 -0
  105. package/packages/cli/dist/chunk-VQDTXLOX.js.map +7 -0
  106. package/packages/cli/dist/chunk-VXNS3X5O.js +60 -0
  107. package/packages/cli/dist/chunk-VXNS3X5O.js.map +7 -0
  108. package/packages/cli/dist/chunk-WF7H2YDU.js +376 -0
  109. package/packages/cli/dist/chunk-WF7H2YDU.js.map +7 -0
  110. package/packages/cli/dist/chunk-WNRXZLWW.js +266 -0
  111. package/packages/cli/dist/chunk-WNRXZLWW.js.map +7 -0
  112. package/packages/cli/dist/chunk-WT4VVCXM.js +1121 -0
  113. package/packages/cli/dist/chunk-WT4VVCXM.js.map +7 -0
  114. package/packages/cli/dist/configure-3AZUMDJZ.js +107 -0
  115. package/packages/cli/dist/configure-3AZUMDJZ.js.map +7 -0
  116. package/packages/cli/dist/configure-D722JQOD.js +107 -0
  117. package/packages/cli/dist/configure-D722JQOD.js.map +7 -0
  118. package/packages/cli/dist/configure-IU5H7XD6.js +107 -0
  119. package/packages/cli/dist/configure-IU5H7XD6.js.map +7 -0
  120. package/packages/cli/dist/file-format-detector-PXCIAKTK.js +22 -0
  121. package/packages/cli/dist/file-format-detector-PXCIAKTK.js.map +7 -0
  122. package/packages/cli/dist/index.js +17 -17
  123. package/packages/cli/dist/install-EZNWMLJR.js +7581 -0
  124. package/packages/cli/dist/install-EZNWMLJR.js.map +7 -0
  125. package/packages/cli/dist/install-F5ANFUBX.js +7577 -0
  126. package/packages/cli/dist/install-F5ANFUBX.js.map +7 -0
  127. package/packages/cli/dist/install-JSXEPPC2.js +7104 -0
  128. package/packages/cli/dist/install-JSXEPPC2.js.map +7 -0
  129. package/packages/cli/dist/install-QHEBX7JH.js +7101 -0
  130. package/packages/cli/dist/install-QHEBX7JH.js.map +7 -0
  131. package/packages/cli/dist/list-DMOUATYI.js +327 -0
  132. package/packages/cli/dist/list-DMOUATYI.js.map +7 -0
  133. package/packages/cli/dist/list-UESSCB7Y.js +327 -0
  134. package/packages/cli/dist/list-UESSCB7Y.js.map +7 -0
  135. package/packages/cli/dist/list-XR7RSJFS.js +327 -0
  136. package/packages/cli/dist/list-XR7RSJFS.js.map +7 -0
  137. package/packages/cli/dist/login-EYZ2SOYZ.js +150 -0
  138. package/packages/cli/dist/login-EYZ2SOYZ.js.map +7 -0
  139. package/packages/cli/dist/login-JWCSTAEU.js +150 -0
  140. package/packages/cli/dist/login-JWCSTAEU.js.map +7 -0
  141. package/packages/cli/dist/login-NRKHXZKM.js +150 -0
  142. package/packages/cli/dist/login-NRKHXZKM.js.map +7 -0
  143. package/packages/cli/dist/logout-HDMYRXIE.js +40 -0
  144. package/packages/cli/dist/logout-HDMYRXIE.js.map +7 -0
  145. package/packages/cli/dist/logout-SYHXCVCQ.js +40 -0
  146. package/packages/cli/dist/logout-SYHXCVCQ.js.map +7 -0
  147. package/packages/cli/dist/logout-X3XUUOH5.js +40 -0
  148. package/packages/cli/dist/logout-X3XUUOH5.js.map +7 -0
  149. package/packages/cli/dist/new-3LTFKDTQ.js +277 -0
  150. package/packages/cli/dist/new-3LTFKDTQ.js.map +7 -0
  151. package/packages/cli/dist/new-F46OSD72.js +277 -0
  152. package/packages/cli/dist/new-F46OSD72.js.map +7 -0
  153. package/packages/cli/dist/new-OPCCLNL2.js +277 -0
  154. package/packages/cli/dist/new-OPCCLNL2.js.map +7 -0
  155. package/packages/cli/dist/package-marker-detector-T5O5YD2E.js +80 -0
  156. package/packages/cli/dist/package-marker-detector-T5O5YD2E.js.map +7 -0
  157. package/packages/cli/dist/package-yml-QWZIJDYU.js +16 -0
  158. package/packages/cli/dist/package-yml-QWZIJDYU.js.map +7 -0
  159. package/packages/cli/dist/plugin-naming-YP2I4NPA.js +29 -0
  160. package/packages/cli/dist/plugin-naming-YP2I4NPA.js.map +7 -0
  161. package/packages/cli/dist/publish-4H43PCSG.js +619 -0
  162. package/packages/cli/dist/publish-4H43PCSG.js.map +7 -0
  163. package/packages/cli/dist/publish-RULKLNUX.js +619 -0
  164. package/packages/cli/dist/publish-RULKLNUX.js.map +7 -0
  165. package/packages/cli/dist/publish-URWY2P3E.js +619 -0
  166. package/packages/cli/dist/publish-URWY2P3E.js.map +7 -0
  167. package/packages/cli/dist/remove-BD52BHR2.js +542 -0
  168. package/packages/cli/dist/remove-BD52BHR2.js.map +7 -0
  169. package/packages/cli/dist/remove-G5NRC7LD.js +542 -0
  170. package/packages/cli/dist/remove-G5NRC7LD.js.map +7 -0
  171. package/packages/cli/dist/remove-TC3FQUYQ.js +542 -0
  172. package/packages/cli/dist/remove-TC3FQUYQ.js.map +7 -0
  173. package/packages/cli/dist/resource-discoverer-4X4RY43E.js +17 -0
  174. package/packages/cli/dist/resource-discoverer-4X4RY43E.js.map +7 -0
  175. package/packages/cli/dist/save-24TESYKI.js +1728 -0
  176. package/packages/cli/dist/save-24TESYKI.js.map +7 -0
  177. package/packages/cli/dist/save-N3QWF2WN.js +1728 -0
  178. package/packages/cli/dist/save-N3QWF2WN.js.map +7 -0
  179. package/packages/cli/dist/save-P2U67DTV.js +1728 -0
  180. package/packages/cli/dist/save-P2U67DTV.js.map +7 -0
  181. package/packages/cli/dist/search-ABROK3UO.js +157 -0
  182. package/packages/cli/dist/search-ABROK3UO.js.map +7 -0
  183. package/packages/cli/dist/search-WVFXFNAV.js +157 -0
  184. package/packages/cli/dist/search-WVFXFNAV.js.map +7 -0
  185. package/packages/cli/dist/search-YQN2Q2SO.js +157 -0
  186. package/packages/cli/dist/search-YQN2Q2SO.js.map +7 -0
  187. package/packages/cli/dist/set-DCWF73F6.js +251 -0
  188. package/packages/cli/dist/set-DCWF73F6.js.map +7 -0
  189. package/packages/cli/dist/set-GJEG2F6Y.js +251 -0
  190. package/packages/cli/dist/set-GJEG2F6Y.js.map +7 -0
  191. package/packages/cli/dist/set-NGM2FIKF.js +251 -0
  192. package/packages/cli/dist/set-NGM2FIKF.js.map +7 -0
  193. package/packages/cli/dist/uninstall-3CJQMTYH.js +539 -0
  194. package/packages/cli/dist/uninstall-3CJQMTYH.js.map +7 -0
  195. package/packages/cli/dist/uninstall-Q3CP4UN5.js +539 -0
  196. package/packages/cli/dist/uninstall-Q3CP4UN5.js.map +7 -0
  197. package/packages/cli/dist/uninstall-QU5OMEEC.js +539 -0
  198. package/packages/cli/dist/uninstall-QU5OMEEC.js.map +7 -0
  199. package/packages/cli/dist/unpublish-GHJQYC4S.js +245 -0
  200. package/packages/cli/dist/unpublish-GHJQYC4S.js.map +7 -0
  201. package/packages/cli/dist/unpublish-L2CYMK4B.js +245 -0
  202. package/packages/cli/dist/unpublish-L2CYMK4B.js.map +7 -0
  203. package/packages/cli/dist/unpublish-VBTNTMS5.js +245 -0
  204. package/packages/cli/dist/unpublish-VBTNTMS5.js.map +7 -0
  205. package/packages/cli/dist/view-MXRBMXOG.js +488 -0
  206. package/packages/cli/dist/view-MXRBMXOG.js.map +7 -0
  207. package/packages/cli/dist/view-NMND7SAW.js +488 -0
  208. package/packages/cli/dist/view-NMND7SAW.js.map +7 -0
  209. package/packages/cli/dist/view-RPQRDSYB.js +488 -0
  210. package/packages/cli/dist/view-RPQRDSYB.js.map +7 -0
  211. package/packages/cli/package.json +2 -0
  212. package/packages/core/dist/constants/index.d.ts +9 -0
  213. package/packages/core/dist/constants/index.d.ts.map +1 -1
  214. package/packages/core/dist/constants/index.js +12 -0
  215. package/packages/core/dist/constants/index.js.map +1 -1
  216. package/packages/core/dist/core/dependency-resolver/index.d.ts +2 -10
  217. package/packages/core/dist/core/dependency-resolver/index.d.ts.map +1 -1
  218. package/packages/core/dist/core/dependency-resolver/index.js +3 -14
  219. package/packages/core/dist/core/dependency-resolver/index.js.map +1 -1
  220. package/packages/core/dist/core/install/base-detector.d.ts +2 -1
  221. package/packages/core/dist/core/install/base-detector.d.ts.map +1 -1
  222. package/packages/core/dist/core/install/base-detector.js +54 -1
  223. package/packages/core/dist/core/install/base-detector.js.map +1 -1
  224. package/packages/core/dist/core/install/conflicts/file-conflict-resolver.d.ts +7 -5
  225. package/packages/core/dist/core/install/conflicts/file-conflict-resolver.d.ts.map +1 -1
  226. package/packages/core/dist/core/install/conflicts/file-conflict-resolver.js +25 -9
  227. package/packages/core/dist/core/install/conflicts/file-conflict-resolver.js.map +1 -1
  228. package/packages/core/dist/core/install/flow-index-installer.d.ts +2 -1
  229. package/packages/core/dist/core/install/flow-index-installer.d.ts.map +1 -1
  230. package/packages/core/dist/core/install/flow-index-installer.js +19 -4
  231. package/packages/core/dist/core/install/flow-index-installer.js.map +1 -1
  232. package/packages/core/dist/core/install/input-classifier-base.js +3 -3
  233. package/packages/core/dist/core/install/input-classifier-base.js.map +1 -1
  234. package/packages/core/dist/core/install/install-reporting.d.ts.map +1 -1
  235. package/packages/core/dist/core/install/install-reporting.js +7 -9
  236. package/packages/core/dist/core/install/install-reporting.js.map +1 -1
  237. package/packages/core/dist/core/install/list-handler.d.ts.map +1 -1
  238. package/packages/core/dist/core/install/list-handler.js +3 -0
  239. package/packages/core/dist/core/install/list-handler.js.map +1 -1
  240. package/packages/core/dist/core/install/marketplace-handler.d.ts.map +1 -1
  241. package/packages/core/dist/core/install/marketplace-handler.js.map +1 -1
  242. package/packages/core/dist/core/install/operations/conflict-handler.d.ts +2 -1
  243. package/packages/core/dist/core/install/operations/conflict-handler.d.ts.map +1 -1
  244. package/packages/core/dist/core/install/operations/conflict-handler.js +2 -2
  245. package/packages/core/dist/core/install/operations/conflict-handler.js.map +1 -1
  246. package/packages/core/dist/core/install/operations/installation-executor.d.ts +3 -0
  247. package/packages/core/dist/core/install/operations/installation-executor.d.ts.map +1 -1
  248. package/packages/core/dist/core/install/operations/installation-executor.js +39 -22
  249. package/packages/core/dist/core/install/operations/installation-executor.js.map +1 -1
  250. package/packages/core/dist/core/install/orchestrator/orchestrator.d.ts +7 -3
  251. package/packages/core/dist/core/install/orchestrator/orchestrator.d.ts.map +1 -1
  252. package/packages/core/dist/core/install/orchestrator/orchestrator.js +193 -93
  253. package/packages/core/dist/core/install/orchestrator/orchestrator.js.map +1 -1
  254. package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.d.ts +1 -0
  255. package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.d.ts.map +1 -1
  256. package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.js +11 -24
  257. package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.js.map +1 -1
  258. package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.d.ts +2 -0
  259. package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.d.ts.map +1 -1
  260. package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.js +14 -14
  261. package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.js.map +1 -1
  262. package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.d.ts +7 -0
  263. package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.d.ts.map +1 -1
  264. package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.js +28 -0
  265. package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.js.map +1 -1
  266. package/packages/core/dist/core/install/orchestrator/types.d.ts +2 -0
  267. package/packages/core/dist/core/install/orchestrator/types.d.ts.map +1 -1
  268. package/packages/core/dist/core/install/path-package-loader.d.ts.map +1 -1
  269. package/packages/core/dist/core/install/path-package-loader.js +20 -1
  270. package/packages/core/dist/core/install/path-package-loader.js.map +1 -1
  271. package/packages/core/dist/core/install/platform-resolution.d.ts +3 -0
  272. package/packages/core/dist/core/install/platform-resolution.d.ts.map +1 -1
  273. package/packages/core/dist/core/install/platform-resolution.js +5 -2
  274. package/packages/core/dist/core/install/platform-resolution.js.map +1 -1
  275. package/packages/core/dist/core/install/preprocessing/context-population.d.ts +18 -0
  276. package/packages/core/dist/core/install/preprocessing/context-population.d.ts.map +1 -0
  277. package/packages/core/dist/core/install/preprocessing/context-population.js +36 -0
  278. package/packages/core/dist/core/install/preprocessing/context-population.js.map +1 -0
  279. package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.d.ts +23 -0
  280. package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.d.ts.map +1 -1
  281. package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.js +44 -0
  282. package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.js.map +1 -1
  283. package/packages/core/dist/core/install/sources/git-source.d.ts.map +1 -1
  284. package/packages/core/dist/core/install/sources/git-source.js +67 -4
  285. package/packages/core/dist/core/install/sources/git-source.js.map +1 -1
  286. package/packages/core/dist/core/install/sources/path-source.d.ts.map +1 -1
  287. package/packages/core/dist/core/install/sources/path-source.js +8 -0
  288. package/packages/core/dist/core/install/sources/path-source.js.map +1 -1
  289. package/packages/core/dist/core/install/strategies/flow-based-strategy.d.ts.map +1 -1
  290. package/packages/core/dist/core/install/strategies/flow-based-strategy.js +12 -5
  291. package/packages/core/dist/core/install/strategies/flow-based-strategy.js.map +1 -1
  292. package/packages/core/dist/core/install/strategies/types.d.ts +11 -1
  293. package/packages/core/dist/core/install/strategies/types.d.ts.map +1 -1
  294. package/packages/core/dist/core/install/unified/context-builders.d.ts +5 -0
  295. package/packages/core/dist/core/install/unified/context-builders.d.ts.map +1 -1
  296. package/packages/core/dist/core/install/unified/context-builders.js +12 -0
  297. package/packages/core/dist/core/install/unified/context-builders.js.map +1 -1
  298. package/packages/core/dist/core/install/unified/context-helpers.d.ts +0 -4
  299. package/packages/core/dist/core/install/unified/context-helpers.d.ts.map +1 -1
  300. package/packages/core/dist/core/install/unified/context-helpers.js +0 -24
  301. package/packages/core/dist/core/install/unified/context-helpers.js.map +1 -1
  302. package/packages/core/dist/core/install/unified/index.d.ts +1 -1
  303. package/packages/core/dist/core/install/unified/index.d.ts.map +1 -1
  304. package/packages/core/dist/core/install/unified/index.js +1 -1
  305. package/packages/core/dist/core/install/unified/index.js.map +1 -1
  306. package/packages/core/dist/core/install/unified/multi-context-pipeline.d.ts +6 -0
  307. package/packages/core/dist/core/install/unified/multi-context-pipeline.d.ts.map +1 -1
  308. package/packages/core/dist/core/install/unified/multi-context-pipeline.js +11 -4
  309. package/packages/core/dist/core/install/unified/multi-context-pipeline.js.map +1 -1
  310. package/packages/core/dist/core/install/unified/phases/conflicts.d.ts.map +1 -1
  311. package/packages/core/dist/core/install/unified/phases/conflicts.js +1 -1
  312. package/packages/core/dist/core/install/unified/phases/conflicts.js.map +1 -1
  313. package/packages/core/dist/core/install/unified/phases/execute.d.ts.map +1 -1
  314. package/packages/core/dist/core/install/unified/phases/execute.js +5 -5
  315. package/packages/core/dist/core/install/unified/phases/execute.js.map +1 -1
  316. package/packages/core/dist/core/install/unified/phases/load-package.js +3 -3
  317. package/packages/core/dist/core/install/unified/phases/load-package.js.map +1 -1
  318. package/packages/core/dist/core/install/unified/phases/report.js +1 -1
  319. package/packages/core/dist/core/install/unified/phases/report.js.map +1 -1
  320. package/packages/core/dist/core/install/unified/pipeline.d.ts.map +1 -1
  321. package/packages/core/dist/core/install/unified/pipeline.js +7 -10
  322. package/packages/core/dist/core/install/unified/pipeline.js.map +1 -1
  323. package/packages/core/dist/core/install/wave-resolver/content-root-cache.d.ts +24 -0
  324. package/packages/core/dist/core/install/wave-resolver/content-root-cache.d.ts.map +1 -0
  325. package/packages/core/dist/core/install/wave-resolver/content-root-cache.js +71 -0
  326. package/packages/core/dist/core/install/wave-resolver/content-root-cache.js.map +1 -0
  327. package/packages/core/dist/core/install/wave-resolver/context-builder.d.ts +39 -0
  328. package/packages/core/dist/core/install/wave-resolver/context-builder.d.ts.map +1 -0
  329. package/packages/core/dist/core/install/wave-resolver/context-builder.js +148 -0
  330. package/packages/core/dist/core/install/wave-resolver/context-builder.js.map +1 -0
  331. package/packages/core/dist/core/install/wave-resolver/fetcher.d.ts +49 -0
  332. package/packages/core/dist/core/install/wave-resolver/fetcher.d.ts.map +1 -0
  333. package/packages/core/dist/core/install/wave-resolver/fetcher.js +221 -0
  334. package/packages/core/dist/core/install/wave-resolver/fetcher.js.map +1 -0
  335. package/packages/core/dist/core/install/wave-resolver/index-updater.d.ts +23 -0
  336. package/packages/core/dist/core/install/wave-resolver/index-updater.d.ts.map +1 -0
  337. package/packages/core/dist/core/install/wave-resolver/index-updater.js +87 -0
  338. package/packages/core/dist/core/install/wave-resolver/index-updater.js.map +1 -0
  339. package/packages/core/dist/core/install/wave-resolver/index-write-collector.d.ts +101 -0
  340. package/packages/core/dist/core/install/wave-resolver/index-write-collector.d.ts.map +1 -0
  341. package/packages/core/dist/core/install/wave-resolver/index-write-collector.js +194 -0
  342. package/packages/core/dist/core/install/wave-resolver/index-write-collector.js.map +1 -0
  343. package/packages/core/dist/core/install/wave-resolver/index.d.ts +17 -0
  344. package/packages/core/dist/core/install/wave-resolver/index.d.ts.map +1 -0
  345. package/packages/core/dist/core/install/wave-resolver/index.js +16 -0
  346. package/packages/core/dist/core/install/wave-resolver/index.js.map +1 -0
  347. package/packages/core/dist/core/install/wave-resolver/manifest-reader.d.ts +34 -0
  348. package/packages/core/dist/core/install/wave-resolver/manifest-reader.d.ts.map +1 -0
  349. package/packages/core/dist/core/install/wave-resolver/manifest-reader.js +112 -0
  350. package/packages/core/dist/core/install/wave-resolver/manifest-reader.js.map +1 -0
  351. package/packages/core/dist/core/install/wave-resolver/types.d.ts +210 -0
  352. package/packages/core/dist/core/install/wave-resolver/types.d.ts.map +1 -0
  353. package/packages/core/dist/core/install/wave-resolver/types.js +6 -0
  354. package/packages/core/dist/core/install/wave-resolver/types.js.map +1 -0
  355. package/packages/core/dist/core/install/wave-resolver/version-solver.d.ts +65 -0
  356. package/packages/core/dist/core/install/wave-resolver/version-solver.d.ts.map +1 -0
  357. package/packages/core/dist/core/install/wave-resolver/version-solver.js +166 -0
  358. package/packages/core/dist/core/install/wave-resolver/version-solver.js.map +1 -0
  359. package/packages/core/dist/core/install/wave-resolver/wave-engine.d.ts +16 -0
  360. package/packages/core/dist/core/install/wave-resolver/wave-engine.d.ts.map +1 -0
  361. package/packages/core/dist/core/install/wave-resolver/wave-engine.js +337 -0
  362. package/packages/core/dist/core/install/wave-resolver/wave-engine.js.map +1 -0
  363. package/packages/core/dist/core/install/wave-resolver/wave-installer.d.ts +50 -0
  364. package/packages/core/dist/core/install/wave-resolver/wave-installer.d.ts.map +1 -0
  365. package/packages/core/dist/core/install/wave-resolver/wave-installer.js +246 -0
  366. package/packages/core/dist/core/install/wave-resolver/wave-installer.js.map +1 -0
  367. package/packages/core/dist/core/ports/buffered-output.d.ts +36 -0
  368. package/packages/core/dist/core/ports/buffered-output.d.ts.map +1 -0
  369. package/packages/core/dist/core/ports/buffered-output.js +89 -0
  370. package/packages/core/dist/core/ports/buffered-output.js.map +1 -0
  371. package/packages/core/dist/core/ports/resolve.d.ts +0 -13
  372. package/packages/core/dist/core/ports/resolve.d.ts.map +1 -1
  373. package/packages/core/dist/core/ports/resolve.js +0 -28
  374. package/packages/core/dist/core/ports/resolve.js.map +1 -1
  375. package/packages/core/dist/core/remove/removal-confirmation.d.ts +4 -1
  376. package/packages/core/dist/core/remove/removal-confirmation.d.ts.map +1 -1
  377. package/packages/core/dist/core/remove/removal-confirmation.js +5 -4
  378. package/packages/core/dist/core/remove/removal-confirmation.js.map +1 -1
  379. package/packages/core/dist/core/remove/remove-from-source-pipeline.d.ts.map +1 -1
  380. package/packages/core/dist/core/remove/remove-from-source-pipeline.js +1 -10
  381. package/packages/core/dist/core/remove/remove-from-source-pipeline.js.map +1 -1
  382. package/packages/core/dist/core/uninstall/uninstall-executor.js +1 -1
  383. package/packages/core/dist/core/uninstall/uninstall-executor.js.map +1 -1
  384. package/packages/core/dist/core/uninstall/uninstall-reporter.d.ts +2 -2
  385. package/packages/core/dist/core/uninstall/uninstall-reporter.d.ts.map +1 -1
  386. package/packages/core/dist/core/uninstall/uninstall-reporter.js +4 -4
  387. package/packages/core/dist/core/uninstall/uninstall-reporter.js.map +1 -1
  388. package/packages/core/dist/index.d.ts +1 -1
  389. package/packages/core/dist/index.d.ts.map +1 -1
  390. package/packages/core/dist/types/execution-context.d.ts +40 -10
  391. package/packages/core/dist/types/execution-context.d.ts.map +1 -1
  392. package/packages/core/dist/utils/concurrency-pool.d.ts +34 -0
  393. package/packages/core/dist/utils/concurrency-pool.d.ts.map +1 -0
  394. package/packages/core/dist/utils/concurrency-pool.js +58 -0
  395. package/packages/core/dist/utils/concurrency-pool.js.map +1 -0
  396. package/packages/core/dist/utils/plugin-naming.d.ts +11 -3
  397. package/packages/core/dist/utils/plugin-naming.d.ts.map +1 -1
  398. package/packages/core/dist/utils/plugin-naming.js +27 -7
  399. package/packages/core/dist/utils/plugin-naming.js.map +1 -1
  400. package/plans/wave-resolver.md +254 -0
  401. package/.claude/agents/essentials/code-simplifier.md +0 -52
  402. package/.claude/commands/essentials/cleanup.md +0 -1
  403. package/.claude/commands/essentials/review.md +0 -8
  404. package/.claude/commands/git/commit.md +0 -5
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../core/src/core/list/view-metadata.ts", "../../core/src/core/list/list-printers.ts", "../../core/src/core/resources/resource-namespace.ts", "../../core/src/core/list/list-pipeline.ts", "../../core/src/utils/entity-detector.ts"],
4
+ "sourcesContent": ["/**\n * Metadata extraction for view command output.\n * Separated to avoid circular dependencies between list-printers and remote-list-resolver.\n */\n\nimport type { PackageYml, PackageRepository } from '../../types/index.js';\n\nexport interface ViewMetadataEntry {\n key: string;\n value: string | boolean | string[];\n}\n\n/** Extract recognized manifest metadata for display (excludes dependencies) */\nexport function extractMetadataFromManifest(manifest: Partial<PackageYml>): ViewMetadataEntry[] {\n const entries: ViewMetadataEntry[] = [];\n const push = (key: string, value: unknown) => {\n if (value !== undefined && value !== null && value !== '') {\n entries.push({ key, value: value as string | boolean | string[] });\n }\n };\n push('name', manifest.name);\n push('version', manifest.version);\n push('description', manifest.description);\n push('keywords', manifest.keywords);\n push('author', manifest.author);\n push('license', manifest.license);\n push('homepage', manifest.homepage);\n if (manifest.repository) {\n const repo = manifest.repository as PackageRepository;\n const repoStr = repo.directory ? `${repo.url} (${repo.directory})` : repo.url;\n push('repository', repoStr);\n }\n if (manifest.private === true) push('private', true);\n if (manifest.partial === true) push('partial', true);\n return entries;\n}\n", "import type { ListPackageReport, ListTreeNode } from './list-pipeline.js';\nimport { flattenResourceGroups, renderFlatResourceList, getChildPrefix, type TreeRenderConfig, type EnhancedFileMapping, type EnhancedResourceGroup, type ResourceScope } from './list-tree-renderer.js';\nimport { formatScopeBadge } from '../../utils/formatters.js';\nimport type { ScopeResult, HeaderInfo } from './scope-data-collector.js';\nimport type { ViewMetadataEntry } from './view-metadata.js';\nimport type { OutputPort } from '../ports/output.js';\nimport { resolveOutput } from '../ports/resolve.js';\n\nexport type { ViewMetadataEntry } from './view-metadata.js';\nexport { extractMetadataFromManifest } from './view-metadata.js';\n\nexport function printMetadataSection(metadata: ViewMetadataEntry[], output?: OutputPort): void {\n const out = output ?? resolveOutput();\n out.info(sectionHeader('Metadata', metadata.length));\n metadata.forEach((entry) => {\n const valueStr = Array.isArray(entry.value)\n ? entry.value.join(', ')\n : String(entry.value);\n out.info(`${dim(entry.key + ':')} ${valueStr}`);\n });\n}\n\n// ---------------------------------------------------------------------------\n// ANSI helpers\n// ---------------------------------------------------------------------------\n\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\nconst RED = '\\x1b[31m';\nconst CYAN = '\\x1b[36m';\n\nexport function dim(text: string): string {\n return `${DIM}${text}${RESET}`;\n}\n\nexport function cyan(text: string): string {\n return `${CYAN}${text}${RESET}`;\n}\n\nfunction red(text: string): string {\n return `${RED}${text}${RESET}`;\n}\n\nexport function sectionHeader(title: string, count: number): string {\n return `${cyan(`[${title}]`)} ${dim(`(${count})`)}`;\n}\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\nfunction formatPackageLine(pkg: ListPackageReport): string {\n const version = pkg.version && pkg.version !== '0.0.0' ? `@${pkg.version}` : '';\n\n let stateSuffix = '';\n if (pkg.state === 'missing') {\n stateSuffix = dim(' (missing)');\n }\n\n return `${pkg.name}${version}${stateSuffix}`;\n}\n\nfunction formatFilePath(file: EnhancedFileMapping): string {\n if (file.scope === 'global' && !file.target.startsWith('~')) {\n return `~/${file.target}`;\n }\n return file.target;\n}\n\n// ---------------------------------------------------------------------------\n// File and resource group printing\n// ---------------------------------------------------------------------------\n\nfunction printFileList(\n files: { source: string; target: string; exists: boolean }[],\n prefix: string,\n out: OutputPort\n): void {\n const sortedFiles = [...files].sort((a, b) => a.target.localeCompare(b.target));\n\n for (let i = 0; i < sortedFiles.length; i++) {\n const file = sortedFiles[i];\n const isLast = i === sortedFiles.length - 1;\n const connector = isLast ? '\u2514\u2500\u2500 ' : '\u251C\u2500\u2500 ';\n const label = file.exists\n ? dim(file.target)\n : `${dim(file.target)} ${red('[MISSING]')}`;\n out.info(`${prefix}${connector}${label}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Deps view\n// ---------------------------------------------------------------------------\n\ninterface DepsPackageEntry {\n report: ListPackageReport;\n children: ListTreeNode[];\n scopes: Set<ResourceScope>;\n}\n\nfunction printDepTreeNode(\n node: ListTreeNode,\n prefix: string,\n isLast: boolean,\n showFiles: boolean,\n out: OutputPort\n): void {\n const hasChildren = node.children.length > 0;\n const hasFiles = showFiles && node.report.fileList && node.report.fileList.length > 0;\n const hasBranches = hasChildren || hasFiles;\n\n const connector = isLast\n ? (hasBranches ? '\u2514\u2500\u252C ' : '\u2514\u2500\u2500 ')\n : (hasBranches ? '\u251C\u2500\u252C ' : '\u251C\u2500\u2500 ');\n const childPrefix = getChildPrefix(prefix, isLast);\n\n out.info(`${prefix}${connector}${formatPackageLine(node.report)}`);\n\n if (hasFiles) {\n printFileList(node.report.fileList!, childPrefix, out);\n }\n\n node.children.forEach((child, index) => {\n const isLastChild = index === node.children.length - 1;\n printDepTreeNode(child, childPrefix, isLastChild, showFiles, out);\n });\n}\n\nexport function printDepsView(\n results: Array<{ scope: ResourceScope; result: ScopeResult }>,\n showFiles: boolean,\n headerInfo?: HeaderInfo,\n output?: OutputPort\n): void {\n const out = output ?? resolveOutput();\n const packageMap = new Map<string, DepsPackageEntry>();\n\n for (const { scope, result } of results) {\n for (const node of result.tree) {\n const key = node.report.name;\n if (packageMap.has(key)) {\n packageMap.get(key)!.scopes.add(scope);\n } else {\n packageMap.set(key, {\n report: node.report,\n children: node.children,\n scopes: new Set([scope])\n });\n }\n }\n }\n\n if (packageMap.size === 0) {\n out.info(dim('No packages installed.'));\n return;\n }\n\n // Option 1: When workspace is the header, exclude it from the tree to avoid duplication.\n // Its files are shown under the header when -f is used.\n let workspaceEntry: DepsPackageEntry | undefined;\n if (headerInfo?.type === 'workspace' && headerInfo.name) {\n workspaceEntry = packageMap.get(headerInfo.name);\n if (workspaceEntry) {\n packageMap.delete(headerInfo.name);\n }\n }\n\n // Print header showing workspace/package name and path\n if (headerInfo) {\n const version = headerInfo.version ? `@${headerInfo.version}` : '';\n const typeTag = dim(`[${headerInfo.type}]`);\n out.info(`${headerInfo.name}${version} ${dim(`(${headerInfo.path})`)} ${typeTag}`);\n } else if (results.length > 0) {\n const firstResult = results[0].result;\n const version = firstResult.headerVersion ? `@${firstResult.headerVersion}` : '';\n const typeTag = dim(`[${firstResult.headerType}]`);\n out.info(`${firstResult.headerName}${version} ${dim(`(${firstResult.headerPath})`)} ${typeTag}`);\n }\n\n const entries = Array.from(packageMap.values())\n .sort((a, b) => a.report.name.localeCompare(b.report.name));\n\n out.info(sectionHeader('Dependencies', entries.length));\n\n // If workspace was excluded, show its files under the header when -f is used.\n // Use empty prefix so workspace files appear as siblings of dep entries.\n if (workspaceEntry && showFiles && workspaceEntry.report.fileList && workspaceEntry.report.fileList.length > 0) {\n printFileList(workspaceEntry.report.fileList, '', out);\n }\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n const isLast = i === entries.length - 1;\n const hasChildren = entry.children.length > 0;\n const hasFiles = showFiles && entry.report.fileList && entry.report.fileList.length > 0;\n const hasBranches = hasChildren || hasFiles;\n\n const scopeBadge = dim(formatScopeBadge(entry.scopes));\n const connector = isLast\n ? (hasBranches ? '\u2514\u2500\u252C ' : '\u2514\u2500\u2500 ')\n : (hasBranches ? '\u251C\u2500\u252C ' : '\u251C\u2500\u2500 ');\n const childPrefix = getChildPrefix('', isLast);\n\n out.info(`${connector}${formatPackageLine(entry.report)} ${scopeBadge}`);\n\n // Show flat file list for the package when -f is requested\n if (hasFiles) {\n printFileList(entry.report.fileList!, childPrefix, out);\n }\n\n for (let ci = 0; ci < entry.children.length; ci++) {\n const child = entry.children[ci];\n const isLastChild = ci === entry.children.length - 1;\n printDepTreeNode(child, childPrefix, isLastChild, showFiles, out);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Resources view (default)\n// ---------------------------------------------------------------------------\n\nexport function printResourcesView(\n groups: EnhancedResourceGroup[],\n showFiles: boolean,\n headerInfo?: HeaderInfo,\n output?: OutputPort\n): void {\n const out = output ?? resolveOutput();\n // Print header showing workspace/package name and path if provided\n if (headerInfo) {\n const version = headerInfo.version ? `@${headerInfo.version}` : '';\n const typeTag = dim(`[${headerInfo.type}]`);\n out.info(`${headerInfo.name}${version} ${dim(`(${headerInfo.path})`)} ${typeTag}`);\n }\n\n // Show package label only when listing workspace (not a specific package).\n // Temporarily disabled behind feature flag; set OPKG_LIST_SHOW_PACKAGE_LABELS=true to enable.\n const showPackageLabels =\n headerInfo?.type !== 'package' &&\n process.env.OPKG_LIST_SHOW_PACKAGE_LABELS === 'true';\n\n const config: TreeRenderConfig<EnhancedFileMapping> = {\n formatPath: (file) => formatFilePath(file),\n isMissing: (file) => file.status === 'missing',\n sortFiles: (a, b) => formatFilePath(a).localeCompare(formatFilePath(b)),\n getResourceBadge: (scopes) => scopes ? dim(formatScopeBadge(scopes)) : '',\n ...(showPackageLabels && {\n getResourcePackageLabels: (packages) => {\n if (!packages || packages.size === 0) return [];\n return Array.from(packages)\n .sort()\n .map((pkg) => dim(`(${pkg})`));\n }\n })\n };\n\n const flatResources = flattenResourceGroups(groups);\n out.info(sectionHeader('Installed', flatResources.length));\n renderFlatResourceList(flatResources, '', showFiles, config);\n}\n", "/**\n * Resource Namespace Module\n *\n * Single source of truth for deriving category/namespace from paths.\n * Used by list pipeline, scope merger, and future consumers.\n */\n\nimport { stripExtension } from './resource-naming.js';\nimport { getResourceTypeDef, toPluralKey, type ResourceTypeId } from './resource-registry.js';\nimport { stripPlatformSuffixFromFilename } from '../flows/platform-suffix-handler.js';\n\n/**\n * Extract the path segment under a category directory from a full path.\n * Handles both source keys (rules/foo.mdc) and workspace paths (.cursor/rules/foo.mdc).\n *\n * @param path - Normalized path (source key, target, or workspace path)\n * @param categoryDir - The category directory (e.g., 'rules', 'agents')\n * @returns Path under category, or null if category not found\n */\nexport function getPathUnderCategory(path: string, categoryDir: string): string | null {\n const normalized = path.replace(/\\\\/g, '/').replace(/\\/$/, '');\n const parts = normalized.split('/');\n\n const idx = parts.indexOf(categoryDir);\n if (idx < 0) return null;\n\n const remaining = parts.slice(idx + 1);\n return remaining.length > 0 ? remaining.join('/') : '';\n}\n\n/**\n * Derive the namespace (path under category with extension stripped from last segment).\n * - File-based: \"basics/custom-rules.mdc\" \u2192 \"basics/custom-rules\"\n * - Skill: \"my-skill/readme.md\" \u2192 \"my-skill\" (first segment, directory-based)\n *\n * @param pathUnderCategory - Path under the category directory\n * @param resourceType - Singular type: rule, agent, skill, etc.\n */\nfunction deriveNamespace(pathUnderCategory: string, resourceType: ResourceTypeId): string {\n if (!pathUnderCategory || pathUnderCategory === '') return 'unnamed';\n\n const parts = pathUnderCategory.split('/');\n\n if (resourceType === 'skill') {\n return parts[0] || 'unnamed';\n }\n\n // Strip platform suffix (e.g. git-manager.opencode.md -> git-manager.md) so platform-specific\n // variants group under the same resource\n const pathStripped = stripPlatformSuffixFromFilename(pathUnderCategory);\n const strippedParts = pathStripped.split('/');\n const lastSegment = strippedParts[strippedParts.length - 1] ?? '';\n const nameWithoutExt = stripExtension(lastSegment);\n\n if (strippedParts.length === 1) {\n return nameWithoutExt || lastSegment;\n }\n\n const subpath = strippedParts.slice(0, -1).join('/');\n return subpath ? `${subpath}/${nameWithoutExt}` : nameWithoutExt;\n}\n\n/**\n * Derive the full resource identifier (category/namespace) from a path.\n *\n * @param path - Source key, target path, or workspace path\n * @param resourceType - Singular type: rule, agent, skill, command, hook, mcp, other\n * @returns Full name like \"rules/custom-rules\", \"rules/basics/custom-rules\", \"agents/agent-creator\"\n */\nexport function deriveResourceFullName(path: string, resourceType: ResourceTypeId): string {\n const normalizedType = resourceType as ResourceTypeId;\n\n if (normalizedType === 'mcp') {\n return 'mcps/configs';\n }\n\n if (normalizedType === 'other') {\n return 'other';\n }\n\n const def = getResourceTypeDef(normalizedType);\n const categoryDir = def.dirName;\n\n if (!categoryDir) {\n return `other/${deriveNamespace(path, 'other')}`;\n }\n\n const pathUnder = getPathUnderCategory(path, categoryDir);\n if (pathUnder === null) {\n const pluralKey = toPluralKey(normalizedType);\n const fallback = path.replace(/\\\\/g, '/').split('/').pop() ?? 'unnamed';\n return `${pluralKey}/${stripExtension(fallback)}`;\n }\n\n const namespace = deriveNamespace(pathUnder, normalizedType);\n const pluralKey = toPluralKey(normalizedType);\n return `${pluralKey}/${namespace}`;\n}\n", "import path from 'path';\n\nimport type { CommandResult, ExecutionContext } from '../../types/index.js';\nimport { ValidationError } from '../../utils/errors.js';\nimport { getLocalOpenPackageDir, getLocalPackageYmlPath } from '../../utils/paths.js';\nimport { readWorkspaceIndex } from '../../utils/workspace-index-yml.js';\nimport { resolveDeclaredPath } from '../../utils/path-resolution.js';\nimport { exists } from '../../utils/fs.js';\nimport type { WorkspaceIndexPackage } from '../../types/workspace-index.js';\nimport { logger } from '../../utils/logger.js';\nimport { getTargetPath } from '../../utils/workspace-index-helpers.js';\nimport { parsePackageYml } from '../../utils/package-yml.js';\nimport { arePackageNamesEquivalent } from '../../utils/package-name.js';\nimport { scanUntrackedFiles, type UntrackedScanResult } from './untracked-files-scanner.js';\nimport { getWorkspaceIndexPath } from '../../utils/workspace-index-yml.js';\nimport { isPlatformId, getAllPlatforms, getPlatformDefinition } from '../platforms.js';\nimport { normalizePlatforms } from '../platform/platform-mapper.js';\nimport { DIR_TO_TYPE, RESOURCE_TYPE_ORDER, toPluralKey, type ResourceTypeId } from '../resources/resource-registry.js';\nimport { classifySourceKey } from '../resources/source-key-classifier.js';\nimport { deriveResourceFullName } from '../resources/resource-namespace.js';\nexport { classifySourceKey } from '../resources/source-key-classifier.js';\n\nexport type PackageSyncState = 'synced' | 'partial' | 'missing';\n\nexport interface ListFileMapping {\n source: string;\n target: string;\n exists: boolean;\n}\n\n/**\n * A single resource within a package (e.g., one rule, one agent, one skill)\n */\nexport interface ListResourceInfo {\n /** Display name (filename sans .md for files, directory name for skills) */\n name: string;\n /** Resource type: agent, skill, command, rule, hook, mcp, or 'other' for unrecognized */\n resourceType: string;\n /** Files belonging to this resource */\n files: ListFileMapping[];\n}\n\n/**\n * Resources grouped by type within a package\n */\nexport interface ListResourceGroup {\n /** Resource type label (e.g., 'rules', 'agents', 'skills') */\n resourceType: string;\n /** Individual resources of this type */\n resources: ListResourceInfo[];\n}\n\nexport interface ListPackageReport {\n name: string;\n version?: string;\n path: string;\n state: PackageSyncState;\n totalFiles: number;\n existingFiles: number;\n fileList?: ListFileMapping[];\n resourceGroups?: ListResourceGroup[];\n dependencies?: string[];\n}\n\nexport interface ListTreeNode {\n report: ListPackageReport;\n children: ListTreeNode[];\n}\n\nexport interface ListPipelineOptions {\n /** Include full file list for each package */\n includeFiles?: boolean;\n /** Build full recursive dependency tree */\n all?: boolean;\n /** Filter to tracked view only */\n tracked?: boolean;\n /** Filter to untracked view only */\n untracked?: boolean;\n /** Filter by platform names */\n platforms?: string[];\n}\n\nexport interface ListPipelineResult {\n packages: ListPackageReport[];\n tree?: ListTreeNode[];\n rootPackageNames?: string[];\n /** When a specific package is targeted, this contains its info for the header */\n targetPackage?: ListPackageReport;\n /** Total tracked files that exist on disk */\n trackedCount: number;\n /** Total tracked files that are missing on disk */\n missingCount: number;\n /** Total untracked files found */\n untrackedCount: number;\n /** Untracked files scan result */\n untrackedFiles?: UntrackedScanResult;\n}\n\n\n/**\n * Extract the root directory prefix from a `to` pattern string.\n * e.g. \".cursor/agents/x.md\" -> \".cursor\", \".config/opencode/agents/x.md\" -> \".config/opencode\"\n * Returns null for patterns without a dot-prefixed root dir.\n */\nfunction extractRootPrefixFromToPattern(pattern: string): string | null {\n const parts = pattern.replace(/\\\\/g, '/').split('/');\n if (parts.length < 2 || !parts[0].startsWith('.')) return null;\n const nonGlobParts = [];\n for (const part of parts) {\n if (part.includes('*') || part.includes('{')) break;\n nonGlobParts.push(part);\n }\n if (nonGlobParts.length < 2) return nonGlobParts.length === 1 ? nonGlobParts[0] : null;\n // For paths like \".config/opencode/agents/foo.md\", the root prefix is everything\n // up to but not including known resource type dirs or the filename.\n const resourceDirs = new Set(Object.keys(DIR_TO_TYPE));\n const prefixParts = [];\n for (const part of nonGlobParts) {\n if (resourceDirs.has(part)) break;\n if (part.includes('.') && part !== nonGlobParts[0]) break;\n prefixParts.push(part);\n }\n return prefixParts.length > 0 ? prefixParts.join('/') : null;\n}\n\n/**\n * Collect all `to` pattern strings from a flow, including $switch cases.\n */\nfunction collectToPatternsFromFlow(toField: unknown): string[] {\n if (typeof toField === 'string') return [toField];\n\n if (typeof toField === 'object' && toField !== null) {\n if ('$switch' in toField) {\n const sw = (toField as any).$switch;\n const patterns: string[] = [];\n for (const c of sw?.cases ?? []) {\n const v = c.value;\n if (typeof v === 'string') patterns.push(v);\n else if (typeof v === 'object' && v && 'pattern' in v) patterns.push(v.pattern);\n }\n const d = sw?.default;\n if (typeof d === 'string') patterns.push(d);\n else if (typeof d === 'object' && d && 'pattern' in d) patterns.push(d.pattern);\n return patterns;\n }\n if ('pattern' in toField && typeof (toField as any).pattern === 'string') {\n return [(toField as any).pattern];\n }\n }\n return [];\n}\n\n/**\n * Build a mapping from root directory prefixes to platform IDs.\n * Collects all root prefixes from every export flow `to` pattern (including $switch cases).\n * Cached per targetDir to avoid recomputing on every file.\n */\nconst rootDirCacheMap = new Map<string, Map<string, string>>();\n\nfunction getRootDirToPlatformMap(targetDir: string): Map<string, string> {\n const cached = rootDirCacheMap.get(targetDir);\n if (cached) return cached;\n\n const map = new Map<string, string>();\n for (const platform of getAllPlatforms({ includeDisabled: true }, targetDir)) {\n const definition = getPlatformDefinition(platform, targetDir);\n if (!definition.export) continue;\n for (const flow of definition.export) {\n for (const pattern of collectToPatternsFromFlow(flow.to)) {\n const prefix = extractRootPrefixFromToPattern(pattern);\n if (prefix && !map.has(prefix)) {\n map.set(prefix, platform);\n }\n }\n }\n }\n rootDirCacheMap.set(targetDir, map);\n return map;\n}\n\n/**\n * Extract platform from a target path by matching its root directory against\n * known platform root directories derived from export flows.\n * Returns null if the file is universal (no platform).\n *\n * @param targetPath - Target path relative to workspace (e.g., \".cursor/agents/foo.md\")\n * @param targetDir - Target directory for context and flow resolution\n * @returns Platform ID or null if universal\n */\nfunction extractPlatformFromPath(targetPath: string, targetDir: string): string | null {\n const normalized = targetPath.replace(/\\\\/g, '/');\n\n // Check if the path starts with a known platform root directory\n // Sort by longest prefix first so more-specific prefixes match before shorter ones\n const rootDirMap = getRootDirToPlatformMap(targetDir);\n const sortedEntries = [...rootDirMap.entries()].sort((a, b) => b[0].length - a[0].length);\n for (const [rootDir, platform] of sortedEntries) {\n if (normalized === rootDir || normalized.startsWith(rootDir + '/')) {\n return platform;\n }\n }\n\n // Fallback: Check for platform suffix in filename (e.g., mcp.cursor.jsonc, rule.claude.md)\n const parts = normalized.split('/');\n const filename = parts[parts.length - 1];\n const nameParts = filename.split('.');\n\n // Need at least 3 parts: name.platform.ext\n if (nameParts.length >= 3) {\n const possiblePlatform = nameParts[nameParts.length - 2];\n if (isPlatformId(possiblePlatform, targetDir)) {\n return possiblePlatform;\n }\n }\n\n // No platform detected - this is a universal file\n return null;\n}\n\n/**\n * Group file mappings into resource groups by analyzing source keys.\n *\n * For skills, all files sharing the same skills/<name>/ prefix are grouped into one resource.\n * For other types, each source key maps to one resource.\n */\nexport function groupFilesIntoResources(fileList: ListFileMapping[]): ListResourceGroup[] {\n // First pass: classify each file and group by resource identity\n const resourceMap = new Map<string, ListResourceInfo>();\n\n for (const file of fileList) {\n const { resourceType } = classifySourceKey(file.source);\n const fullName = deriveResourceFullName(file.source, resourceType);\n const key = fullName;\n\n if (!resourceMap.has(key)) {\n resourceMap.set(key, {\n name: fullName,\n resourceType,\n files: []\n });\n }\n resourceMap.get(key)!.files.push(file);\n }\n\n // Second pass: group resources by type\n const typeGroupMap = new Map<string, ListResourceInfo[]>();\n\n for (const resource of resourceMap.values()) {\n if (!typeGroupMap.has(resource.resourceType)) {\n typeGroupMap.set(resource.resourceType, []);\n }\n typeGroupMap.get(resource.resourceType)!.push(resource);\n }\n\n // Build final groups, sorted by type then by resource name\n const typeOrder = RESOURCE_TYPE_ORDER;\n const groups: ListResourceGroup[] = [];\n\n for (const type of typeOrder) {\n const resources = typeGroupMap.get(type);\n if (!resources || resources.length === 0) continue;\n\n // Sort resources by name\n resources.sort((a, b) => a.name.localeCompare(b.name));\n\n // Sort files within each resource by target path\n for (const resource of resources) {\n resource.files.sort((a, b) => a.target.localeCompare(b.target));\n }\n\n // Use plural form for group label\n const pluralLabel = toPluralKey(type as ResourceTypeId);\n groups.push({ resourceType: pluralLabel, resources });\n }\n\n // Handle any types not in typeOrder\n for (const [type, resources] of typeGroupMap) {\n if ((typeOrder as readonly string[]).includes(type)) continue;\n resources.sort((a, b) => a.name.localeCompare(b.name));\n for (const resource of resources) {\n resource.files.sort((a, b) => a.target.localeCompare(b.target));\n }\n groups.push({ resourceType: `${type}s`, resources });\n }\n\n return groups;\n}\n\n/**\n * Check package list status by verifying file existence\n * Does not compare content - only checks if expected files exist\n */\nasync function checkPackageStatus(\n targetDir: string,\n pkgName: string,\n entry: WorkspaceIndexPackage,\n includeFileList: boolean = false,\n platformsFilter?: string[]\n): Promise<ListPackageReport> {\n const totalTargets = entry.files\n ? Object.values(entry.files).reduce((s, arr) => s + (Array.isArray(arr) ? arr.length : 0), 0)\n : 0;\n const resolved = resolveDeclaredPath(entry.path, targetDir);\n const sourceRoot = resolved.absolute;\n\n // Check if source path exists\n const sourceExists = await exists(sourceRoot);\n\n // When source path is gone but we have workspace file mappings, determine state from\n // workspace targets instead of marking the package missing (e.g. index.path was a temp dir).\n const canDeriveFromFiles = totalTargets > 0;\n if (!sourceExists && !canDeriveFromFiles) {\n return {\n name: pkgName,\n version: entry.version,\n path: entry.path,\n state: 'missing',\n totalFiles: 0,\n existingFiles: 0,\n fileList: includeFileList ? [] : undefined\n };\n }\n\n // Check workspace file existence\n let totalFiles = 0;\n let existingFiles = 0;\n const fileList: ListFileMapping[] = [];\n \n const filesMapping = entry.files || {};\n \n // Normalize platform filter\n const normalizedPlatforms = platformsFilter ? normalizePlatforms(platformsFilter) : null;\n\n for (const [sourceKey, targets] of Object.entries(filesMapping)) {\n if (!Array.isArray(targets) || targets.length === 0) continue;\n\n for (const mapping of targets) {\n const targetPath = getTargetPath(mapping);\n \n // Apply platform filter if specified\n if (normalizedPlatforms && normalizedPlatforms.length > 0) {\n const filePlatform = extractPlatformFromPath(targetPath, targetDir);\n \n // If the file has a platform, check if it matches the filter\n if (filePlatform) {\n if (!normalizedPlatforms.includes(filePlatform.toLowerCase())) {\n continue; // Skip this file - it doesn't match the platform filter\n }\n }\n // If the file has no platform (universal), include it in all platform filters\n }\n \n const absPath = path.join(targetDir, targetPath);\n totalFiles++;\n \n const fileExists = await exists(absPath);\n if (fileExists) {\n existingFiles++;\n }\n if (includeFileList) {\n fileList.push({\n source: sourceKey,\n target: targetPath,\n exists: fileExists\n });\n }\n }\n }\n\n // Classify package state\n const state: PackageSyncState = existingFiles === totalFiles ? 'synced' : 'partial';\n\n // Read dependencies from the package manifest (not workspace index)\n let dependencies: string[] | undefined = entry.dependencies;\n if (!dependencies || dependencies.length === 0) {\n try {\n const pkgManifestPath = path.join(sourceRoot, 'openpackage.yml');\n if (await exists(pkgManifestPath)) {\n const pkgManifest = await parsePackageYml(pkgManifestPath);\n const allDeps = [\n ...(pkgManifest.dependencies || []),\n ...(pkgManifest['dev-dependencies'] || [])\n ];\n dependencies = allDeps.map(dep => dep.name);\n }\n } catch (error) {\n logger.debug(`Failed to read package manifest for ${pkgName}: ${error}`);\n }\n }\n\n // Always compute resource groups from the file data we collected\n const allFilesForGrouping: ListFileMapping[] = includeFileList ? fileList : [];\n\n // If we didn't collect file details for the list, we still need them for resource grouping\n if (!includeFileList) {\n for (const [sourceKey, targets] of Object.entries(filesMapping)) {\n if (!Array.isArray(targets) || targets.length === 0) continue;\n for (const mapping of targets) {\n const targetPath = getTargetPath(mapping);\n \n // Apply platform filter if specified\n if (normalizedPlatforms && normalizedPlatforms.length > 0) {\n const filePlatform = extractPlatformFromPath(targetPath, targetDir);\n \n // If the file has a platform, check if it matches the filter\n if (filePlatform) {\n if (!normalizedPlatforms.includes(filePlatform.toLowerCase())) {\n continue; // Skip this file - it doesn't match the platform filter\n }\n }\n // If the file has no platform (universal), include it in all platform filters\n }\n \n allFilesForGrouping.push({\n source: sourceKey,\n target: targetPath,\n exists: true\n });\n }\n }\n }\n\n const resourceGroups = allFilesForGrouping.length > 0\n ? groupFilesIntoResources(allFilesForGrouping)\n : undefined;\n\n return {\n name: pkgName,\n version: entry.version,\n path: entry.path,\n state,\n totalFiles,\n existingFiles,\n fileList: includeFileList ? fileList : undefined,\n resourceGroups,\n dependencies\n };\n}\n\n/**\n * Build a dependency tree from package reports\n */\nfunction buildDependencyTree(\n rootNames: string[],\n reportMap: Map<string, ListPackageReport>,\n all: boolean\n): ListTreeNode[] {\n const visited = new Set<string>();\n\n function buildNode(pkgName: string, depth: number): ListTreeNode | null {\n const report = reportMap.get(pkgName);\n if (!report) return null;\n\n // Prevent infinite loops from circular dependencies\n if (visited.has(pkgName)) {\n return {\n report: { ...report, name: `${report.name} (circular)` },\n children: []\n };\n }\n\n visited.add(pkgName);\n\n let children: ListTreeNode[] = [];\n if (all && report.dependencies && report.dependencies.length > 0) {\n children = report.dependencies\n .map(depName => buildNode(depName, depth + 1))\n .filter((node): node is ListTreeNode => node !== null);\n }\n\n visited.delete(pkgName);\n\n return { report, children };\n }\n\n return rootNames\n .map(name => buildNode(name, 0))\n .filter((node): node is ListTreeNode => node !== null);\n}\n\nexport async function runListPipeline(\n packageName: string | undefined,\n execContext: ExecutionContext,\n options: ListPipelineOptions = {}\n): Promise<CommandResult<ListPipelineResult>> {\n const { includeFiles = false, all = false, tracked = false, untracked = false, platforms } = options;\n \n // Use targetDir for list operations\n const targetDir = execContext.targetDir;\n const indexPath = getWorkspaceIndexPath(targetDir);\n\n // Validate mutual exclusivity\n if (tracked && untracked) {\n throw new ValidationError('Cannot use --tracked and --untracked together.');\n }\n\n // For --untracked only, we just need the workspace index (not the full manifest)\n if (untracked) {\n if (!(await exists(indexPath))) {\n throw new ValidationError(\n `No workspace index found at ${indexPath}. Cannot scan for untracked files.`\n );\n }\n\n const untrackedFiles = await scanUntrackedFiles(targetDir, platforms);\n\n return {\n success: true,\n data: {\n packages: [],\n tree: [],\n rootPackageNames: [],\n trackedCount: 0,\n missingCount: 0,\n untrackedCount: untrackedFiles.totalFiles,\n untrackedFiles\n }\n };\n }\n\n // Regular list operation - require both index and manifest\n const openpkgDir = getLocalOpenPackageDir(targetDir);\n const manifestPath = getLocalPackageYmlPath(targetDir);\n\n if (!(await exists(openpkgDir)) || !(await exists(manifestPath))) {\n throw new ValidationError(\n `No .openpackage/openpackage.yml found in ${targetDir}.`\n );\n }\n\n const { index } = await readWorkspaceIndex(targetDir);\n const packages = index.packages || {};\n const reports: ListPackageReport[] = [];\n const reportMap = new Map<string, ListPackageReport>();\n\n // Get workspace config to find root packages\n let rootPackageNames: string[] = [];\n let workspacePackageName: string | undefined;\n try {\n const config = await parsePackageYml(manifestPath);\n workspacePackageName = config.name;\n // Root packages are those declared in dependencies/dev-dependencies\n const declaredDeps = [\n ...(config.dependencies || []),\n ...(config['dev-dependencies'] || [])\n ];\n rootPackageNames = declaredDeps.map(dep => dep.name);\n // Include workspace package in tree roots when it's in the index (so its resources are listed)\n if (workspacePackageName && packages[workspacePackageName]) {\n rootPackageNames = [workspacePackageName, ...rootPackageNames];\n }\n } catch (error) {\n logger.warn(`Failed to read workspace manifest: ${error}`);\n }\n\n // If specific package requested, that package becomes the \"root\" and we show its dependencies\n if (packageName) {\n const pkgEntry = packages[packageName];\n if (!pkgEntry) {\n return {\n success: true,\n data: { packages: [], rootPackageNames: [], trackedCount: 0, missingCount: 0, untrackedCount: 0 }\n };\n }\n\n let targetPackage: ListPackageReport;\n try {\n targetPackage = await checkPackageStatus(targetDir, packageName, pkgEntry, true, platforms);\n reports.push(targetPackage);\n reportMap.set(packageName, targetPackage);\n } catch (error) {\n logger.warn(`Failed to check package ${packageName}: ${error}`);\n targetPackage = {\n name: packageName,\n version: pkgEntry?.version,\n path: pkgEntry?.path ?? '',\n state: 'missing',\n totalFiles: 0,\n existingFiles: 0,\n fileList: [],\n dependencies: pkgEntry?.dependencies\n };\n reports.push(targetPackage);\n reportMap.set(packageName, targetPackage);\n }\n\n // Load the target package's dependencies as tree nodes\n const depNames = targetPackage.dependencies || [];\n for (const depName of depNames) {\n if (reportMap.has(depName)) continue;\n \n const depEntry = packages[depName];\n if (!depEntry) continue;\n \n try {\n const depReport = await checkPackageStatus(targetDir, depName, depEntry, includeFiles, platforms);\n reportMap.set(depName, depReport);\n } catch (error) {\n logger.debug(`Failed to load dependency ${depName}: ${error}`);\n }\n }\n\n // If full tree (deps view), recursively load nested dependencies\n if (all) {\n const loadNestedDeps = async (names: string[]) => {\n for (const name of names) {\n const report = reportMap.get(name);\n if (!report?.dependencies) continue;\n \n for (const nestedDepName of report.dependencies) {\n if (reportMap.has(nestedDepName)) continue;\n \n const nestedEntry = packages[nestedDepName];\n if (!nestedEntry) continue;\n \n try {\n const nestedReport = await checkPackageStatus(targetDir, nestedDepName, nestedEntry, includeFiles, platforms);\n reportMap.set(nestedDepName, nestedReport);\n \n if (nestedReport.dependencies && nestedReport.dependencies.length > 0) {\n await loadNestedDeps([nestedDepName]);\n }\n } catch (error) {\n logger.debug(`Failed to load nested dependency ${nestedDepName}: ${error}`);\n }\n }\n }\n };\n await loadNestedDeps(depNames);\n }\n\n // Build tree from the target package's dependencies (not the package itself)\n const tree = buildDependencyTree(depNames, reportMap, all);\n \n // When listing a specific package, also create a tree node for the target package itself\n // so its resources can be displayed\n const targetTreeNode: ListTreeNode = {\n report: targetPackage,\n children: tree\n };\n const treeWithTarget = [targetTreeNode];\n\n // Compute tracked/missing counts from reports\n const trackedCount = reports.reduce((sum, r) => sum + r.existingFiles, 0);\n const missingCount = reports.reduce((sum, r) => sum + (r.totalFiles - r.existingFiles), 0);\n\n // Scan untracked files unless --tracked flag is set\n let untrackedFiles: UntrackedScanResult | undefined;\n let untrackedCount = 0;\n if (!tracked) {\n untrackedFiles = await scanUntrackedFiles(targetDir, platforms);\n untrackedCount = untrackedFiles.totalFiles;\n }\n\n return {\n success: true,\n data: { packages: reports, tree: treeWithTarget, rootPackageNames: depNames, targetPackage, trackedCount, missingCount, untrackedCount, untrackedFiles }\n };\n }\n\n // Check all packages and build reports (include workspace package so its resources are listed)\n for (const [pkgName, pkgEntry] of Object.entries(packages)) {\n try {\n const report = await checkPackageStatus(targetDir, pkgName, pkgEntry, includeFiles, platforms);\n reports.push(report);\n reportMap.set(pkgName, report);\n } catch (error) {\n logger.warn(`Failed to check package ${pkgName}: ${error}`);\n const errorReport: ListPackageReport = {\n name: pkgName,\n version: pkgEntry?.version,\n path: pkgEntry?.path ?? '',\n state: 'missing',\n totalFiles: 0,\n existingFiles: 0,\n dependencies: pkgEntry?.dependencies\n };\n reports.push(errorReport);\n reportMap.set(pkgName, errorReport);\n }\n }\n\n // Build dependency tree from root packages\n const tree = buildDependencyTree(rootPackageNames, reportMap, all);\n\n // Compute tracked/missing counts from reports\n const trackedCount = reports.reduce((sum, r) => sum + r.existingFiles, 0);\n const missingCount = reports.reduce((sum, r) => sum + (r.totalFiles - r.existingFiles), 0);\n\n // Scan untracked files unless --tracked flag is set\n let untrackedFiles: UntrackedScanResult | undefined;\n let untrackedCount = 0;\n if (!tracked) {\n untrackedFiles = await scanUntrackedFiles(targetDir, platforms);\n untrackedCount = untrackedFiles.totalFiles;\n }\n\n return {\n success: true,\n data: { packages: reports, tree, rootPackageNames, trackedCount, missingCount, untrackedCount, untrackedFiles }\n };\n}\n", "/**\n * Entity Type Detection Utilities\n * \n * Determines whether a path represents a package, workspace, or generic resource.\n */\n\nimport { join } from 'path';\nimport { exists, isDirectory } from './fs.js';\n\n/**\n * Entity type classification\n */\nexport type EntityType = 'workspace' | 'package' | 'resource';\n\n/**\n * Detect the type of entity at a given path.\n * \n * Detection logic:\n * - workspace: Has .openpackage/openpackage.yml\n * - package: Has openpackage.yml, or has Claude plugin characteristics, or has standard package directories\n * - resource: Everything else (individual files, subdirectories without package markers)\n * \n * @param path - Absolute path to check\n * @returns Entity type\n */\nexport async function detectEntityType(path: string): Promise<EntityType> {\n // Check for workspace marker (.openpackage/openpackage.yml)\n const workspaceMarker = join(path, '.openpackage', 'openpackage.yml');\n if (await exists(workspaceMarker)) {\n return 'workspace';\n }\n\n // Check for package marker (openpackage.yml at root)\n const packageMarker = join(path, 'openpackage.yml');\n if (await exists(packageMarker)) {\n return 'package';\n }\n\n // Check for Claude plugin characteristics (.claude-plugin/plugin.json)\n const claudePluginMarker = join(path, '.claude-plugin', 'plugin.json');\n if (await exists(claudePluginMarker)) {\n return 'package';\n }\n\n // Check for standard package directories (agents/, skills/, commands/, rules/, hooks/)\n const packageDirs = ['agents', 'skills', 'commands', 'rules', 'hooks'];\n for (const dir of packageDirs) {\n const dirPath = join(path, dir);\n if (await exists(dirPath) && await isDirectory(dirPath)) {\n return 'package';\n }\n }\n\n // Default to resource for everything else\n return 'resource';\n}\n\n/**\n * Get the display name for an entity.\n * \n * For packages: reads name from openpackage.yml, falls back to directory name\n * For other types: uses the provided name\n * \n * @param path - Absolute path to the entity\n * @param fallbackName - Name to use if package name cannot be determined\n * @returns Display name\n */\nexport async function getEntityDisplayName(\n path: string,\n fallbackName: string\n): Promise<string> {\n const entityType = await detectEntityType(path);\n\n // For packages and workspaces, try to read the name from openpackage.yml\n if (entityType === 'package' || entityType === 'workspace') {\n try {\n const { parsePackageYml } = await import('./package-yml.js');\n const manifestPath = entityType === 'workspace'\n ? join(path, '.openpackage', 'openpackage.yml')\n : join(path, 'openpackage.yml');\n\n if (await exists(manifestPath)) {\n const manifest = await parsePackageYml(manifestPath);\n if (manifest.name) {\n return manifest.name;\n }\n }\n } catch (error) {\n // Fall through to use fallback name\n }\n }\n\n return fallbackName;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["path", "pluralKey", "untrackedFiles", "tree", "trackedCount", "missingCount", "untrackedCount", "path", "parsePackageYml"]
7
+ }
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ isPlatformId,
4
+ parseUniversalPath
5
+ } from "./chunk-N43IXOND.js";
6
+
7
+ // ../core/src/core/flows/platform-suffix-handler.ts
8
+ import { basename, dirname, join } from "path";
9
+ function extractPlatformSuffixFromFilename(filename) {
10
+ let parts = basename(filename).split(".");
11
+ if (parts.length >= 3) {
12
+ let possiblePlatform = parts[parts.length - 2];
13
+ if (isPlatformId(possiblePlatform))
14
+ return possiblePlatform;
15
+ }
16
+ return null;
17
+ }
18
+ function stripPlatformSuffixFromFilename(filename) {
19
+ if (!extractPlatformSuffixFromFilename(filename))
20
+ return filename;
21
+ let dir = dirname(filename), parts = basename(filename).split("."), strippedBaseName = [...parts.slice(0, -2), parts[parts.length - 1]].join(".");
22
+ return dir === "." ? strippedBaseName : join(dir, strippedBaseName);
23
+ }
24
+ function buildOverrideMap(sources) {
25
+ let overridesByBasePath = /* @__PURE__ */ new Map();
26
+ for (let sourceRel of sources) {
27
+ let parsed = parseUniversalPath(sourceRel, { allowPlatformSuffix: !0 }), platformSuffix = parsed?.platformSuffix || extractPlatformSuffixFromFilename(sourceRel);
28
+ if (platformSuffix) {
29
+ let baseKey = parsed ? `${parsed.universalSubdir}/${parsed.relPath}` : stripPlatformSuffixFromFilename(sourceRel);
30
+ overridesByBasePath.has(baseKey) || overridesByBasePath.set(baseKey, /* @__PURE__ */ new Set()), overridesByBasePath.get(baseKey).add(platformSuffix);
31
+ }
32
+ }
33
+ return overridesByBasePath;
34
+ }
35
+ function shouldSkipUniversalFile(sourceRel, targetPlatform, sources, overrideMap) {
36
+ let parsed = parseUniversalPath(sourceRel, { allowPlatformSuffix: !0 });
37
+ if (parsed?.platformSuffix || extractPlatformSuffixFromFilename(sourceRel))
38
+ return !1;
39
+ let overrides = overrideMap || buildOverrideMap(sources);
40
+ if (parsed) {
41
+ let baseKey = `${parsed.universalSubdir}/${parsed.relPath}`;
42
+ return overrides.get(baseKey)?.has(targetPlatform) ?? !1;
43
+ } else {
44
+ let strippedFileName = stripPlatformSuffixFromFilename(sourceRel);
45
+ return sources.some((s) => {
46
+ let sSuffix = extractPlatformSuffixFromFilename(s), sStripped = stripPlatformSuffixFromFilename(s);
47
+ return sSuffix === targetPlatform && sStripped === strippedFileName;
48
+ });
49
+ }
50
+ }
51
+ function isPlatformSpecificFileForTarget(sourceRel, targetPlatform) {
52
+ let platformSuffix = parseUniversalPath(sourceRel, { allowPlatformSuffix: !0 })?.platformSuffix || extractPlatformSuffixFromFilename(sourceRel);
53
+ return platformSuffix ? platformSuffix === targetPlatform : !1;
54
+ }
55
+
56
+ export {
57
+ extractPlatformSuffixFromFilename,
58
+ stripPlatformSuffixFromFilename,
59
+ buildOverrideMap,
60
+ shouldSkipUniversalFile,
61
+ isPlatformSpecificFileForTarget
62
+ };
63
+ //# sourceMappingURL=chunk-4X2EJHJN.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../core/src/core/flows/platform-suffix-handler.ts"],
4
+ "sourcesContent": ["/**\n * Platform Suffix Handler\n * \n * Handles platform-specific file suffix detection and manipulation.\n * Supports naming conventions like:\n * - mcp.claude.jsonc (root-level platform-specific file)\n * - commands/test.claude.md (universal subdir with platform suffix)\n */\n\nimport { basename, dirname, join } from 'path';\nimport type { Platform } from '../platforms.js';\nimport { getAllPlatforms, isPlatformId } from '../platforms.js';\nimport { parseUniversalPath } from '../platform/platform-file.js';\n\n/**\n * Extract platform suffix from filename\n * \n * @param filename - Filename or path to check\n * @returns Platform ID if suffix found, null otherwise\n * \n * @example\n * extractPlatformSuffixFromFilename('mcp.claude.jsonc') // => 'claude'\n * extractPlatformSuffixFromFilename('commands/test.cursor.md') // => 'cursor'\n * extractPlatformSuffixFromFilename('mcp.jsonc') // => null\n */\nexport function extractPlatformSuffixFromFilename(filename: string): string | null {\n const baseName = basename(filename);\n const parts = baseName.split('.');\n \n // Need at least 3 parts: name.platform.ext\n if (parts.length >= 3) {\n const possiblePlatform = parts[parts.length - 2];\n if (isPlatformId(possiblePlatform)) {\n return possiblePlatform;\n }\n }\n \n return null;\n}\n\n/**\n * Strip platform suffix from filename\n * \n * @param filename - Filename or path to process\n * @returns Filename with platform suffix removed\n * \n * @example\n * stripPlatformSuffixFromFilename('mcp.claude.jsonc') // => 'mcp.jsonc'\n * stripPlatformSuffixFromFilename('commands/test.cursor.md') // => 'commands/test.md'\n * stripPlatformSuffixFromFilename('mcp.jsonc') // => 'mcp.jsonc' (unchanged)\n */\nexport function stripPlatformSuffixFromFilename(filename: string): string {\n const platformSuffix = extractPlatformSuffixFromFilename(filename);\n if (!platformSuffix) {\n return filename;\n }\n \n const dir = dirname(filename);\n const baseName = basename(filename);\n const parts = baseName.split('.');\n \n // Remove platform suffix (second-to-last part)\n const strippedParts = [...parts.slice(0, -2), parts[parts.length - 1]];\n const strippedBaseName = strippedParts.join('.');\n \n return dir === '.' ? strippedBaseName : join(dir, strippedBaseName);\n}\n\n/**\n * Build a map of base paths to platforms that have override files\n * \n * This is used to determine when universal files should be skipped because\n * platform-specific overrides exist.\n * \n * @param sources - Array of source file paths\n * @returns Map of base path to Set of platforms with overrides\n * \n * @example\n * // Input: ['commands/test.md', 'commands/test.claude.md', 'mcp.jsonc', 'mcp.cursor.jsonc']\n * // Output: Map {\n * // 'commands/test.md' => Set(['claude']),\n * // 'mcp.jsonc' => Set(['cursor'])\n * // }\n */\nexport function buildOverrideMap(sources: string[]): Map<string, Set<Platform>> {\n const overridesByBasePath = new Map<string, Set<Platform>>();\n \n for (const sourceRel of sources) {\n const parsed = parseUniversalPath(sourceRel, { allowPlatformSuffix: true });\n const platformSuffix = parsed?.platformSuffix || extractPlatformSuffixFromFilename(sourceRel);\n \n if (platformSuffix) {\n // For universal subdir files, use the parsed baseKey\n // For root-level files, use the stripped filename as the baseKey\n const baseKey = parsed \n ? `${parsed.universalSubdir}/${parsed.relPath}`\n : stripPlatformSuffixFromFilename(sourceRel);\n \n if (!overridesByBasePath.has(baseKey)) {\n overridesByBasePath.set(baseKey, new Set());\n }\n overridesByBasePath.get(baseKey)!.add(platformSuffix as Platform);\n }\n }\n \n return overridesByBasePath;\n}\n\n/**\n * Check if a universal file should be skipped due to platform-specific override\n * \n * @param sourceRel - Source file path (relative)\n * @param targetPlatform - Target platform to check\n * @param sources - All source files (for building override map)\n * @param overrideMap - Pre-built override map (optional, for performance)\n * @returns True if file should be skipped\n */\nexport function shouldSkipUniversalFile(\n sourceRel: string,\n targetPlatform: Platform,\n sources: string[],\n overrideMap?: Map<string, Set<Platform>>\n): boolean {\n // Parse to check if it's a universal subdir file\n const parsed = parseUniversalPath(sourceRel, { allowPlatformSuffix: true });\n \n // If file has platform suffix, it's not universal\n const platformSuffix = parsed?.platformSuffix || extractPlatformSuffixFromFilename(sourceRel);\n if (platformSuffix) {\n return false;\n }\n \n // Build override map if not provided\n const overrides = overrideMap || buildOverrideMap(sources);\n \n // Check for override\n if (parsed) {\n // Universal subdir file\n const baseKey = `${parsed.universalSubdir}/${parsed.relPath}`;\n const overridePlatforms = overrides.get(baseKey);\n return overridePlatforms?.has(targetPlatform) ?? false;\n } else {\n // Root-level file\n const strippedFileName = stripPlatformSuffixFromFilename(sourceRel);\n \n // Check if any file in sources is a platform-specific override for this file\n return sources.some(s => {\n const sSuffix = extractPlatformSuffixFromFilename(s);\n const sStripped = stripPlatformSuffixFromFilename(s);\n return sSuffix === targetPlatform && sStripped === strippedFileName;\n });\n }\n}\n\n/**\n * Check if a platform-specific file is for the target platform\n * \n * @param sourceRel - Source file path (relative)\n * @param targetPlatform - Target platform to check\n * @returns True if file is for target platform\n */\nexport function isPlatformSpecificFileForTarget(\n sourceRel: string,\n targetPlatform: Platform\n): boolean {\n const parsed = parseUniversalPath(sourceRel, { allowPlatformSuffix: true });\n const platformSuffix = parsed?.platformSuffix || extractPlatformSuffixFromFilename(sourceRel);\n \n if (!platformSuffix) {\n return false;\n }\n \n return platformSuffix === targetPlatform;\n}\n\n/**\n * Get all platform-specific variants of a file\n * \n * @param baseFile - Base filename (without platform suffix)\n * @param sources - All source files\n * @returns Array of platform-specific variants\n * \n * @example\n * getPlatformVariants('mcp.jsonc', ['mcp.jsonc', 'mcp.claude.jsonc', 'mcp.cursor.jsonc'])\n * // => ['mcp.claude.jsonc', 'mcp.cursor.jsonc']\n */\nexport function getPlatformVariants(\n baseFile: string,\n sources: string[]\n): Array<{ platform: Platform; path: string }> {\n const variants: Array<{ platform: Platform; path: string }> = [];\n \n const baseStripped = stripPlatformSuffixFromFilename(baseFile);\n \n for (const source of sources) {\n const platformSuffix = extractPlatformSuffixFromFilename(source);\n if (platformSuffix) {\n const sourceStripped = stripPlatformSuffixFromFilename(source);\n if (sourceStripped === baseStripped) {\n variants.push({\n platform: platformSuffix as Platform,\n path: source\n });\n }\n }\n }\n \n return variants;\n}\n\n/**\n * Normalize a source path for canonical key generation\n * \n * This handles the case where a dot-prefixed file (.mcp.json) is discovered\n * but the flow pattern array includes other patterns. Returns the canonical\n * form preferred for file mapping keys.\n * \n * @param sourceRel - Source file path (relative)\n * @param flowPatterns - Flow patterns that could match\n * @param packageRoot - Package root directory\n * @returns Canonical source path\n */\nexport function normalizeSourceForMapping(\n sourceRel: string,\n flowPatterns: string | string[],\n packageRoot: string\n): string {\n // If not a dot-prefixed root-level file, return as-is\n if (!sourceRel.startsWith('.') || sourceRel.includes('/')) {\n return sourceRel;\n }\n \n // Not an array pattern, return as-is\n if (!Array.isArray(flowPatterns)) {\n return sourceRel;\n }\n \n // For dot-prefixed files, prefer explicit pattern match over dot-prefix pattern\n // This prevents duplicate keys in file mapping\n const patterns = flowPatterns;\n \n for (const pattern of patterns) {\n // Skip dot-prefixed patterns and the current sourceRel\n if (pattern.startsWith('.') || pattern === sourceRel) {\n continue;\n }\n \n // Check if pattern could match this file\n // Simple heuristic: if stripping dot from sourceRel matches pattern structure\n const withoutDot = sourceRel.substring(1);\n if (withoutDot === pattern) {\n return pattern;\n }\n }\n \n return sourceRel;\n}\n"],
5
+ "mappings": ";;;;;;;AASA,SAAS,UAAU,SAAS,YAAY;AAgBjC,SAAS,kCAAkC,UAAiC;AAEjF,MAAM,QADW,SAAS,QAAQ,EACX,MAAM,GAAG;AAGhC,MAAI,MAAM,UAAU,GAAG;AACrB,QAAM,mBAAmB,MAAM,MAAM,SAAS,CAAC;AAC/C,QAAI,aAAa,gBAAgB;AAC/B,aAAO;AAAA,EAEX;AAEA,SAAO;AACT;AAaO,SAAS,gCAAgC,UAA0B;AAExE,MAAI,CADmB,kCAAkC,QAAQ;AAE/D,WAAO;AAGT,MAAM,MAAM,QAAQ,QAAQ,GAEtB,QADW,SAAS,QAAQ,EACX,MAAM,GAAG,GAI1B,mBADgB,CAAC,GAAG,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,MAAM,SAAS,CAAC,CAAC,EAC9B,KAAK,GAAG;AAE/C,SAAO,QAAQ,MAAM,mBAAmB,KAAK,KAAK,gBAAgB;AACpE;AAkBO,SAAS,iBAAiB,SAA+C;AAC9E,MAAM,sBAAsB,oBAAI,IAA2B;AAE3D,WAAW,aAAa,SAAS;AAC/B,QAAM,SAAS,mBAAmB,WAAW,EAAE,qBAAqB,GAAK,CAAC,GACpE,iBAAiB,QAAQ,kBAAkB,kCAAkC,SAAS;AAE5F,QAAI,gBAAgB;AAGlB,UAAM,UAAU,SACZ,GAAG,OAAO,eAAe,IAAI,OAAO,OAAO,KAC3C,gCAAgC,SAAS;AAE7C,MAAK,oBAAoB,IAAI,OAAO,KAClC,oBAAoB,IAAI,SAAS,oBAAI,IAAI,CAAC,GAE5C,oBAAoB,IAAI,OAAO,EAAG,IAAI,cAA0B;AAAA,IAClE;AAAA,EACF;AAEA,SAAO;AACT;AAWO,SAAS,wBACd,WACA,gBACA,SACA,aACS;AAET,MAAM,SAAS,mBAAmB,WAAW,EAAE,qBAAqB,GAAK,CAAC;AAI1E,MADuB,QAAQ,kBAAkB,kCAAkC,SAAS;AAE1F,WAAO;AAIT,MAAM,YAAY,eAAe,iBAAiB,OAAO;AAGzD,MAAI,QAAQ;AAEV,QAAM,UAAU,GAAG,OAAO,eAAe,IAAI,OAAO,OAAO;AAE3D,WAD0B,UAAU,IAAI,OAAO,GACrB,IAAI,cAAc,KAAK;AAAA,EACnD,OAAO;AAEL,QAAM,mBAAmB,gCAAgC,SAAS;AAGlE,WAAO,QAAQ,KAAK,OAAK;AACvB,UAAM,UAAU,kCAAkC,CAAC,GAC7C,YAAY,gCAAgC,CAAC;AACnD,aAAO,YAAY,kBAAkB,cAAc;AAAA,IACrD,CAAC;AAAA,EACH;AACF;AASO,SAAS,gCACd,WACA,gBACS;AAET,MAAM,iBADS,mBAAmB,WAAW,EAAE,qBAAqB,GAAK,CAAC,GAC3C,kBAAkB,kCAAkC,SAAS;AAE5F,SAAK,iBAIE,mBAAmB,iBAHjB;AAIX;",
6
+ "names": []
7
+ }