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,426 @@
1
+ /**
2
+ * Project Validation Command
3
+ * ==========================
4
+ *
5
+ * Validates public fixtures and private project references without copying
6
+ * customer repositories into this repo. Versioned descriptors live under
7
+ * validation/projects/*.json; private paths live in validation.local.json,
8
+ * which is intentionally ignored by git.
9
+ *
10
+ * Usage:
11
+ * super validate-projects
12
+ * super validate-projects --project base-template
13
+ * super validate-projects --root C:\path\to\bi-superpowers
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+
19
+ const DEFAULT_VALIDATION_DIR = 'validation';
20
+ const DEFAULT_LOCAL_CONFIG = 'validation.local.json';
21
+
22
+ function parseArgs(args) {
23
+ const options = {
24
+ rootDir: process.cwd(),
25
+ localConfigPath: null,
26
+ projectIds: [],
27
+ json: false,
28
+ list: false,
29
+ strict: false,
30
+ };
31
+
32
+ for (let index = 0; index < args.length; index++) {
33
+ const arg = args[index];
34
+
35
+ if (arg === '--root') {
36
+ options.rootDir = readValue(args, ++index, arg);
37
+ } else if (arg === '--local') {
38
+ options.localConfigPath = readValue(args, ++index, arg);
39
+ } else if (arg === '--project' || arg === '-p') {
40
+ options.projectIds.push(readValue(args, ++index, arg));
41
+ } else if (arg === '--json') {
42
+ options.json = true;
43
+ } else if (arg === '--list') {
44
+ options.list = true;
45
+ } else if (arg === '--strict') {
46
+ options.strict = true;
47
+ }
48
+ }
49
+
50
+ options.rootDir = path.resolve(options.rootDir);
51
+ if (options.localConfigPath) {
52
+ options.localConfigPath = path.resolve(options.localConfigPath);
53
+ }
54
+ return options;
55
+ }
56
+
57
+ function readValue(args, index, flag) {
58
+ const value = args[index];
59
+ if (!value || value.startsWith('-')) {
60
+ throw new Error(`${flag} requires a value`);
61
+ }
62
+ return value;
63
+ }
64
+
65
+ function readJsonStrict(filePath) {
66
+ try {
67
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
68
+ } catch (err) {
69
+ throw new Error(`Cannot read JSON at ${filePath}: ${err.message}`);
70
+ }
71
+ }
72
+
73
+ function getValidationProjectsDir(rootDir) {
74
+ return path.join(rootDir, DEFAULT_VALIDATION_DIR, 'projects');
75
+ }
76
+
77
+ function getLocalConfigPath(rootDir, overridePath) {
78
+ return overridePath || path.join(rootDir, DEFAULT_LOCAL_CONFIG);
79
+ }
80
+
81
+ function loadProjectDescriptors(rootDir) {
82
+ const projectsDir = getValidationProjectsDir(rootDir);
83
+ if (!fs.existsSync(projectsDir)) {
84
+ throw new Error(
85
+ `Validation project descriptors not found at ${projectsDir}. ` +
86
+ 'Run this command from the bi-superpowers source checkout or pass --root <repo>.'
87
+ );
88
+ }
89
+
90
+ const descriptorFiles = fs.readdirSync(projectsDir).filter(isDescriptorFile).sort();
91
+
92
+ if (descriptorFiles.length === 0) {
93
+ throw new Error(`No validation project descriptors found in ${projectsDir}.`);
94
+ }
95
+
96
+ return descriptorFiles.map((file) => {
97
+ const filePath = path.join(projectsDir, file);
98
+ const descriptor = readJsonStrict(filePath);
99
+ validateDescriptor(descriptor, filePath);
100
+ return { ...descriptor, descriptorPath: filePath };
101
+ });
102
+ }
103
+
104
+ function isDescriptorFile(file) {
105
+ return file.endsWith('.json') && !file.endsWith('.example.json');
106
+ }
107
+
108
+ function validateDescriptor(descriptor, filePath) {
109
+ if (!descriptor || typeof descriptor !== 'object' || Array.isArray(descriptor)) {
110
+ throw new Error(`Project descriptor must be an object: ${filePath}`);
111
+ }
112
+ if (!isValidProjectId(descriptor.id)) {
113
+ throw new Error(`Project descriptor has invalid id at ${filePath}`);
114
+ }
115
+ if (!descriptor.name || typeof descriptor.name !== 'string') {
116
+ throw new Error(`Project descriptor ${descriptor.id} must include a name`);
117
+ }
118
+ if (descriptor.path != null && typeof descriptor.path !== 'string') {
119
+ throw new Error(`Project descriptor ${descriptor.id} path must be a string`);
120
+ }
121
+ if (descriptor.path != null && path.isAbsolute(descriptor.path)) {
122
+ throw new Error(
123
+ `Project descriptor ${descriptor.id} path must be relative. Put private absolute paths in validation.local.json.`
124
+ );
125
+ }
126
+ if (descriptor.skills != null && !isStringArray(descriptor.skills)) {
127
+ throw new Error(`Project descriptor ${descriptor.id} skills must be an array of strings`);
128
+ }
129
+ if (descriptor.checks != null && !Array.isArray(descriptor.checks)) {
130
+ throw new Error(`Project descriptor ${descriptor.id} checks must be an array`);
131
+ }
132
+ for (const check of descriptor.checks || []) {
133
+ if (!check || typeof check !== 'object' || Array.isArray(check)) {
134
+ throw new Error(`Project descriptor ${descriptor.id} has an invalid check`);
135
+ }
136
+ if (!check.name || typeof check.name !== 'string') {
137
+ throw new Error(`Project descriptor ${descriptor.id} has a check without a name`);
138
+ }
139
+ if (!check.path || typeof check.path !== 'string') {
140
+ throw new Error(`Project descriptor ${descriptor.id} check ${check.name} needs a path`);
141
+ }
142
+ if (path.isAbsolute(check.path)) {
143
+ throw new Error(`Project descriptor ${descriptor.id} check ${check.name} must be relative`);
144
+ }
145
+ }
146
+ }
147
+
148
+ function isValidProjectId(value) {
149
+ return typeof value === 'string' && /^[a-z0-9][a-z0-9-]*$/.test(value);
150
+ }
151
+
152
+ function isStringArray(value) {
153
+ return Array.isArray(value) && value.every((entry) => typeof entry === 'string');
154
+ }
155
+
156
+ function loadLocalConfig(rootDir, overridePath) {
157
+ const localPath = getLocalConfigPath(rootDir, overridePath);
158
+ if (!fs.existsSync(localPath)) {
159
+ return { path: localPath, projects: {} };
160
+ }
161
+
162
+ const config = readJsonStrict(localPath);
163
+ if (!config || typeof config !== 'object' || Array.isArray(config)) {
164
+ throw new Error(`Local validation config must be an object: ${localPath}`);
165
+ }
166
+ if (config.projects == null) {
167
+ return { path: localPath, projects: {} };
168
+ }
169
+ if (typeof config.projects !== 'object' || Array.isArray(config.projects)) {
170
+ throw new Error(`Local validation config projects must be an object: ${localPath}`);
171
+ }
172
+
173
+ for (const [projectId, project] of Object.entries(config.projects)) {
174
+ if (!isValidProjectId(projectId)) {
175
+ throw new Error(`Local validation config has invalid project id: ${projectId}`);
176
+ }
177
+ if (!project || typeof project !== 'object' || Array.isArray(project)) {
178
+ throw new Error(`Local validation project ${projectId} must be an object`);
179
+ }
180
+ if (!project.path || typeof project.path !== 'string') {
181
+ throw new Error(`Local validation project ${projectId} must include a path`);
182
+ }
183
+ }
184
+
185
+ return { path: localPath, projects: config.projects };
186
+ }
187
+
188
+ function mergeProjects(descriptors, localProjects) {
189
+ const merged = new Map();
190
+
191
+ for (const descriptor of descriptors) {
192
+ const local = localProjects[descriptor.id] || {};
193
+ merged.set(descriptor.id, {
194
+ ...descriptor,
195
+ path: local.path || descriptor.path,
196
+ localOnly: false,
197
+ localNotes: local.notes,
198
+ });
199
+ }
200
+
201
+ for (const [id, local] of Object.entries(localProjects)) {
202
+ if (merged.has(id)) {
203
+ continue;
204
+ }
205
+ merged.set(id, {
206
+ id,
207
+ name: local.name || id,
208
+ privacy: 'private-local',
209
+ path: local.path,
210
+ skills: local.skills || [],
211
+ checks: local.checks || [],
212
+ localOnly: true,
213
+ localNotes: local.notes,
214
+ });
215
+ }
216
+
217
+ return Array.from(merged.values()).sort((a, b) => a.id.localeCompare(b.id));
218
+ }
219
+
220
+ function resolveProjectPath(rootDir, projectPath) {
221
+ if (!projectPath) {
222
+ return null;
223
+ }
224
+ return path.isAbsolute(projectPath)
225
+ ? path.normalize(projectPath)
226
+ : path.resolve(rootDir, projectPath);
227
+ }
228
+
229
+ function validateProject(project, rootDir) {
230
+ const resolvedPath = resolveProjectPath(rootDir, project.path);
231
+ const result = {
232
+ id: project.id,
233
+ name: project.name,
234
+ privacy: project.privacy || 'unspecified',
235
+ path: resolvedPath,
236
+ status: 'passed',
237
+ reason: null,
238
+ checks: [],
239
+ };
240
+
241
+ if (!resolvedPath) {
242
+ result.status = 'skipped';
243
+ result.reason = 'No path configured. Add this project to validation.local.json.';
244
+ return result;
245
+ }
246
+
247
+ if (!fs.existsSync(resolvedPath)) {
248
+ result.status = 'failed';
249
+ result.reason = `Project path does not exist: ${resolvedPath}`;
250
+ return result;
251
+ }
252
+
253
+ for (const check of project.checks || []) {
254
+ const checkPath = path.resolve(resolvedPath, check.path);
255
+ if (!isPathInside(resolvedPath, checkPath)) {
256
+ result.checks.push({
257
+ name: check.name,
258
+ path: checkPath,
259
+ passed: false,
260
+ reason: 'Check path escapes the project root.',
261
+ });
262
+ continue;
263
+ }
264
+ const passed = fs.existsSync(checkPath);
265
+ result.checks.push({
266
+ name: check.name,
267
+ path: checkPath,
268
+ passed,
269
+ });
270
+ }
271
+
272
+ if (result.checks.some((check) => !check.passed)) {
273
+ result.status = 'failed';
274
+ result.reason = 'One or more required project files are missing.';
275
+ }
276
+
277
+ return result;
278
+ }
279
+
280
+ function isPathInside(parentPath, childPath) {
281
+ const relative = path.relative(parentPath, childPath);
282
+ return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
283
+ }
284
+
285
+ function runValidation(options) {
286
+ const descriptors = loadProjectDescriptors(options.rootDir);
287
+ const localConfig = loadLocalConfig(options.rootDir, options.localConfigPath);
288
+ const projects = mergeProjects(descriptors, localConfig.projects);
289
+ const selected = filterProjects(projects, options.projectIds);
290
+ const results = selected.projects.map((project) => validateProject(project, options.rootDir));
291
+
292
+ if (options.strict) {
293
+ for (const result of results) {
294
+ if (result.status === 'skipped') {
295
+ result.status = 'failed';
296
+ result.reason = `${result.reason} Strict mode treats skipped projects as failures.`;
297
+ }
298
+ }
299
+ }
300
+
301
+ return {
302
+ rootDir: options.rootDir,
303
+ localConfigPath: localConfig.path,
304
+ missingProjectIds: selected.missingProjectIds,
305
+ results,
306
+ summary: summarizeResults(results, selected.missingProjectIds),
307
+ };
308
+ }
309
+
310
+ function filterProjects(projects, ids) {
311
+ if (ids.length === 0) {
312
+ return { projects, missingProjectIds: [] };
313
+ }
314
+
315
+ const byId = new Map(projects.map((project) => [project.id, project]));
316
+ const selected = [];
317
+ const missingProjectIds = [];
318
+
319
+ for (const id of ids) {
320
+ if (byId.has(id)) {
321
+ selected.push(byId.get(id));
322
+ } else {
323
+ missingProjectIds.push(id);
324
+ }
325
+ }
326
+
327
+ return { projects: selected, missingProjectIds };
328
+ }
329
+
330
+ function summarizeResults(results, missingProjectIds = []) {
331
+ return {
332
+ total: results.length,
333
+ passed: results.filter((result) => result.status === 'passed').length,
334
+ failed:
335
+ results.filter((result) => result.status === 'failed').length + missingProjectIds.length,
336
+ skipped: results.filter((result) => result.status === 'skipped').length,
337
+ };
338
+ }
339
+
340
+ function printList(report) {
341
+ console.log('BI Agent Superpowers — Validation Projects');
342
+ console.log('==========================================\n');
343
+
344
+ if (report.results.length === 0) {
345
+ console.log('No project descriptors found.');
346
+ return;
347
+ }
348
+
349
+ for (const result of report.results) {
350
+ console.log(`- ${result.id}: ${result.name} (${result.privacy})`);
351
+ }
352
+ }
353
+
354
+ function printReport(report) {
355
+ console.log('BI Agent Superpowers — Project Validation');
356
+ console.log('=========================================\n');
357
+ console.log(`Root: ${report.rootDir}`);
358
+ console.log(`Local config: ${report.localConfigPath}`);
359
+ console.log('');
360
+
361
+ for (const missingId of report.missingProjectIds) {
362
+ console.log(`FAIL ${missingId}`);
363
+ console.log(' Project id was requested but no descriptor or local config exists.\n');
364
+ }
365
+
366
+ for (const result of report.results) {
367
+ const label = result.status.toUpperCase();
368
+ console.log(`${label} ${result.id} — ${result.name}`);
369
+ if (result.path) {
370
+ console.log(` Path: ${result.path}`);
371
+ }
372
+ if (result.reason) {
373
+ console.log(` ${result.reason}`);
374
+ }
375
+ for (const check of result.checks) {
376
+ const checkLabel = check.passed ? 'OK' : 'MISS';
377
+ console.log(` ${checkLabel} ${check.name}: ${check.path}`);
378
+ }
379
+ console.log('');
380
+ }
381
+
382
+ const summary = report.summary;
383
+ console.log(
384
+ `Summary: ${summary.passed} passed, ${summary.failed} failed, ${summary.skipped} skipped (${summary.total} checked)`
385
+ );
386
+ }
387
+
388
+ function validateProjectsCommand(args) {
389
+ let options;
390
+ try {
391
+ options = parseArgs(args || []);
392
+ const report = runValidation(options);
393
+
394
+ if (options.json) {
395
+ console.log(JSON.stringify(report, null, 2));
396
+ } else if (options.list) {
397
+ printList(report);
398
+ } else {
399
+ printReport(report);
400
+ }
401
+
402
+ if (report.summary.failed > 0) {
403
+ process.exitCode = 1;
404
+ }
405
+ } catch (err) {
406
+ if (options && options.json) {
407
+ console.log(JSON.stringify({ error: err.message }, null, 2));
408
+ } else {
409
+ console.error(`Error: ${err.message}`);
410
+ }
411
+ process.exitCode = 1;
412
+ }
413
+ }
414
+
415
+ module.exports = Object.assign(validateProjectsCommand, {
416
+ parseArgs,
417
+ readJsonStrict,
418
+ loadProjectDescriptors,
419
+ loadLocalConfig,
420
+ mergeProjects,
421
+ resolveProjectPath,
422
+ validateProject,
423
+ isPathInside,
424
+ runValidation,
425
+ summarizeResults,
426
+ });
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Watch Command (sentinel)
3
+ * ========================
4
+ * Watches for changes in skills and auto-regenerates the Claude Code plugin
5
+ * plus any configured legacy adapters.
6
+ *
7
+ * Usage:
8
+ * super sentinel Watch all configured outputs
9
+ * super sentinel --tool claude-plugin Watch a specific output only
10
+ */
11
+
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+ const tui = require('../utils/tui');
15
+
16
+ // Try to require chokidar, but handle if not available
17
+ let chokidar;
18
+ try {
19
+ chokidar = require('chokidar');
20
+ } catch (e) {
21
+ chokidar = null;
22
+ }
23
+
24
+ /**
25
+ * Parse command line arguments
26
+ * @param {string[]} args - CLI arguments
27
+ * @returns {Object} Parsed options
28
+ */
29
+ function parseArgs(args) {
30
+ const options = {
31
+ tool: null, // null means all configured outputs
32
+ targetDir: process.cwd(),
33
+ debounce: 500, // ms
34
+ };
35
+
36
+ for (let i = 0; i < args.length; i++) {
37
+ const arg = args[i];
38
+
39
+ if (arg === '--tool' || arg === '-t') {
40
+ options.tool = args[++i];
41
+ } else if (arg === '--debounce') {
42
+ options.debounce = parseInt(args[++i], 10) || 500;
43
+ } else if (!arg.startsWith('-')) {
44
+ options.targetDir = arg;
45
+ }
46
+ }
47
+
48
+ return options;
49
+ }
50
+
51
+ /**
52
+ * Chokidar v4 no longer supports glob paths. Watch the skill root and filter
53
+ * relevant runtime/source files in-process so folder-based skills are covered.
54
+ *
55
+ * @param {string} skillsDir - Directory containing skill sources
56
+ * @returns {string[]} Watch roots
57
+ */
58
+ function getWatchRoots(skillsDir) {
59
+ return [skillsDir];
60
+ }
61
+
62
+ /**
63
+ * @param {string} changedPath - Changed file path
64
+ * @param {string} skillsDir - Watched skill root
65
+ * @returns {boolean} Whether the changed file should trigger regeneration
66
+ */
67
+ function isRelevantSkillPath(changedPath, skillsDir) {
68
+ const relative = path.relative(skillsDir, changedPath);
69
+ if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {
70
+ return false;
71
+ }
72
+
73
+ const base = path.basename(changedPath);
74
+ if (
75
+ base.endsWith('.test.js') ||
76
+ base.endsWith('.spec.js') ||
77
+ base.endsWith('.bak') ||
78
+ base.endsWith('.tmp') ||
79
+ base.startsWith('.')
80
+ ) {
81
+ return false;
82
+ }
83
+
84
+ return ['.md', '.js', '.json', '.sh'].includes(path.extname(changedPath));
85
+ }
86
+
87
+ /**
88
+ * Main watch command handler
89
+ * @param {string[]} args - Command arguments
90
+ * @param {Object} config - CLI configuration with paths
91
+ * @param {Object} cliModule - Reference to main CLI module for regeneration
92
+ */
93
+ function watchCommand(args, config, cliModule) {
94
+ if (!chokidar) {
95
+ tui.error('Watch mode requires the chokidar package.');
96
+ tui.info('Install dependencies with: npm install');
97
+ process.exit(1);
98
+ }
99
+
100
+ const options = parseArgs(args);
101
+ const skillsDir = config.skillsDir;
102
+ const targetDir = options.targetDir;
103
+
104
+ if (!fs.existsSync(skillsDir)) {
105
+ tui.error('Skills directory not found. Try reinstalling: npm install -g bi-superpowers');
106
+ process.exit(1);
107
+ }
108
+
109
+ tui.header('BI Agent Superpowers', 'Watch Mode');
110
+
111
+ tui.info(`Watching: ${skillsDir}`);
112
+ tui.info(`Target: ${targetDir}`);
113
+ if (options.tool) {
114
+ tui.info(`Tool: ${options.tool}`);
115
+ } else {
116
+ tui.info('Tool: All configured tools');
117
+ }
118
+
119
+ console.log('');
120
+ tui.muted('Press Ctrl+C to stop watching');
121
+ console.log('');
122
+
123
+ // Debounce timer
124
+ let debounceTimer = null;
125
+ const pendingChanges = new Set();
126
+
127
+ // Create watcher
128
+ const watcher = chokidar.watch(getWatchRoots(skillsDir), {
129
+ persistent: true,
130
+ ignoreInitial: true,
131
+ awaitWriteFinish: {
132
+ stabilityThreshold: 200,
133
+ pollInterval: 100,
134
+ },
135
+ });
136
+
137
+ /**
138
+ * Handle file change
139
+ * @param {string} changedPath - Path to changed file
140
+ * @param {string} eventType - Type of event (add, change, unlink)
141
+ */
142
+ function handleChange(changedPath, _eventType) {
143
+ if (!isRelevantSkillPath(changedPath, skillsDir)) {
144
+ return;
145
+ }
146
+
147
+ const filename = path.relative(skillsDir, changedPath);
148
+ pendingChanges.add(filename);
149
+
150
+ // Clear existing timer
151
+ if (debounceTimer) {
152
+ clearTimeout(debounceTimer);
153
+ }
154
+
155
+ // Set new timer
156
+ debounceTimer = setTimeout(() => {
157
+ const changes = Array.from(pendingChanges);
158
+ pendingChanges.clear();
159
+
160
+ const timestamp = new Date().toLocaleTimeString();
161
+ console.log(`\n${tui.colors.muted(`[${timestamp}]`)} ${tui.icons.watch} Changes detected:`);
162
+ changes.forEach((file) => {
163
+ console.log(` ${tui.icons.bullet} ${tui.colors.info(file)}`);
164
+ });
165
+
166
+ // Trigger regeneration
167
+ regenerateConfigs(targetDir, options.tool, cliModule);
168
+ }, options.debounce);
169
+ }
170
+
171
+ // Watch events
172
+ watcher
173
+ .on('add', (path) => handleChange(path, 'add'))
174
+ .on('change', (path) => handleChange(path, 'change'))
175
+ .on('unlink', (path) => handleChange(path, 'unlink'))
176
+ .on('error', (error) => {
177
+ tui.error(`Watcher error: ${error.message}`);
178
+ })
179
+ .on('ready', () => {
180
+ tui.success('Watching for changes...');
181
+ });
182
+
183
+ // Handle graceful shutdown
184
+ process.on('SIGINT', () => {
185
+ console.log('\n');
186
+ tui.info('Stopping watch mode...');
187
+ watcher.close();
188
+ process.exit(0);
189
+ });
190
+ }
191
+
192
+ /**
193
+ * Regenerate configs after changes detected
194
+ * @param {string} targetDir - Target directory
195
+ * @param {string|null} specificTool - Specific tool or null for all
196
+ * @param {Object} cliModule - CLI module reference
197
+ */
198
+ async function regenerateConfigs(targetDir, specificTool, cliModule) {
199
+ const ora = require('ora');
200
+ const spinner = ora('Regenerating configs...').start();
201
+
202
+ try {
203
+ // Load the saved tool config
204
+ const configPath = path.join(targetDir, '.bi-superpowers.json');
205
+ let tools = ['claude-plugin'];
206
+
207
+ if (fs.existsSync(configPath)) {
208
+ try {
209
+ const savedConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
210
+ if (savedConfig.tools) {
211
+ tools = savedConfig.tools;
212
+ }
213
+ } catch (e) {
214
+ // Ignore parse errors, use defaults
215
+ }
216
+ }
217
+
218
+ if (!tools.includes('claude-plugin')) {
219
+ tools = ['claude-plugin', ...tools];
220
+ }
221
+
222
+ // Filter to specific tool if requested
223
+ if (specificTool) {
224
+ tools = tools.filter((t) => t === specificTool);
225
+ }
226
+
227
+ if (tools.length === 0) {
228
+ spinner.warn('No tools configured');
229
+ return;
230
+ }
231
+
232
+ // Call the sync logic from CLI module
233
+ if (cliModule && typeof cliModule.syncProjectInternal === 'function') {
234
+ await cliModule.syncProjectInternal(targetDir, tools);
235
+ spinner.succeed(`Regenerated configs for: ${tools.join(', ')}`);
236
+ } else {
237
+ // Fallback: just report what would be done
238
+ spinner.succeed(`Would regenerate configs for: ${tools.join(', ')}`);
239
+ tui.muted('Note: Run "super recharge" manually to apply changes');
240
+ }
241
+ } catch (error) {
242
+ spinner.fail(`Regeneration failed: ${error.message}`);
243
+ }
244
+ }
245
+
246
+ module.exports = Object.assign(watchCommand, {
247
+ parseArgs,
248
+ getWatchRoots,
249
+ isRelevantSkillPath,
250
+ regenerateConfigs,
251
+ });