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,346 @@
1
+ /**
2
+ * MCP Detection Utilities for BI Agent Superpowers
3
+ * =================================================
4
+ *
5
+ * Detects installed MCP servers (Microsoft Power BI Modeling MCP).
6
+ * Covers the local (Windows) VS Code/Cursor extension install path.
7
+ *
8
+ * @module utils/mcp-detect
9
+ */
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ const os = require('os');
14
+ const { spawnSync } = require('child_process');
15
+ const { PLUGIN_ROOT_LAUNCHER_MODE, createMcpConfigForFormat } = require('../lib/microsoft-mcp');
16
+
17
+ /**
18
+ * Common installation paths for the Power BI Modeling MCP
19
+ */
20
+ const EXTENSION_PATTERNS = [
21
+ // VS Code extensions folder
22
+ path.join(os.homedir(), '.vscode', 'extensions'),
23
+ // Cursor extensions folder
24
+ path.join(os.homedir(), '.cursor', 'extensions'),
25
+ // VS Code Insiders
26
+ path.join(os.homedir(), '.vscode-insiders', 'extensions'),
27
+ // Manual installation path we suggest
28
+ path.join(os.homedir(), '.bi-superpowers', 'mcp'),
29
+ ];
30
+
31
+ /**
32
+ * Extension name pattern to search for
33
+ */
34
+ const EXTENSION_NAME_PATTERN = /^analysis-services\.powerbi-modeling-mcp-/;
35
+ const MODELING_MCP_EXE_NAME = 'powerbi-modeling-mcp.exe';
36
+
37
+ const MODELING_MCP_ENV_VARS = [
38
+ 'BI_SUPERPOWERS_POWERBI_MODELING_MCP_PATH',
39
+ 'POWERBI_MODELING_MCP_PATH',
40
+ 'PBI_MODELING_MCP_PATH',
41
+ ];
42
+
43
+ /**
44
+ * Resolve an explicitly configured MCP executable path, if any.
45
+ *
46
+ * @returns {string|null} Existing executable path
47
+ */
48
+ function getExplicitMcpPath() {
49
+ for (const envVar of MODELING_MCP_ENV_VARS) {
50
+ const configuredPath = normalizeConfiguredPath(process.env[envVar]);
51
+ if (configuredPath && isMcpExecutableFile(configuredPath)) {
52
+ return configuredPath;
53
+ }
54
+ }
55
+
56
+ return null;
57
+ }
58
+
59
+ /**
60
+ * Normalize common shell/user input around executable paths.
61
+ *
62
+ * @param {string|undefined} configuredPath - Environment variable value
63
+ * @returns {string|null} Trimmed path without surrounding quotes
64
+ */
65
+ function normalizeConfiguredPath(configuredPath) {
66
+ if (!configuredPath) {
67
+ return null;
68
+ }
69
+
70
+ const trimmedPath = configuredPath.trim();
71
+ const quotedPath = trimmedPath.match(/^"(.*)"$/);
72
+ return quotedPath ? quotedPath[1] : trimmedPath;
73
+ }
74
+
75
+ /**
76
+ * Check whether a path points to the official local Modeling MCP executable.
77
+ *
78
+ * @param {string|null} candidatePath - Candidate executable path
79
+ * @returns {boolean} True when the path is an executable file candidate
80
+ */
81
+ function isMcpExecutableFile(candidatePath) {
82
+ if (!candidatePath || path.basename(candidatePath).toLowerCase() !== MODELING_MCP_EXE_NAME) {
83
+ return false;
84
+ }
85
+
86
+ try {
87
+ return fs.statSync(candidatePath).isFile();
88
+ } catch (e) {
89
+ return false;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Parse the extension version from a Power BI Modeling MCP extension folder.
95
+ *
96
+ * @param {string} entry - Extension folder name
97
+ * @returns {number[]} Numeric semver parts, or [0, 0, 0] when absent
98
+ */
99
+ function getExtensionVersionParts(entry) {
100
+ const match = entry.match(/^analysis-services\.powerbi-modeling-mcp-(\d+)\.(\d+)\.(\d+)(?:-|$)/);
101
+
102
+ if (!match) {
103
+ return [0, 0, 0];
104
+ }
105
+
106
+ return match.slice(1).map((part) => Number.parseInt(part, 10));
107
+ }
108
+
109
+ /**
110
+ * Sort extension folder names newest-first, deterministically.
111
+ *
112
+ * @param {string[]} entries - Directory entries
113
+ * @returns {string[]} Matching extension folder names, newest first
114
+ */
115
+ function sortMcpExtensionEntries(entries) {
116
+ return entries
117
+ .filter((entry) => EXTENSION_NAME_PATTERN.test(entry))
118
+ .sort((left, right) => {
119
+ const leftVersion = getExtensionVersionParts(left);
120
+ const rightVersion = getExtensionVersionParts(right);
121
+
122
+ for (let index = 0; index < 3; index += 1) {
123
+ if (leftVersion[index] !== rightVersion[index]) {
124
+ return rightVersion[index] - leftVersion[index];
125
+ }
126
+ }
127
+
128
+ return left.localeCompare(right);
129
+ });
130
+ }
131
+
132
+ /**
133
+ * Resolve the executable path from one extension folder.
134
+ *
135
+ * @param {string} extensionsDir - Parent extensions directory
136
+ * @param {string} entry - Extension folder name
137
+ * @returns {string|null} Executable path when valid
138
+ */
139
+ function findMcpExecutableInExtensionEntry(extensionsDir, entry) {
140
+ const directExePath = path.join(extensionsDir, entry, 'server', MODELING_MCP_EXE_NAME);
141
+
142
+ if (isMcpExecutableFile(directExePath)) {
143
+ return directExePath;
144
+ }
145
+
146
+ const nestedExePath = path.join(
147
+ extensionsDir,
148
+ entry,
149
+ 'extension',
150
+ 'server',
151
+ MODELING_MCP_EXE_NAME
152
+ );
153
+
154
+ return isMcpExecutableFile(nestedExePath) ? nestedExePath : null;
155
+ }
156
+
157
+ /**
158
+ * Find the Power BI Modeling MCP executable
159
+ * @returns {string|null} Path to the executable or null if not found
160
+ */
161
+ function findLocalMcp() {
162
+ const explicitPath = getExplicitMcpPath();
163
+ if (explicitPath) {
164
+ return explicitPath;
165
+ }
166
+
167
+ if (os.platform() !== 'win32') {
168
+ return null;
169
+ }
170
+
171
+ for (const extensionsDir of EXTENSION_PATTERNS) {
172
+ if (!fs.existsSync(extensionsDir)) {
173
+ continue;
174
+ }
175
+
176
+ try {
177
+ const entries = sortMcpExtensionEntries(fs.readdirSync(extensionsDir));
178
+
179
+ for (const entry of entries) {
180
+ const exePath = findMcpExecutableInExtensionEntry(extensionsDir, entry);
181
+
182
+ if (exePath) {
183
+ return exePath;
184
+ }
185
+ }
186
+ } catch (e) {
187
+ // Ignore read errors
188
+ }
189
+ }
190
+
191
+ // Check if it's in PATH
192
+ try {
193
+ // No shell: `where` is a real executable on Windows and runs fine without
194
+ // one. Avoids a shell-injection footgun and a PATH-precedence surprise on
195
+ // the path that is later launched as a read/write MCP.
196
+ const result = spawnSync('where', ['powerbi-modeling-mcp.exe'], {
197
+ encoding: 'utf8',
198
+ });
199
+
200
+ if (result.status === 0 && result.stdout) {
201
+ const firstLine = result.stdout.trim().split('\n')[0];
202
+ if (isMcpExecutableFile(firstLine)) {
203
+ return firstLine;
204
+ }
205
+ }
206
+ } catch (e) {
207
+ // Ignore errors
208
+ }
209
+
210
+ return null;
211
+ }
212
+
213
+ /**
214
+ * Get version from MCP executable
215
+ * @param {string} exePath - Path to the executable
216
+ * @returns {string|null} Version string or null
217
+ */
218
+ function getMcpVersion(exePath) {
219
+ if (!exePath || !fs.existsSync(exePath)) {
220
+ return null;
221
+ }
222
+
223
+ try {
224
+ const result = spawnSync(exePath, ['--version'], {
225
+ encoding: 'utf8',
226
+ timeout: 5000,
227
+ });
228
+
229
+ if (result.stdout) {
230
+ const match = result.stdout.match(/\d+\.\d+\.\d+/);
231
+ return match ? match[0] : null;
232
+ }
233
+ } catch (e) {
234
+ // Ignore errors
235
+ }
236
+
237
+ // Try to extract version from path
238
+ const match = exePath.match(/powerbi-modeling-mcp-(\d+\.\d+\.\d+)/);
239
+ return match ? match[1] : null;
240
+ }
241
+
242
+ /**
243
+ * Get full MCP status for the local Power BI Modeling MCP launcher.
244
+ * @returns {Object} Status object
245
+ */
246
+ function getMcpStatus() {
247
+ const localPath = findLocalMcp();
248
+
249
+ return {
250
+ local: {
251
+ installed: !!localPath,
252
+ path: localPath,
253
+ version: getMcpVersion(localPath),
254
+ platform: os.platform(),
255
+ available: os.platform() === 'win32',
256
+ envVars: MODELING_MCP_ENV_VARS,
257
+ },
258
+ };
259
+ }
260
+
261
+ /**
262
+ * Get installation instructions for local MCP
263
+ * @returns {Object} Installation instructions
264
+ */
265
+ function getInstallInstructions() {
266
+ return {
267
+ title: 'Power BI Modeling MCP not detected',
268
+ options: [
269
+ {
270
+ name: 'VS Code / Cursor',
271
+ steps: [
272
+ 'Open VS Code or Cursor',
273
+ 'Go to Extensions (Ctrl+Shift+X)',
274
+ 'Search for "Power BI Modeling MCP"',
275
+ 'Install the Microsoft extension',
276
+ 'Run: super install --all --yes',
277
+ ],
278
+ link: 'https://aka.ms/powerbi-modeling-mcp-vscode',
279
+ },
280
+ {
281
+ name: 'Manual',
282
+ steps: [
283
+ 'Download the VSIX from VS Code Marketplace',
284
+ 'Rename .vsix to .zip',
285
+ `Extract to ${path.join(os.homedir(), '.bi-superpowers', 'mcp')}`,
286
+ 'Set BI_SUPERPOWERS_POWERBI_MODELING_MCP_PATH to the .exe path',
287
+ ],
288
+ link: 'https://marketplace.visualstudio.com/items?itemName=analysis-services.powerbi-modeling-mcp',
289
+ },
290
+ ],
291
+ note:
292
+ os.platform() !== 'win32'
293
+ ? 'The local MCP is only available on Windows. On macOS/Linux, microsoft-learn still provides official docs.'
294
+ : null,
295
+ };
296
+ }
297
+
298
+ /**
299
+ * Build an actionable error for environments where the local Modeling MCP
300
+ * executable isn't available.
301
+ *
302
+ * @returns {string} Human-friendly error message
303
+ */
304
+ function getModelingMcpError() {
305
+ if (os.platform() !== 'win32') {
306
+ return [
307
+ 'Power BI Modeling MCP is only available on Windows.',
308
+ 'You still get the microsoft-learn MCP on macOS/Linux.',
309
+ 'If you are on Windows and extracted the server manually, set BI_SUPERPOWERS_POWERBI_MODELING_MCP_PATH.',
310
+ ].join('\n');
311
+ }
312
+
313
+ return [
314
+ 'Unable to locate the official Microsoft Power BI Modeling MCP executable.',
315
+ 'Install the "Power BI Modeling MCP" extension in VS Code or Cursor, or set BI_SUPERPOWERS_POWERBI_MODELING_MCP_PATH to powerbi-modeling-mcp.exe.',
316
+ ].join('\n');
317
+ }
318
+
319
+ /**
320
+ * Backward-compatible config generator retained for legacy callers/tests.
321
+ *
322
+ * @param {Object} _status - Unused, kept for compatibility
323
+ * @param {string} format - Config format (cursor, claude, vscode, etc.)
324
+ * @param {Object} [options] - Additional generation options
325
+ * @returns {Object} Configuration object
326
+ */
327
+ function generateMcpConfig(_status, format, options = {}) {
328
+ return createMcpConfigForFormat(format, {
329
+ packageDir: options.packageDir,
330
+ launcherMode: options.launcherMode || PLUGIN_ROOT_LAUNCHER_MODE,
331
+ });
332
+ }
333
+
334
+ module.exports = {
335
+ findLocalMcp,
336
+ getMcpVersion,
337
+ getMcpStatus,
338
+ getInstallInstructions,
339
+ generateMcpConfig,
340
+ getExplicitMcpPath,
341
+ getModelingMcpError,
342
+ isMcpExecutableFile,
343
+ sortMcpExtensionEntries,
344
+ findMcpExecutableInExtensionEntry,
345
+ MODELING_MCP_ENV_VARS,
346
+ };
@@ -0,0 +1,314 @@
1
+ /**
2
+ * TUI Utilities - Rich terminal UI helpers
3
+ * =========================================
4
+ * Provides consistent styling and formatting for CLI output.
5
+ */
6
+
7
+ const chalk = require('chalk');
8
+ const boxen = require('boxen');
9
+ const Table = require('cli-table3');
10
+
11
+ // Color scheme
12
+ const colors = {
13
+ primary: chalk.cyan,
14
+ success: chalk.green,
15
+ error: chalk.red,
16
+ warning: chalk.yellow,
17
+ info: chalk.blue,
18
+ muted: chalk.gray,
19
+ highlight: chalk.bold.white,
20
+ code: chalk.magenta,
21
+ };
22
+
23
+ // Icons
24
+ const icons = {
25
+ success: chalk.green('✓'),
26
+ error: chalk.red('✗'),
27
+ warning: chalk.yellow('⚠'),
28
+ info: chalk.blue('ℹ'),
29
+ bullet: chalk.cyan('•'),
30
+ arrow: chalk.cyan('→'),
31
+ skill: '📚',
32
+ snippet: '📝',
33
+ theme: '🎨',
34
+ search: '🔍',
35
+ lint: '🔬',
36
+ diff: '📊',
37
+ watch: '👁',
38
+ };
39
+
40
+ /**
41
+ * Print a success message
42
+ * @param {string} message - Message to display
43
+ */
44
+ function success(message) {
45
+ console.log(`${icons.success} ${message}`);
46
+ }
47
+
48
+ /**
49
+ * Print an error message
50
+ * @param {string} message - Message to display
51
+ */
52
+ function error(message) {
53
+ console.log(`${icons.error} ${colors.error(message)}`);
54
+ }
55
+
56
+ /**
57
+ * Print a warning message
58
+ * @param {string} message - Message to display
59
+ */
60
+ function warning(message) {
61
+ console.log(`${icons.warning} ${colors.warning(message)}`);
62
+ }
63
+
64
+ /**
65
+ * Print an info message
66
+ * @param {string} message - Message to display
67
+ */
68
+ function info(message) {
69
+ console.log(`${icons.info} ${colors.info(message)}`);
70
+ }
71
+
72
+ /**
73
+ * Print a muted message
74
+ * @param {string} message - Message to display
75
+ */
76
+ function muted(message) {
77
+ console.log(colors.muted(message));
78
+ }
79
+
80
+ /**
81
+ * Print a header box
82
+ * @param {string} title - Title text
83
+ * @param {string} [subtitle] - Optional subtitle
84
+ */
85
+ function header(title, subtitle) {
86
+ const content = subtitle
87
+ ? `${colors.highlight(title)}\n${colors.muted(subtitle)}`
88
+ : colors.highlight(title);
89
+
90
+ console.log(
91
+ boxen(content, {
92
+ padding: 1,
93
+ margin: { top: 1, bottom: 1 },
94
+ borderStyle: 'round',
95
+ borderColor: 'cyan',
96
+ })
97
+ );
98
+ }
99
+
100
+ /**
101
+ * Print a section header
102
+ * @param {string} title - Section title
103
+ */
104
+ function section(title) {
105
+ console.log(`\n${colors.primary(title)}`);
106
+ console.log(colors.muted('─'.repeat(title.length + 4)));
107
+ }
108
+
109
+ /**
110
+ * Create a table for displaying data
111
+ * @param {string[]} headers - Table headers
112
+ * @param {string[][]} rows - Table rows
113
+ * @param {Object} [options] - Additional options
114
+ * @returns {string} Formatted table string
115
+ */
116
+ function createTable(headers, rows, options = {}) {
117
+ const table = new Table({
118
+ head: headers.map((h) => colors.primary(h)),
119
+ style: {
120
+ head: [],
121
+ border: ['gray'],
122
+ },
123
+ ...options,
124
+ });
125
+
126
+ rows.forEach((row) => table.push(row));
127
+ return table.toString();
128
+ }
129
+
130
+ /**
131
+ * Format a file path for display
132
+ * @param {string} filePath - File path to format
133
+ * @returns {string} Formatted path
134
+ */
135
+ function formatPath(filePath) {
136
+ return colors.code(filePath);
137
+ }
138
+
139
+ /**
140
+ * Format a code snippet for display
141
+ * @param {string} code - Code to format
142
+ * @param {string} [language] - Optional language hint
143
+ * @returns {string} Formatted code
144
+ */
145
+ function formatCode(code, language) {
146
+ const prefix = language ? colors.muted(`[${language}] `) : '';
147
+ return `${prefix}${colors.code(code)}`;
148
+ }
149
+
150
+ /**
151
+ * Print a key-value pair
152
+ * @param {string} key - Key/label
153
+ * @param {string} value - Value
154
+ */
155
+ function keyValue(key, value) {
156
+ console.log(` ${colors.muted(key + ':')} ${value}`);
157
+ }
158
+
159
+ /**
160
+ * Print a list item
161
+ * @param {string} text - Item text
162
+ * @param {number} [indent=0] - Indentation level
163
+ */
164
+ function listItem(text, indent = 0) {
165
+ const padding = ' '.repeat(indent);
166
+ console.log(`${padding}${icons.bullet} ${text}`);
167
+ }
168
+
169
+ /**
170
+ * Print a diff line (addition)
171
+ * @param {string} text - Line text
172
+ */
173
+ function diffAdd(text) {
174
+ console.log(colors.success(`+ ${text}`));
175
+ }
176
+
177
+ /**
178
+ * Print a diff line (deletion)
179
+ * @param {string} text - Line text
180
+ */
181
+ function diffRemove(text) {
182
+ console.log(colors.error(`- ${text}`));
183
+ }
184
+
185
+ /**
186
+ * Print a diff line (unchanged)
187
+ * @param {string} text - Line text
188
+ */
189
+ function diffUnchanged(text) {
190
+ console.log(colors.muted(` ${text}`));
191
+ }
192
+
193
+ /**
194
+ * Print search result
195
+ * @param {Object} result - Search result object
196
+ * @param {string} result.title - Result title
197
+ * @param {string} result.path - File path
198
+ * @param {string} result.preview - Preview text
199
+ * @param {number} result.score - Match score
200
+ */
201
+ function searchResult(result) {
202
+ console.log(`\n${icons.search} ${colors.highlight(result.title)}`);
203
+ console.log(` ${colors.muted(result.path)}`);
204
+ if (result.preview) {
205
+ console.log(` ${colors.muted(result.preview.substring(0, 100))}...`);
206
+ }
207
+ if (result.score !== undefined) {
208
+ console.log(` ${colors.muted('Score:')} ${result.score.toFixed(2)}`);
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Print lint result
214
+ * @param {Object} result - Lint result
215
+ * @param {string} result.file - File name
216
+ * @param {Object[]} result.errors - Array of errors
217
+ * @param {Object[]} result.warnings - Array of warnings
218
+ */
219
+ function lintResult(result) {
220
+ const hasIssues = result.errors.length > 0 || result.warnings.length > 0;
221
+
222
+ if (!hasIssues) {
223
+ console.log(`${icons.success} ${formatPath(result.file)}`);
224
+ return;
225
+ }
226
+
227
+ console.log(`\n${formatPath(result.file)}`);
228
+
229
+ result.errors.forEach((err) => {
230
+ console.log(` ${icons.error} ${colors.error(err.message)}`);
231
+ if (err.line) {
232
+ console.log(` ${colors.muted(`Line ${err.line}`)}`);
233
+ }
234
+ });
235
+
236
+ result.warnings.forEach((warn) => {
237
+ console.log(` ${icons.warning} ${colors.warning(warn.message)}`);
238
+ if (warn.line) {
239
+ console.log(` ${colors.muted(`Line ${warn.line}`)}`);
240
+ }
241
+ });
242
+ }
243
+
244
+ /**
245
+ * Print a summary box
246
+ * @param {Object} summary - Summary data
247
+ * @param {string} summary.title - Summary title
248
+ * @param {Object} summary.stats - Key-value stats
249
+ */
250
+ function summaryBox(summary) {
251
+ let content = colors.highlight(summary.title) + '\n\n';
252
+
253
+ Object.entries(summary.stats).forEach(([key, value]) => {
254
+ content += `${colors.muted(key + ':')} ${value}\n`;
255
+ });
256
+
257
+ console.log(
258
+ boxen(content.trim(), {
259
+ padding: 1,
260
+ margin: { top: 1, bottom: 1 },
261
+ borderStyle: 'round',
262
+ borderColor: 'green',
263
+ })
264
+ );
265
+ }
266
+
267
+ /**
268
+ * Print dry-run notice
269
+ */
270
+ function dryRunNotice() {
271
+ console.log(
272
+ boxen(colors.warning('DRY RUN MODE\n') + colors.muted('No files will be created or modified'), {
273
+ padding: 1,
274
+ borderStyle: 'round',
275
+ borderColor: 'yellow',
276
+ })
277
+ );
278
+ }
279
+
280
+ /**
281
+ * Truncate text with ellipsis
282
+ * @param {string} text - Text to truncate
283
+ * @param {number} maxLength - Maximum length
284
+ * @returns {string} Truncated text
285
+ */
286
+ function truncate(text, maxLength) {
287
+ if (text.length <= maxLength) return text;
288
+ return text.substring(0, maxLength - 3) + '...';
289
+ }
290
+
291
+ module.exports = {
292
+ colors,
293
+ icons,
294
+ success,
295
+ error,
296
+ warning,
297
+ info,
298
+ muted,
299
+ header,
300
+ section,
301
+ createTable,
302
+ formatPath,
303
+ formatCode,
304
+ keyValue,
305
+ listItem,
306
+ diffAdd,
307
+ diffRemove,
308
+ diffUnchanged,
309
+ searchResult,
310
+ lintResult,
311
+ summaryBox,
312
+ dryRunNotice,
313
+ truncate,
314
+ };