bi-superpowers 1.0.0

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 (276) hide show
  1. package/.claude-plugin/marketplace.json +31 -0
  2. package/.claude-plugin/plugin.json +34 -0
  3. package/.claude-plugin/skill-manifest.json +79 -0
  4. package/.mcp.json +13 -0
  5. package/.plugin/plugin.json +14 -0
  6. package/LICENSE +21 -0
  7. package/README.md +849 -0
  8. package/bin/build-plugin.js +97 -0
  9. package/bin/cli.js +891 -0
  10. package/bin/commands/autoupdate.js +128 -0
  11. package/bin/commands/build-desktop.js +368 -0
  12. package/bin/commands/create-from-template.js +165 -0
  13. package/bin/commands/diff.js +435 -0
  14. package/bin/commands/install.js +542 -0
  15. package/bin/commands/lint.js +441 -0
  16. package/bin/commands/mcp-setup.js +255 -0
  17. package/bin/commands/session-update.js +204 -0
  18. package/bin/commands/smoke-test.js +20 -0
  19. package/bin/commands/uninstall.js +611 -0
  20. package/bin/commands/update-check.js +427 -0
  21. package/bin/commands/validate-cases.js +264 -0
  22. package/bin/commands/validate-projects.js +426 -0
  23. package/bin/commands/watch.js +251 -0
  24. package/bin/lib/agents.js +62 -0
  25. package/bin/lib/base-template-smoke.js +299 -0
  26. package/bin/lib/claude-hooks.js +160 -0
  27. package/bin/lib/generators/claude-plugin.js +529 -0
  28. package/bin/lib/generators/index.js +116 -0
  29. package/bin/lib/generators/shared.js +257 -0
  30. package/bin/lib/mcp-config.js +835 -0
  31. package/bin/lib/microsoft-mcp.js +206 -0
  32. package/bin/lib/powerbi-mcp-session.js +140 -0
  33. package/bin/lib/skills.js +164 -0
  34. package/bin/lib/template-scaffold.js +366 -0
  35. package/bin/mcp/powerbi-modeling-launcher.js +42 -0
  36. package/bin/postinstall.js +50 -0
  37. package/bin/utils/mcp-detect.js +346 -0
  38. package/bin/utils/tui.js +314 -0
  39. package/commands/bi-connect.md +520 -0
  40. package/commands/bi-dax.md +464 -0
  41. package/commands/bi-kickoff.md +550 -0
  42. package/commands/bi-modeling.md +485 -0
  43. package/commands/bi-performance.md +521 -0
  44. package/commands/bi-powerquery.md +229 -0
  45. package/commands/bi-refactor.md +249 -0
  46. package/commands/bi-scorecard.md +268 -0
  47. package/commands/bi-start.md +272 -0
  48. package/config.example.json +23 -0
  49. package/config.json +23 -0
  50. package/desktop-extension/manifest.json +30 -0
  51. package/desktop-extension/package.json +10 -0
  52. package/desktop-extension/server.js +137 -0
  53. package/package.json +94 -0
  54. package/skills/bi-connect/SKILL.md +522 -0
  55. package/skills/bi-connect/scripts/update-check.js +427 -0
  56. package/skills/bi-dax/SKILL.md +466 -0
  57. package/skills/bi-dax/scripts/update-check.js +427 -0
  58. package/skills/bi-kickoff/SKILL.md +552 -0
  59. package/skills/bi-kickoff/references/flow.html +78 -0
  60. package/skills/bi-kickoff/references/flow.md +62 -0
  61. package/skills/bi-kickoff/scripts/update-check.js +427 -0
  62. package/skills/bi-modeling/SKILL.md +487 -0
  63. package/skills/bi-modeling/scripts/update-check.js +427 -0
  64. package/skills/bi-performance/SKILL.md +523 -0
  65. package/skills/bi-performance/scripts/install-tabular-editor.ps1 +159 -0
  66. package/skills/bi-performance/scripts/run-bpa.ps1 +265 -0
  67. package/skills/bi-performance/scripts/update-check.js +427 -0
  68. package/skills/bi-powerquery/SKILL.md +231 -0
  69. package/skills/bi-powerquery/references/base-template-data-contract.md +323 -0
  70. package/skills/bi-powerquery/references/power-query-standards.md +74 -0
  71. package/skills/bi-powerquery/scripts/new-powerquery-staging.ps1 +371 -0
  72. package/skills/bi-powerquery/scripts/test-powerquery-contract.ps1 +225 -0
  73. package/skills/bi-powerquery/scripts/update-check.js +427 -0
  74. package/skills/bi-refactor/SKILL.md +251 -0
  75. package/skills/bi-refactor/references/flow.md +27 -0
  76. package/skills/bi-refactor/scripts/update-check.js +427 -0
  77. package/skills/bi-scorecard/SKILL.md +270 -0
  78. package/skills/bi-scorecard/examples/base-template-scorecard-overlay.json +82 -0
  79. package/skills/bi-scorecard/scripts/new-scorecard-blueprint-from-base-template.ps1 +124 -0
  80. package/skills/bi-scorecard/scripts/powerbi-goal-status-rules-api.ps1 +39 -0
  81. package/skills/bi-scorecard/scripts/powerbi-goal-values-api.ps1 +48 -0
  82. package/skills/bi-scorecard/scripts/powerbi-goals-api.ps1 +68 -0
  83. package/skills/bi-scorecard/scripts/powerbi-rest-common.ps1 +197 -0
  84. package/skills/bi-scorecard/scripts/powerbi-scorecards-api.ps1 +53 -0
  85. package/skills/bi-scorecard/scripts/update-check.js +427 -0
  86. package/skills/bi-start/SKILL.md +274 -0
  87. package/skills/bi-start/scripts/update-check.js +427 -0
  88. package/src/content/base.md +197 -0
  89. package/src/content/mcp-requirements.json +57 -0
  90. package/src/content/routing.md +201 -0
  91. package/src/content/skills/bi-connect.md +493 -0
  92. package/src/content/skills/bi-dax.md +437 -0
  93. package/src/content/skills/bi-kickoff/SKILL.md +523 -0
  94. package/src/content/skills/bi-kickoff/references/flow.html +78 -0
  95. package/src/content/skills/bi-kickoff/references/flow.md +62 -0
  96. package/src/content/skills/bi-modeling.md +458 -0
  97. package/src/content/skills/bi-performance/SKILL.md +494 -0
  98. package/src/content/skills/bi-performance/scripts/install-tabular-editor.ps1 +159 -0
  99. package/src/content/skills/bi-performance/scripts/run-bpa.ps1 +265 -0
  100. package/src/content/skills/bi-powerquery/SKILL.md +202 -0
  101. package/src/content/skills/bi-powerquery/references/base-template-data-contract.md +323 -0
  102. package/src/content/skills/bi-powerquery/references/power-query-standards.md +74 -0
  103. package/src/content/skills/bi-powerquery/scripts/new-powerquery-staging.ps1 +371 -0
  104. package/src/content/skills/bi-powerquery/scripts/test-powerquery-contract.ps1 +225 -0
  105. package/src/content/skills/bi-refactor/SKILL.md +222 -0
  106. package/src/content/skills/bi-refactor/references/flow.md +27 -0
  107. package/src/content/skills/bi-scorecard/SKILL.md +241 -0
  108. package/src/content/skills/bi-scorecard/examples/base-template-scorecard-blueprint.expected.json +105 -0
  109. package/src/content/skills/bi-scorecard/examples/base-template-scorecard-overlay.json +82 -0
  110. package/src/content/skills/bi-scorecard/scripts/new-scorecard-blueprint-from-base-template.ps1 +124 -0
  111. package/src/content/skills/bi-scorecard/scripts/powerbi-goal-status-rules-api.ps1 +39 -0
  112. package/src/content/skills/bi-scorecard/scripts/powerbi-goal-values-api.ps1 +48 -0
  113. package/src/content/skills/bi-scorecard/scripts/powerbi-goals-api.ps1 +68 -0
  114. package/src/content/skills/bi-scorecard/scripts/powerbi-rest-common.ps1 +197 -0
  115. package/src/content/skills/bi-scorecard/scripts/powerbi-scorecards-api.ps1 +53 -0
  116. package/src/content/skills/bi-start.md +266 -0
  117. package/templates/base-template/AGENTS.md +33 -0
  118. package/templates/base-template/base-template.Report/.platform +11 -0
  119. package/templates/base-template/base-template.Report/StaticResources/RegisteredResources/BISuperpowers.json +3888 -0
  120. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BaseThemes/CY18SU07.json +177 -0
  121. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BaseThemes/Fluent2-CY26SU03.json +4104 -0
  122. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleCityPark.json +26 -0
  123. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleDefault.json +26 -0
  124. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleNeutral.json +26 -0
  125. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleOrchid.json +26 -0
  126. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleTidal.json +26 -0
  127. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Bloom.json +139 -0
  128. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/CityPark.json +40 -0
  129. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Classroom.json +40 -0
  130. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/ColorblindSafe.json +48 -0
  131. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/CopilotDefault.json +1861 -0
  132. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Divergent.json +127 -0
  133. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Electric.json +48 -0
  134. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Frontier.json +136 -0
  135. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/HighContrast.json +40 -0
  136. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Highrise.json +41 -0
  137. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Innovate.json +227 -0
  138. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/NewExecutive.json +41 -0
  139. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Solar.json +33 -0
  140. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Storm.json +25 -0
  141. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Sunset.json +48 -0
  142. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Temperature.json +33 -0
  143. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Tidal.json +100 -0
  144. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Twilight.json +40 -0
  145. package/templates/base-template/base-template.Report/definition/bookmarks/1d40d43c7ade66e8603c.bookmark.json +2297 -0
  146. package/templates/base-template/base-template.Report/definition/bookmarks/af068ff51c0ca3089ea7.bookmark.json +2300 -0
  147. package/templates/base-template/base-template.Report/definition/bookmarks/bookmarks.json +11 -0
  148. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/page.json +130 -0
  149. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/0352fd80d074693a65db/mobile.json +11 -0
  150. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/0352fd80d074693a65db/visual.json +669 -0
  151. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/1c5a14bf493697344b68/mobile.json +11 -0
  152. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/1c5a14bf493697344b68/visual.json +723 -0
  153. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/3486cf7624c5b109b4e5/mobile.json +11 -0
  154. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/3486cf7624c5b109b4e5/visual.json +333 -0
  155. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/4d8b989008edc0db28d1/mobile.json +11 -0
  156. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/4d8b989008edc0db28d1/visual.json +109 -0
  157. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/55e10ac7d76a1954f94f/mobile.json +31 -0
  158. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/55e10ac7d76a1954f94f/visual.json +378 -0
  159. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/57f52ecf4490f70e4da1/mobile.json +11 -0
  160. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/57f52ecf4490f70e4da1/visual.json +175 -0
  161. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/5f4d76bbc870118e9840/mobile.json +11 -0
  162. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/5f4d76bbc870118e9840/visual.json +468 -0
  163. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/73629e1abebb7a444b59/mobile.json +11 -0
  164. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/73629e1abebb7a444b59/visual.json +359 -0
  165. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/749cb1388c7e0a88161c/mobile.json +11 -0
  166. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/749cb1388c7e0a88161c/visual.json +690 -0
  167. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/90677f13cea5d1275990/visual.json +17 -0
  168. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/92cf92e3da10493adb78/mobile.json +11 -0
  169. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/92cf92e3da10493adb78/visual.json +468 -0
  170. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/9fe17b1971f68443fc15/mobile.json +10 -0
  171. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/9fe17b1971f68443fc15/visual.json +328 -0
  172. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a30bd0950630ed94e8a3/mobile.json +11 -0
  173. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a30bd0950630ed94e8a3/visual.json +578 -0
  174. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a56e91d9400a835e4814/mobile.json +11 -0
  175. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a56e91d9400a835e4814/visual.json +432 -0
  176. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/aded24cd205c0b528642/mobile.json +11 -0
  177. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/aded24cd205c0b528642/visual.json +801 -0
  178. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/af34b26f14a8a724c9a9/mobile.json +37 -0
  179. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/af34b26f14a8a724c9a9/visual.json +1318 -0
  180. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/b529688fe5a226643322/visual.json +209 -0
  181. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/c4c6f332d05e72e2eb06/mobile.json +11 -0
  182. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/c4c6f332d05e72e2eb06/visual.json +174 -0
  183. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/fa81f184e2cb0e8b087c/mobile.json +29 -0
  184. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/fa81f184e2cb0e8b087c/visual.json +241 -0
  185. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/page.json +130 -0
  186. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/07e9c4302e29029c5462/mobile.json +11 -0
  187. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/07e9c4302e29029c5462/visual.json +690 -0
  188. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/109ceede4bc015b0c006/mobile.json +11 -0
  189. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/109ceede4bc015b0c006/visual.json +468 -0
  190. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/118257e006d472277e10/mobile.json +11 -0
  191. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/118257e006d472277e10/visual.json +359 -0
  192. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/2caf02e0137c4a1280cc/mobile.json +11 -0
  193. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/2caf02e0137c4a1280cc/visual.json +669 -0
  194. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/311e76fe3c9edad68204/mobile.json +11 -0
  195. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/311e76fe3c9edad68204/visual.json +109 -0
  196. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/31c21f8cbeb3b208940a/visual.json +209 -0
  197. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/3ab72c25062437149b03/visual.json +17 -0
  198. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5959867442abcb0ce2b3/mobile.json +11 -0
  199. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5959867442abcb0ce2b3/visual.json +788 -0
  200. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5b96e0f88d192b044a13/mobile.json +11 -0
  201. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5b96e0f88d192b044a13/visual.json +592 -0
  202. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/64e749a63d0786000e22/mobile.json +11 -0
  203. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/64e749a63d0786000e22/visual.json +468 -0
  204. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/7ae1ca604edac6586ad0/mobile.json +11 -0
  205. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/7ae1ca604edac6586ad0/visual.json +1310 -0
  206. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/840300733885141a6603/mobile.json +11 -0
  207. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/840300733885141a6603/visual.json +175 -0
  208. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/a38448cdb203279273d2/mobile.json +11 -0
  209. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/a38448cdb203279273d2/visual.json +516 -0
  210. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d1e86f213a3841d12e20/visual.json +328 -0
  211. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d4a484c1bcc8ee3075e2/mobile.json +11 -0
  212. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d4a484c1bcc8ee3075e2/visual.json +432 -0
  213. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d87cb5cf06acca19bbb5/mobile.json +11 -0
  214. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d87cb5cf06acca19bbb5/visual.json +241 -0
  215. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/e243da2677209ed69408/mobile.json +11 -0
  216. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/e243da2677209ed69408/visual.json +174 -0
  217. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/f3aaf24f5b22b67573b0/mobile.json +11 -0
  218. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/f3aaf24f5b22b67573b0/visual.json +333 -0
  219. package/templates/base-template/base-template.Report/definition/pages/pages.json +8 -0
  220. package/templates/base-template/base-template.Report/definition/report.json +89 -0
  221. package/templates/base-template/base-template.Report/definition/version.json +4 -0
  222. package/templates/base-template/base-template.Report/definition.pbir +9 -0
  223. package/templates/base-template/base-template.SemanticModel/.platform +11 -0
  224. package/templates/base-template/base-template.SemanticModel/definition/cultures/es-AR.tmdl +11185 -0
  225. package/templates/base-template/base-template.SemanticModel/definition/database.tmdl +3 -0
  226. package/templates/base-template/base-template.SemanticModel/definition/expressions.tmdl +234 -0
  227. package/templates/base-template/base-template.SemanticModel/definition/functions.tmdl +637 -0
  228. package/templates/base-template/base-template.SemanticModel/definition/model.tmdl +82 -0
  229. package/templates/base-template/base-template.SemanticModel/definition/relationships.tmdl +271 -0
  230. package/templates/base-template/base-template.SemanticModel/definition/tables/Calendario.tmdl +200 -0
  231. package/templates/base-template/base-template.SemanticModel/definition/tables/Campa/303/261as.tmdl +75 -0
  232. package/templates/base-template/base-template.SemanticModel/definition/tables/Canales.tmdl +84 -0
  233. package/templates/base-template/base-template.SemanticModel/definition/tables/Clientes.tmdl +143 -0
  234. package/templates/base-template/base-template.SemanticModel/definition/tables/Devoluciones.tmdl +95 -0
  235. package/templates/base-template/base-template.SemanticModel/definition/tables/Ejecuci/303/263n proyectos.tmdl" +130 -0
  236. package/templates/base-template/base-template.SemanticModel/definition/tables/Entregas.tmdl +122 -0
  237. package/templates/base-template/base-template.SemanticModel/definition/tables/Equipos m/303/251tricas.tmdl" +40 -0
  238. package/templates/base-template/base-template.SemanticModel/definition/tables/Equipos.tmdl +73 -0
  239. package/templates/base-template/base-template.SemanticModel/definition/tables/Horas.tmdl +122 -0
  240. package/templates/base-template/base-template.SemanticModel/definition/tables/Interacciones clientes.tmdl +146 -0
  241. package/templates/base-template/base-template.SemanticModel/definition/tables/Leads.tmdl +119 -0
  242. package/templates/base-template/base-template.SemanticModel/definition/tables/Monedas.tmdl +44 -0
  243. package/templates/base-template/base-template.SemanticModel/definition/tables/Movimientos financieros.tmdl +145 -0
  244. package/templates/base-template/base-template.SemanticModel/definition/tables/M/303/251tricas.tmdl +1294 -0
  245. package/templates/base-template/base-template.SemanticModel/definition/tables/N/303/263mina.tmdl +110 -0
  246. package/templates/base-template/base-template.SemanticModel/definition/tables/Oportunidades.tmdl +135 -0
  247. package/templates/base-template/base-template.SemanticModel/definition/tables/Presupuesto.tmdl +125 -0
  248. package/templates/base-template/base-template.SemanticModel/definition/tables/Productos.tmdl +98 -0
  249. package/templates/base-template/base-template.SemanticModel/definition/tables/Proyectos.tmdl +77 -0
  250. package/templates/base-template/base-template.SemanticModel/definition/tables/Servicios.tmdl +75 -0
  251. package/templates/base-template/base-template.SemanticModel/definition/tables/Tareas proyecto.tmdl +102 -0
  252. package/templates/base-template/base-template.SemanticModel/definition/tables/Tipo de cambio.tmdl +67 -0
  253. package/templates/base-template/base-template.SemanticModel/definition/tables/Ventas.tmdl +180 -0
  254. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux An/303/241lisis dimensiones.tmdl" +38 -0
  255. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Comparaciones.tmdl +227 -0
  256. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Compatibilidad m/303/251trica-dimensi/303/263n.tmdl" +68 -0
  257. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Modelo configuraci/303/263n.tmdl" +44 -0
  258. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Modo fechas.tmdl +36 -0
  259. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux M/303/251trica-Equipo.tmdl" +102 -0
  260. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Overrides m/303/251trica-dimensi/303/263n.tmdl" +54 -0
  261. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Per/303/255odos.tmdl" +182 -0
  262. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Rango fechas modo.tmdl +36 -0
  263. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Rango fechas.tmdl +27 -0
  264. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Vista de calendario.tmdl +30 -0
  265. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC C/303/241lculo.tmdl" +70 -0
  266. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC Eje X.tmdl +63 -0
  267. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC M/303/251trica.tmdl" +374 -0
  268. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC Tipo c/303/241lculo.tmdl" +223 -0
  269. package/templates/base-template/base-template.SemanticModel/definition/tables/_PC Dimensi/303/263n.tmdl" +98 -0
  270. package/templates/base-template/base-template.SemanticModel/definition/tables/_PC Eje X.tmdl +68 -0
  271. package/templates/base-template/base-template.SemanticModel/definition/tables//303/223rdenes servicio.tmdl" +151 -0
  272. package/templates/base-template/base-template.SemanticModel/definition.pbism +5 -0
  273. package/templates/base-template/base-template.SemanticModel/diagramLayout.json +568 -0
  274. package/templates/base-template/base-template.pbip +14 -0
  275. package/templates/base-template/template.manifest.json +41 -0
  276. package/theme/BISuperpowers.json +3888 -0
@@ -0,0 +1,441 @@
1
+ /**
2
+ * Lint Command (checkup)
3
+ * ======================
4
+ * Validates skill files for proper structure and format.
5
+ *
6
+ * Usage:
7
+ * super checkup Lint all skills
8
+ * super checkup dax.md Lint specific skill
9
+ * super checkup --fix Auto-fix issues (where possible)
10
+ */
11
+
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+ const tui = require('../utils/tui');
15
+ const { readSkillDirectory, normalizeSkillName } = require('../lib/skills');
16
+
17
+ // Lint rules configuration
18
+ const RULES = {
19
+ // Required sections
20
+ requiredSections: {
21
+ enabled: true,
22
+ severity: 'error',
23
+ sections: ['Trigger', 'Identity', 'MANDATORY RULES'],
24
+ },
25
+
26
+ // Trigger section validation
27
+ triggerFormat: {
28
+ enabled: true,
29
+ severity: 'warning',
30
+ description: 'Trigger section should have bullet points with quoted phrases',
31
+ },
32
+
33
+ // Title validation
34
+ hasTitle: {
35
+ enabled: true,
36
+ severity: 'error',
37
+ description: 'Skill must have an H1 title',
38
+ },
39
+
40
+ // Code block validation
41
+ codeBlocks: {
42
+ enabled: true,
43
+ severity: 'warning',
44
+ description: 'Code blocks should have language specified',
45
+ },
46
+
47
+ // Link validation
48
+ brokenLinks: {
49
+ enabled: true,
50
+ severity: 'warning',
51
+ description: 'Internal links should point to existing files',
52
+ },
53
+
54
+ // Maximum file size
55
+ maxSize: {
56
+ enabled: true,
57
+ severity: 'warning',
58
+ maxBytes: 50000, // 50KB
59
+ },
60
+
61
+ // Naming convention. Folder-based skills follow Anthropic's convention
62
+ // of `<folder>/SKILL.md` (uppercase), so allow that literal too.
63
+ naming: {
64
+ enabled: true,
65
+ severity: 'error',
66
+ pattern: /^([a-z0-9-]+\.md|SKILL\.md)$/,
67
+ description: 'Skill files should be lowercase-kebab-case.md, or SKILL.md inside a skill folder',
68
+ },
69
+ };
70
+
71
+ /**
72
+ * Lint a single skill file
73
+ * @param {string} filePath - Path to skill file
74
+ * @returns {Object} Lint result with errors and warnings
75
+ */
76
+ function lintFile(filePath) {
77
+ const result = {
78
+ file: path.basename(filePath),
79
+ path: filePath,
80
+ errors: [],
81
+ warnings: [],
82
+ };
83
+
84
+ let content;
85
+ try {
86
+ content = fs.readFileSync(filePath, 'utf8');
87
+ } catch (e) {
88
+ result.errors.push({ rule: 'file-read', message: `Cannot read file: ${e.message}` });
89
+ return result;
90
+ }
91
+
92
+ const lines = content.split('\n');
93
+ const filename = path.basename(filePath);
94
+
95
+ // Rule: File naming convention
96
+ if (RULES.naming.enabled && !RULES.naming.pattern.test(filename)) {
97
+ addIssue(
98
+ result,
99
+ 'naming',
100
+ RULES.naming.severity,
101
+ `File name "${filename}" should be lowercase-kebab-case.md`
102
+ );
103
+ }
104
+
105
+ // Rule: Max file size
106
+ if (RULES.maxSize.enabled) {
107
+ const stats = fs.statSync(filePath);
108
+ if (stats.size > RULES.maxSize.maxBytes) {
109
+ addIssue(
110
+ result,
111
+ 'maxSize',
112
+ RULES.maxSize.severity,
113
+ `File size (${(stats.size / 1024).toFixed(1)}KB) exceeds ${RULES.maxSize.maxBytes / 1024}KB limit`
114
+ );
115
+ }
116
+ }
117
+
118
+ // Rule: Has H1 title
119
+ if (RULES.hasTitle.enabled) {
120
+ const hasH1 = lines.some((line) => /^#\s+.+/.test(line));
121
+ if (!hasH1) {
122
+ addIssue(
123
+ result,
124
+ 'hasTitle',
125
+ RULES.hasTitle.severity,
126
+ 'Missing H1 title (should start with "# Title")'
127
+ );
128
+ }
129
+ }
130
+
131
+ // Rule: Required sections
132
+ if (RULES.requiredSections.enabled) {
133
+ RULES.requiredSections.sections.forEach((section) => {
134
+ const sectionPattern = new RegExp(`^##\\s+${section}`, 'mi');
135
+ if (!sectionPattern.test(content)) {
136
+ addIssue(
137
+ result,
138
+ 'requiredSections',
139
+ RULES.requiredSections.severity,
140
+ `Missing required section: "## ${section}"`
141
+ );
142
+ }
143
+ });
144
+ }
145
+
146
+ // Rule: Trigger format validation
147
+ if (RULES.triggerFormat.enabled) {
148
+ const triggerSection = extractSection(content, 'Trigger');
149
+ if (triggerSection) {
150
+ const hasBullets = /[-*]\s+["'].+["']/.test(triggerSection);
151
+ if (!hasBullets) {
152
+ const lineNum = findSectionLine(lines, 'Trigger');
153
+ addIssue(
154
+ result,
155
+ 'triggerFormat',
156
+ RULES.triggerFormat.severity,
157
+ 'Trigger section should have bullet points with quoted phrases (e.g., - "keyword")',
158
+ lineNum
159
+ );
160
+ }
161
+ }
162
+ }
163
+
164
+ // Rule: Code blocks should have language
165
+ if (RULES.codeBlocks.enabled) {
166
+ // Track fence open/close state so we only flag OPENING fences that lack a
167
+ // language specifier. Closing fences are always bare ``` and must never be
168
+ // flagged (the previous next-line heuristic mis-flagged every closing fence).
169
+ let inFence = false;
170
+ lines.forEach((line, index) => {
171
+ const trimmed = line.trim();
172
+ if (!trimmed.startsWith('```')) {
173
+ return;
174
+ }
175
+ if (inFence) {
176
+ inFence = false; // closing fence — carries no language by definition
177
+ return;
178
+ }
179
+ inFence = true; // opening fence
180
+ if (trimmed === '```') {
181
+ addIssue(
182
+ result,
183
+ 'codeBlocks',
184
+ RULES.codeBlocks.severity,
185
+ 'Code block missing language specifier (e.g., ```dax)',
186
+ index + 1
187
+ );
188
+ }
189
+ });
190
+ }
191
+
192
+ // Rule: Check internal links
193
+ if (RULES.brokenLinks.enabled) {
194
+ const linkPattern = /\[([^\]]+)\]\(([^)]+)\)/g;
195
+ let match;
196
+ while ((match = linkPattern.exec(content)) !== null) {
197
+ const linkPath = match[2];
198
+ // Only check relative markdown links
199
+ if (linkPath.endsWith('.md') && !linkPath.startsWith('http')) {
200
+ const resolvedPath = path.resolve(path.dirname(filePath), linkPath);
201
+ if (!fs.existsSync(resolvedPath)) {
202
+ const lineNum = findLineWithText(lines, match[0]);
203
+ addIssue(
204
+ result,
205
+ 'brokenLinks',
206
+ RULES.brokenLinks.severity,
207
+ `Broken internal link: ${linkPath}`,
208
+ lineNum
209
+ );
210
+ }
211
+ }
212
+ }
213
+ }
214
+
215
+ return result;
216
+ }
217
+
218
+ /**
219
+ * Add an issue to the result
220
+ * @param {Object} result - Result object
221
+ * @param {string} rule - Rule name
222
+ * @param {string} severity - 'error' or 'warning'
223
+ * @param {string} message - Issue message
224
+ * @param {number} [line] - Line number
225
+ */
226
+ function addIssue(result, rule, severity, message, line) {
227
+ const issue = { rule, message };
228
+ if (line) issue.line = line;
229
+
230
+ if (severity === 'error') {
231
+ result.errors.push(issue);
232
+ } else {
233
+ result.warnings.push(issue);
234
+ }
235
+ }
236
+
237
+ /**
238
+ * Extract a section from markdown content
239
+ * @param {string} content - Markdown content
240
+ * @param {string} sectionName - Section name (without ##)
241
+ * @returns {string|null} Section content or null
242
+ */
243
+ function extractSection(content, sectionName) {
244
+ // Locate the section heading first, then slice from there to the next
245
+ // H2 heading or horizontal rule. The earlier regex used a multiline
246
+ // `$` as a stop anchor, which matches end of LINE — so it returned
247
+ // only the heading line and dropped the body, breaking downstream
248
+ // rules like triggerFormat that inspect the body.
249
+ const headingMatch = new RegExp(`^##\\s+${sectionName}\\b`, 'mi').exec(content);
250
+ if (!headingMatch) return null;
251
+ const tail = content.slice(headingMatch.index);
252
+ const next = tail.search(/\n##\s+|\n---+\s*\n/);
253
+ return next === -1 ? tail : tail.slice(0, next);
254
+ }
255
+
256
+ /**
257
+ * Find line number of a section
258
+ * @param {string[]} lines - Array of lines
259
+ * @param {string} sectionName - Section name
260
+ * @returns {number|null} Line number or null
261
+ */
262
+ function findSectionLine(lines, sectionName) {
263
+ for (let i = 0; i < lines.length; i++) {
264
+ if (new RegExp(`^##\\s+${sectionName}`, 'i').test(lines[i])) {
265
+ return i + 1;
266
+ }
267
+ }
268
+ return null;
269
+ }
270
+
271
+ /**
272
+ * Find line number containing text
273
+ * @param {string[]} lines - Array of lines
274
+ * @param {string} text - Text to find
275
+ * @returns {number|null} Line number or null
276
+ */
277
+ function findLineWithText(lines, text) {
278
+ for (let i = 0; i < lines.length; i++) {
279
+ if (lines[i].includes(text)) {
280
+ return i + 1;
281
+ }
282
+ }
283
+ return null;
284
+ }
285
+
286
+ /**
287
+ * Parse command line arguments
288
+ * @param {string[]} args - CLI arguments
289
+ * @returns {Object} Parsed options
290
+ */
291
+ function parseArgs(args) {
292
+ const options = {
293
+ files: [],
294
+ fix: false,
295
+ json: false,
296
+ };
297
+
298
+ for (let i = 0; i < args.length; i++) {
299
+ const arg = args[i];
300
+
301
+ if (arg === '--fix') {
302
+ options.fix = true;
303
+ } else if (arg === '--json') {
304
+ options.json = true;
305
+ } else if (!arg.startsWith('-')) {
306
+ options.files.push(arg);
307
+ }
308
+ }
309
+
310
+ return options;
311
+ }
312
+
313
+ /**
314
+ * Display lint summary
315
+ * @param {Object[]} results - Array of lint results
316
+ */
317
+ function displaySummary(results) {
318
+ const totalErrors = results.reduce((sum, r) => sum + r.errors.length, 0);
319
+ const totalWarnings = results.reduce((sum, r) => sum + r.warnings.length, 0);
320
+ const filesWithIssues = results.filter(
321
+ (r) => r.errors.length > 0 || r.warnings.length > 0
322
+ ).length;
323
+
324
+ console.log('');
325
+ tui.section('Summary');
326
+
327
+ const table = tui.createTable(
328
+ ['Metric', 'Count'],
329
+ [
330
+ ['Files checked', results.length.toString()],
331
+ ['Files with issues', filesWithIssues.toString()],
332
+ ['Errors', tui.colors.error(totalErrors.toString())],
333
+ ['Warnings', tui.colors.warning(totalWarnings.toString())],
334
+ ]
335
+ );
336
+ console.log(table);
337
+
338
+ if (totalErrors > 0) {
339
+ console.log(`\n${tui.icons.error} ${tui.colors.error(`${totalErrors} error(s) found`)}`);
340
+ } else if (totalWarnings > 0) {
341
+ console.log(
342
+ `\n${tui.icons.warning} ${tui.colors.warning(`${totalWarnings} warning(s) found`)}`
343
+ );
344
+ } else {
345
+ console.log(`\n${tui.icons.success} ${tui.colors.success('All skills passed validation!')}`);
346
+ }
347
+ }
348
+
349
+ /**
350
+ * Main lint command handler
351
+ * @param {string[]} args - Command arguments
352
+ * @param {Object} config - CLI configuration with paths
353
+ */
354
+ function lintCommand(args, config) {
355
+ const options = parseArgs(args);
356
+
357
+ // Try cache directory first, fall back to local skills
358
+ let skillsDir = config.skillsDir;
359
+ const localSkills = path.join(config.packageDir, '.agents', 'prompts', 'skills');
360
+
361
+ if (!fs.existsSync(skillsDir)) {
362
+ if (fs.existsSync(localSkills)) {
363
+ skillsDir = localSkills;
364
+ } else {
365
+ tui.error('Skills directory not found. Try reinstalling: npm install -g bi-superpowers');
366
+ process.exit(1);
367
+ }
368
+ }
369
+
370
+ tui.header('BI Agent Superpowers', 'Skill Linter');
371
+
372
+ // Determine which files to lint. Use the shared skill loader so we
373
+ // catch both flat (`<name>.md`) and folder-based (`<name>/SKILL.md`)
374
+ // skills — a previous version filtered with `f.endsWith('.md')` and
375
+ // silently skipped every folder-based skill.
376
+ const allSkills = readSkillDirectory(skillsDir);
377
+ const skillsByName = new Map(allSkills.map((s) => [s.name, s]));
378
+ let filesToLint = [];
379
+
380
+ if (options.files.length > 0) {
381
+ filesToLint = options.files
382
+ .map((f) => {
383
+ // Existing absolute / relative file path the user passed verbatim.
384
+ if (fs.existsSync(f) && fs.statSync(f).isFile()) {
385
+ return f;
386
+ }
387
+ // Look up by skill name. normalizeSkillName accepts `dax`,
388
+ // `dax.md`, `folder-skill`, or `folder-skill/SKILL.md`.
389
+ const skill = skillsByName.get(normalizeSkillName(f));
390
+ if (skill) return skill.path;
391
+
392
+ tui.warning(`Skill not found: ${f}`);
393
+ return null;
394
+ })
395
+ .filter(Boolean);
396
+ } else {
397
+ filesToLint = allSkills.map((s) => s.path);
398
+ }
399
+
400
+ if (filesToLint.length === 0) {
401
+ tui.warning('No skill files found to lint');
402
+ return;
403
+ }
404
+
405
+ tui.info(`Linting ${filesToLint.length} skill file(s)...`);
406
+ console.log('');
407
+
408
+ // Run linting
409
+ const results = filesToLint.map((file) => lintFile(file));
410
+
411
+ // Output results
412
+ if (options.json) {
413
+ console.log(JSON.stringify(results, null, 2));
414
+ return;
415
+ }
416
+
417
+ // Display individual results
418
+ results.forEach((result) => {
419
+ tui.lintResult(result);
420
+ });
421
+
422
+ // Display summary
423
+ displaySummary(results);
424
+
425
+ // Exit with error code if there are errors
426
+ const hasErrors = results.some((r) => r.errors.length > 0);
427
+ if (hasErrors) {
428
+ process.exit(1);
429
+ }
430
+ }
431
+
432
+ // Expose primitives for tests (B3 — replace fake tests with real ones).
433
+ module.exports = Object.assign(lintCommand, {
434
+ lintFile,
435
+ parseArgs,
436
+ extractSection,
437
+ findSectionLine,
438
+ findLineWithText,
439
+ addIssue,
440
+ RULES,
441
+ });
@@ -0,0 +1,255 @@
1
+ /**
2
+ * MCP Setup Command
3
+ * =================
4
+ * Configures the official Microsoft MCP servers for an existing project-local
5
+ * BI Superpowers plugin. Normal multi-agent setup is user-level via
6
+ * `super install --all --yes`; this command refuses arbitrary repo-local writes.
7
+ *
8
+ * Usage:
9
+ * super mcp-setup
10
+ * super mcp-setup --tool claude-plugin
11
+ * super mcp-setup --dry-run
12
+ */
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+ const tui = require('../utils/tui');
17
+ const mcpDetect = require('../utils/mcp-detect');
18
+ const {
19
+ ABSOLUTE_LAUNCHER_MODE,
20
+ PLUGIN_ROOT_LAUNCHER_MODE,
21
+ createMcpConfigForFormat,
22
+ mergeMcpConfig,
23
+ } = require('../lib/microsoft-mcp');
24
+ const { readJsonStrict, readJsoncStrict, writeJson } = require('../lib/mcp-config');
25
+
26
+ const MCP_CONFIGS = {
27
+ 'claude-plugin': {
28
+ name: 'Claude Code Plugin',
29
+ configPath: '.mcp.json',
30
+ format: 'plugin',
31
+ },
32
+ 'claude-code': {
33
+ name: 'Claude Code (legacy standalone)',
34
+ configPath: '.claude/settings.json',
35
+ format: 'claude',
36
+ },
37
+ cursor: {
38
+ name: 'Cursor (legacy)',
39
+ configPath: '.cursor/mcp.json',
40
+ format: 'cursor',
41
+ },
42
+ kilocode: {
43
+ name: 'Kilo Code (legacy)',
44
+ configPath: '.kilo/kilo.jsonc',
45
+ format: 'kilo',
46
+ },
47
+ 'open-code': {
48
+ name: 'OpenCode (legacy)',
49
+ configPath: 'opencode.config.json',
50
+ format: 'opencode',
51
+ },
52
+ vscode: {
53
+ name: 'VS Code (legacy)',
54
+ configPath: '.vscode/settings.json',
55
+ format: 'vscode',
56
+ },
57
+ };
58
+
59
+ function parseArgs(args) {
60
+ const options = {
61
+ tool: null,
62
+ dryRun: false,
63
+ targetDir: process.cwd(),
64
+ deprecatedFlags: [],
65
+ };
66
+
67
+ for (let index = 0; index < args.length; index++) {
68
+ const arg = args[index];
69
+
70
+ if (arg === '--tool' || arg === '-t') {
71
+ options.tool = args[++index];
72
+ } else if (arg === '--dry-run') {
73
+ options.dryRun = true;
74
+ } else if (arg === '--port' || arg === '-p' || arg === '--github' || arg === '-g') {
75
+ options.deprecatedFlags.push(arg);
76
+ if (args[index + 1] && !args[index + 1].startsWith('-')) {
77
+ index++;
78
+ }
79
+ } else if (!arg.startsWith('-')) {
80
+ options.targetDir = arg;
81
+ }
82
+ }
83
+
84
+ return options;
85
+ }
86
+
87
+ function loadConfiguredTools(targetDir) {
88
+ const configPath = path.join(targetDir, '.bi-superpowers.json');
89
+ if (fs.existsSync(configPath)) {
90
+ try {
91
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
92
+ if (Array.isArray(config.tools) && config.tools.length > 0) {
93
+ return Array.from(new Set(config.tools));
94
+ }
95
+ } catch (error) {
96
+ // Ignore invalid config and fall back below.
97
+ }
98
+ }
99
+
100
+ const pluginManifest = path.join(targetDir, '.claude-plugin', 'plugin.json');
101
+ if (fs.existsSync(pluginManifest)) {
102
+ return ['claude-plugin'];
103
+ }
104
+
105
+ return ['claude-plugin'];
106
+ }
107
+
108
+ function hasLocalPluginMarker(targetDir) {
109
+ return (
110
+ fs.existsSync(path.join(targetDir, '.bi-superpowers.json')) ||
111
+ fs.existsSync(path.join(targetDir, '.claude-plugin', 'plugin.json'))
112
+ );
113
+ }
114
+
115
+ function writeConfig(filePath, config, dryRun) {
116
+ if (dryRun) {
117
+ tui.info(`Would write: ${tui.formatPath(filePath)}`);
118
+ tui.muted(JSON.stringify(config, null, 2).slice(0, 220) + '...');
119
+ return true;
120
+ }
121
+
122
+ try {
123
+ writeJson(filePath, config);
124
+ return true;
125
+ } catch (error) {
126
+ tui.error(`Failed to write ${filePath}: ${error.message}`);
127
+ return false;
128
+ }
129
+ }
130
+
131
+ function getLauncherMode(targetDir, packageDir, tool) {
132
+ if (tool === 'claude-plugin' && path.resolve(targetDir) === path.resolve(packageDir)) {
133
+ return PLUGIN_ROOT_LAUNCHER_MODE;
134
+ }
135
+
136
+ return ABSOLUTE_LAUNCHER_MODE;
137
+ }
138
+
139
+ function mcpSetupCommand(args, config) {
140
+ const options = parseArgs(args);
141
+ const targetDir = path.resolve(options.targetDir);
142
+
143
+ tui.header('BI Agent Superpowers', 'Microsoft MCP Setup');
144
+
145
+ if (options.dryRun) {
146
+ tui.dryRunNotice();
147
+ }
148
+
149
+ if (options.deprecatedFlags.length > 0) {
150
+ tui.warning(
151
+ `Deprecated flags ignored: ${options.deprecatedFlags.join(', ')}. MCP setup now targets local Claude Code plugin configs and uses the official Microsoft servers.`
152
+ );
153
+ }
154
+
155
+ if (options.tool && !MCP_CONFIGS[options.tool]) {
156
+ tui.error(`Unknown tool: ${options.tool}`);
157
+ tui.info(`Available tools: ${Object.keys(MCP_CONFIGS).join(', ')}`);
158
+ process.exit(1);
159
+ }
160
+
161
+ if (!hasLocalPluginMarker(targetDir)) {
162
+ tui.warning('mcp-setup is only for existing project-local BI Superpowers plugin configs.');
163
+ tui.info(
164
+ 'For Codex, GitHub Copilot, Gemini CLI, Kilo Code, and Claude Code user-level installs, run:'
165
+ );
166
+ tui.listItem('super install --all --yes');
167
+ tui.info(
168
+ 'That writes user-level skills and MCP config under your home directory without creating files in this repo.'
169
+ );
170
+ tui.info(
171
+ 'If you intentionally need local Claude Code plugin files, run `super kickoff` first, then rerun `super mcp-setup` inside that initialized repo.'
172
+ );
173
+ process.exitCode = 2;
174
+ return;
175
+ }
176
+
177
+ let configuredTools = loadConfiguredTools(targetDir);
178
+
179
+ if (options.tool) {
180
+ configuredTools = [options.tool];
181
+ }
182
+
183
+ tui.section('Configured Outputs');
184
+ configuredTools.forEach((tool) => {
185
+ tui.success(MCP_CONFIGS[tool].name);
186
+ });
187
+
188
+ const status = mcpDetect.getMcpStatus();
189
+
190
+ tui.section('Official Microsoft MCP Status');
191
+ if (status.local.installed) {
192
+ tui.success(`Power BI Modeling MCP detected: ${status.local.path}`);
193
+ if (status.local.version) {
194
+ tui.info(`Version: ${status.local.version}`);
195
+ }
196
+ } else {
197
+ tui.warning('Power BI Modeling MCP not detected locally.');
198
+ tui.info(mcpDetect.getModelingMcpError());
199
+ }
200
+
201
+ tui.success('Microsoft Learn MCP: https://learn.microsoft.com/api/mcp');
202
+
203
+ const results = {
204
+ success: [],
205
+ failed: [],
206
+ };
207
+
208
+ tui.section('Writing Configurations');
209
+ configuredTools.forEach((tool) => {
210
+ const toolConfig = MCP_CONFIGS[tool];
211
+ const filePath = path.join(targetDir, toolConfig.configPath);
212
+ let ok = false;
213
+
214
+ try {
215
+ const existingConfig =
216
+ toolConfig.format === 'kilo'
217
+ ? readJsoncStrict(filePath) || {}
218
+ : readJsonStrict(filePath) || {};
219
+ const generatedConfig = createMcpConfigForFormat(toolConfig.format, {
220
+ packageDir: config.packageDir,
221
+ launcherMode: getLauncherMode(targetDir, config.packageDir, tool),
222
+ });
223
+ const mergedConfig = mergeMcpConfig(existingConfig, generatedConfig, toolConfig.format);
224
+ ok = writeConfig(filePath, mergedConfig, options.dryRun);
225
+ } catch (error) {
226
+ tui.error(`Failed to prepare ${filePath}: ${error.message}`);
227
+ }
228
+
229
+ if (ok) {
230
+ results.success.push(toolConfig.name);
231
+ tui.success(`${toolConfig.name}: ${tui.formatPath(toolConfig.configPath)}`);
232
+ } else {
233
+ results.failed.push(toolConfig.name);
234
+ }
235
+ });
236
+
237
+ console.log('');
238
+ tui.section('Next Steps');
239
+ tui.listItem(
240
+ 'Install the official Microsoft Power BI Modeling MCP extension in VS Code/Cursor on Windows if you need write access to Desktop/PBIP semantic models.'
241
+ );
242
+ tui.listItem('Refresh or restart your MCP client after config changes.');
243
+
244
+ if (configuredTools.includes('claude-plugin')) {
245
+ tui.listItem(`Run Claude Code with the plugin: claude --plugin-dir ${targetDir}`);
246
+ }
247
+
248
+ if (results.failed.length > 0) {
249
+ console.log('');
250
+ tui.warning(`Completed with failures: ${results.failed.join(', ')}`);
251
+ process.exit(1);
252
+ }
253
+ }
254
+
255
+ module.exports = mcpSetupCommand;