bi-superpowers 1.0.0 → 1.1.1

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 (207) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.claude-plugin/skill-manifest.json +1 -1
  4. package/.plugin/plugin.json +1 -1
  5. package/LICENSE +21 -21
  6. package/README.md +16 -6
  7. package/bin/cli.js +8 -1
  8. package/bin/commands/create-from-template.js +5 -0
  9. package/bin/commands/install.js +100 -15
  10. package/bin/commands/session-update.js +33 -3
  11. package/bin/commands/template-path.js +62 -0
  12. package/bin/commands/uninstall.js +76 -16
  13. package/bin/commands/update-check.js +29 -18
  14. package/bin/lib/base-template-smoke.js +80 -40
  15. package/bin/lib/install-manifest.js +198 -0
  16. package/bin/lib/powerbi-mcp-session.js +63 -17
  17. package/bin/lib/template-scaffold.js +40 -5
  18. package/bin/postinstall.js +0 -0
  19. package/commands/bi-powerquery.md +2 -1
  20. package/config.example.json +23 -23
  21. package/config.json +23 -23
  22. package/desktop-extension/manifest.json +30 -30
  23. package/desktop-extension/package.json +10 -10
  24. package/desktop-extension/server.js +76 -76
  25. package/package.json +1 -1
  26. package/skills/bi-connect/SKILL.md +1 -1
  27. package/skills/bi-connect/scripts/update-check.js +30 -19
  28. package/skills/bi-dax/SKILL.md +1 -1
  29. package/skills/bi-dax/scripts/update-check.js +30 -19
  30. package/skills/bi-kickoff/SKILL.md +1 -1
  31. package/skills/bi-kickoff/scripts/update-check.js +30 -19
  32. package/skills/bi-modeling/SKILL.md +1 -1
  33. package/skills/bi-modeling/scripts/update-check.js +30 -19
  34. package/skills/bi-performance/SKILL.md +1 -1
  35. package/skills/bi-performance/scripts/update-check.js +30 -19
  36. package/skills/bi-powerquery/SKILL.md +3 -2
  37. package/skills/bi-powerquery/references/base-template-data-contract.md +5 -2
  38. package/skills/bi-powerquery/scripts/test-powerquery-contract.ps1 +24 -2
  39. package/skills/bi-powerquery/scripts/update-check.js +30 -19
  40. package/skills/bi-refactor/SKILL.md +1 -1
  41. package/skills/bi-refactor/scripts/update-check.js +30 -19
  42. package/skills/bi-scorecard/SKILL.md +1 -1
  43. package/skills/bi-scorecard/scripts/update-check.js +30 -19
  44. package/skills/bi-start/SKILL.md +1 -1
  45. package/skills/bi-start/scripts/update-check.js +30 -19
  46. package/src/content/mcp-requirements.json +57 -57
  47. package/src/content/skills/bi-powerquery/SKILL.md +2 -1
  48. package/src/content/skills/bi-powerquery/references/base-template-data-contract.md +5 -2
  49. package/src/content/skills/bi-powerquery/scripts/test-powerquery-contract.ps1 +24 -2
  50. package/templates/base-template/base-template.Report/.platform +10 -10
  51. package/templates/base-template/base-template.Report/StaticResources/RegisteredResources/BISuperpowers.json +3887 -3887
  52. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BaseThemes/CY18SU07.json +176 -176
  53. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BaseThemes/Fluent2-CY26SU03.json +4103 -4103
  54. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleCityPark.json +25 -25
  55. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleDefault.json +25 -25
  56. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleNeutral.json +25 -25
  57. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleOrchid.json +25 -25
  58. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleTidal.json +25 -25
  59. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Bloom.json +138 -138
  60. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/CityPark.json +39 -39
  61. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Classroom.json +39 -39
  62. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/ColorblindSafe.json +47 -47
  63. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/CopilotDefault.json +1860 -1860
  64. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Divergent.json +126 -126
  65. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Electric.json +47 -47
  66. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Frontier.json +135 -135
  67. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/HighContrast.json +39 -39
  68. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Highrise.json +40 -40
  69. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Innovate.json +226 -226
  70. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/NewExecutive.json +40 -40
  71. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Solar.json +32 -32
  72. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Storm.json +24 -24
  73. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Sunset.json +47 -47
  74. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Temperature.json +32 -32
  75. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Tidal.json +99 -99
  76. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Twilight.json +39 -39
  77. package/templates/base-template/base-template.Report/definition/bookmarks/1d40d43c7ade66e8603c.bookmark.json +2296 -2296
  78. package/templates/base-template/base-template.Report/definition/bookmarks/af068ff51c0ca3089ea7.bookmark.json +2299 -2299
  79. package/templates/base-template/base-template.Report/definition/bookmarks/bookmarks.json +10 -10
  80. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/page.json +129 -129
  81. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/0352fd80d074693a65db/mobile.json +10 -10
  82. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/0352fd80d074693a65db/visual.json +668 -668
  83. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/1c5a14bf493697344b68/mobile.json +10 -10
  84. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/1c5a14bf493697344b68/visual.json +722 -722
  85. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/3486cf7624c5b109b4e5/mobile.json +10 -10
  86. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/3486cf7624c5b109b4e5/visual.json +332 -332
  87. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/4d8b989008edc0db28d1/mobile.json +10 -10
  88. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/4d8b989008edc0db28d1/visual.json +108 -108
  89. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/55e10ac7d76a1954f94f/mobile.json +30 -30
  90. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/55e10ac7d76a1954f94f/visual.json +377 -377
  91. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/57f52ecf4490f70e4da1/mobile.json +10 -10
  92. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/57f52ecf4490f70e4da1/visual.json +174 -174
  93. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/5f4d76bbc870118e9840/mobile.json +10 -10
  94. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/5f4d76bbc870118e9840/visual.json +467 -467
  95. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/73629e1abebb7a444b59/mobile.json +10 -10
  96. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/73629e1abebb7a444b59/visual.json +359 -358
  97. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/749cb1388c7e0a88161c/mobile.json +10 -10
  98. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/749cb1388c7e0a88161c/visual.json +689 -689
  99. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/90677f13cea5d1275990/visual.json +15 -16
  100. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/92cf92e3da10493adb78/mobile.json +10 -10
  101. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/92cf92e3da10493adb78/visual.json +467 -467
  102. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/9fe17b1971f68443fc15/mobile.json +9 -9
  103. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/9fe17b1971f68443fc15/visual.json +327 -327
  104. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a30bd0950630ed94e8a3/mobile.json +10 -10
  105. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a30bd0950630ed94e8a3/visual.json +577 -577
  106. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a56e91d9400a835e4814/mobile.json +10 -10
  107. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a56e91d9400a835e4814/visual.json +431 -431
  108. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/aded24cd205c0b528642/mobile.json +10 -10
  109. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/aded24cd205c0b528642/visual.json +800 -800
  110. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/af34b26f14a8a724c9a9/mobile.json +36 -36
  111. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/af34b26f14a8a724c9a9/visual.json +1317 -1317
  112. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/b529688fe5a226643322/visual.json +208 -208
  113. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/c4c6f332d05e72e2eb06/mobile.json +10 -10
  114. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/c4c6f332d05e72e2eb06/visual.json +173 -173
  115. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/fa81f184e2cb0e8b087c/mobile.json +28 -28
  116. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/fa81f184e2cb0e8b087c/visual.json +240 -240
  117. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/page.json +129 -129
  118. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/07e9c4302e29029c5462/mobile.json +10 -10
  119. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/07e9c4302e29029c5462/visual.json +689 -689
  120. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/109ceede4bc015b0c006/mobile.json +10 -10
  121. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/109ceede4bc015b0c006/visual.json +467 -467
  122. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/118257e006d472277e10/mobile.json +10 -10
  123. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/118257e006d472277e10/visual.json +358 -358
  124. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/2caf02e0137c4a1280cc/mobile.json +10 -10
  125. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/2caf02e0137c4a1280cc/visual.json +668 -668
  126. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/311e76fe3c9edad68204/mobile.json +10 -10
  127. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/311e76fe3c9edad68204/visual.json +108 -108
  128. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/31c21f8cbeb3b208940a/visual.json +208 -208
  129. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/3ab72c25062437149b03/visual.json +16 -16
  130. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5959867442abcb0ce2b3/mobile.json +10 -10
  131. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5959867442abcb0ce2b3/visual.json +787 -787
  132. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5b96e0f88d192b044a13/mobile.json +10 -10
  133. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5b96e0f88d192b044a13/visual.json +591 -591
  134. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/64e749a63d0786000e22/mobile.json +10 -10
  135. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/64e749a63d0786000e22/visual.json +467 -467
  136. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/7ae1ca604edac6586ad0/mobile.json +10 -10
  137. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/7ae1ca604edac6586ad0/visual.json +1309 -1309
  138. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/840300733885141a6603/mobile.json +10 -10
  139. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/840300733885141a6603/visual.json +174 -174
  140. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/a38448cdb203279273d2/mobile.json +10 -10
  141. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/a38448cdb203279273d2/visual.json +515 -515
  142. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d1e86f213a3841d12e20/visual.json +327 -327
  143. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d4a484c1bcc8ee3075e2/mobile.json +10 -10
  144. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d4a484c1bcc8ee3075e2/visual.json +431 -431
  145. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d87cb5cf06acca19bbb5/mobile.json +10 -10
  146. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d87cb5cf06acca19bbb5/visual.json +240 -240
  147. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/e243da2677209ed69408/mobile.json +10 -10
  148. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/e243da2677209ed69408/visual.json +173 -173
  149. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/f3aaf24f5b22b67573b0/mobile.json +10 -10
  150. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/f3aaf24f5b22b67573b0/visual.json +332 -332
  151. package/templates/base-template/base-template.Report/definition/pages/pages.json +7 -7
  152. package/templates/base-template/base-template.Report/definition/report.json +88 -88
  153. package/templates/base-template/base-template.Report/definition/version.json +3 -3
  154. package/templates/base-template/base-template.Report/definition.pbir +8 -8
  155. package/templates/base-template/base-template.SemanticModel/.platform +10 -10
  156. package/templates/base-template/base-template.SemanticModel/definition/cultures/es-AR.tmdl +11185 -11185
  157. package/templates/base-template/base-template.SemanticModel/definition/database.tmdl +5 -3
  158. package/templates/base-template/base-template.SemanticModel/definition/expressions.tmdl +340 -234
  159. package/templates/base-template/base-template.SemanticModel/definition/functions.tmdl +637 -637
  160. package/templates/base-template/base-template.SemanticModel/definition/model.tmdl +85 -82
  161. package/templates/base-template/base-template.SemanticModel/definition/relationships.tmdl +263 -271
  162. package/templates/base-template/base-template.SemanticModel/definition/tables/Calendario.tmdl +200 -200
  163. package/templates/base-template/base-template.SemanticModel/definition/tables/Campa/303/261as.tmdl +75 -75
  164. package/templates/base-template/base-template.SemanticModel/definition/tables/Canales.tmdl +84 -84
  165. package/templates/base-template/base-template.SemanticModel/definition/tables/Clientes.tmdl +126 -143
  166. package/templates/base-template/base-template.SemanticModel/definition/tables/Devoluciones.tmdl +64 -95
  167. package/templates/base-template/base-template.SemanticModel/definition/tables/Ejecuci/303/263n proyectos.tmdl" +98 -130
  168. package/templates/base-template/base-template.SemanticModel/definition/tables/Entregas.tmdl +77 -122
  169. package/templates/base-template/base-template.SemanticModel/definition/tables/Equipos m/303/251tricas.tmdl" +40 -40
  170. package/templates/base-template/base-template.SemanticModel/definition/tables/Equipos.tmdl +47 -73
  171. package/templates/base-template/base-template.SemanticModel/definition/tables/Horas.tmdl +91 -122
  172. package/templates/base-template/base-template.SemanticModel/definition/tables/Interacciones clientes.tmdl +95 -146
  173. package/templates/base-template/base-template.SemanticModel/definition/tables/Leads.tmdl +90 -119
  174. package/templates/base-template/base-template.SemanticModel/definition/tables/Monedas.tmdl +44 -44
  175. package/templates/base-template/base-template.SemanticModel/definition/tables/Movimientos financieros.tmdl +146 -145
  176. package/templates/base-template/base-template.SemanticModel/definition/tables/M/303/251tricas.tmdl +1324 -1294
  177. package/templates/base-template/base-template.SemanticModel/definition/tables/N/303/263mina.tmdl +82 -110
  178. package/templates/base-template/base-template.SemanticModel/definition/tables/Oportunidades.tmdl +83 -135
  179. package/templates/base-template/base-template.SemanticModel/definition/tables/Presupuesto.tmdl +101 -125
  180. package/templates/base-template/base-template.SemanticModel/definition/tables/Productos.tmdl +98 -98
  181. package/templates/base-template/base-template.SemanticModel/definition/tables/Proyectos.tmdl +77 -77
  182. package/templates/base-template/base-template.SemanticModel/definition/tables/Servicios.tmdl +75 -75
  183. package/templates/base-template/base-template.SemanticModel/definition/tables/Tareas proyecto.tmdl +73 -102
  184. package/templates/base-template/base-template.SemanticModel/definition/tables/Tipo de cambio.tmdl +67 -67
  185. package/templates/base-template/base-template.SemanticModel/definition/tables/Ventas.tmdl +142 -180
  186. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux An/303/241lisis dimensiones.tmdl" +38 -38
  187. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Comparaciones.tmdl +227 -227
  188. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Compatibilidad m/303/251trica-dimensi/303/263n.tmdl" +68 -68
  189. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Modelo configuraci/303/263n.tmdl" +44 -44
  190. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Modo fechas.tmdl +36 -36
  191. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux M/303/251trica-Equipo.tmdl" +101 -102
  192. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Overrides m/303/251trica-dimensi/303/263n.tmdl" +57 -54
  193. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Per/303/255odos.tmdl" +182 -182
  194. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Rango fechas modo.tmdl +36 -36
  195. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Rango fechas.tmdl +27 -27
  196. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Vista de calendario.tmdl +30 -30
  197. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC C/303/241lculo.tmdl" +70 -70
  198. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC Eje X.tmdl +63 -63
  199. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC M/303/251trica.tmdl" +374 -374
  200. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC Tipo c/303/241lculo.tmdl" +223 -223
  201. package/templates/base-template/base-template.SemanticModel/definition/tables/_PC Dimensi/303/263n.tmdl" +98 -98
  202. package/templates/base-template/base-template.SemanticModel/definition/tables/_PC Eje X.tmdl +68 -68
  203. package/templates/base-template/base-template.SemanticModel/definition/tables//303/223rdenes servicio.tmdl" +121 -151
  204. package/templates/base-template/base-template.SemanticModel/definition.pbism +4 -4
  205. package/templates/base-template/base-template.SemanticModel/diagramLayout.json +567 -567
  206. package/templates/base-template/base-template.pbip +13 -13
  207. package/theme/BISuperpowers.json +3887 -3887
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "AI-powered skills for Power BI Desktop development. Works with Claude Code, GitHub Copilot, Codex, Gemini CLI, and Kilo Code.",
9
- "version": "1.0.0",
9
+ "version": "1.1.1",
10
10
  "repository": "https://github.com/luquimbo/bi-superpowers"
11
11
  },
12
12
  "plugins": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bi-superpowers",
3
3
  "description": "Claude Code plugin for Power BI, Microsoft Fabric, and semantic model workflows powered by the official Microsoft MCP servers.",
4
- "version": "1.0.0",
4
+ "version": "1.1.1",
5
5
  "author": {
6
6
  "name": "Lucas Sanchez"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bi-superpowers",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "skillCount": 9,
5
5
  "skills": [
6
6
  {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "spec": "open-plugin-spec@1",
3
3
  "name": "bi-superpowers",
4
- "version": "1.0.0",
4
+ "version": "1.1.1",
5
5
  "description": "Claude Code plugin for Power BI, Microsoft Fabric, and semantic model workflows powered by the official Microsoft MCP servers.",
6
6
  "author": {
7
7
  "name": "Lucas Sanchez"
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 BI Agent Superpowers contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2024 BI Agent Superpowers contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -38,7 +38,7 @@ Works with **Codex**, **Claude Code**, **GitHub Copilot**, **Gemini CLI**, and *
38
38
 
39
39
  Fully open source under MIT. No account, no login, no license keys — every command works offline.
40
40
 
41
- > Status: `v1.0.x` is the current stable release line. Every public slash command lives under the `/bi-*` namespace.
41
+ > Status: `v1.1.x` is the current stable release line. Every public slash command lives under the `/bi-*` namespace.
42
42
  >
43
43
  > Validation baseline: developed and stress-tested first in **Codex**. Other agents are shipped as compatibility targets unless a release note says otherwise.
44
44
 
@@ -432,6 +432,7 @@ super uninstall --dry-run # Preview what an uninstall would remove
432
432
  super kickoff # Advanced: generate optional local Claude Code plugin files
433
433
  super recharge # Regenerate optional local Claude Code plugin artifacts
434
434
  super create-from-template # Scaffold a new PBIP project from templates/<name>/ into pbip-files/
435
+ super template-path --template base-template # Print the packaged template path
435
436
  super powers # List available skills
436
437
  super scan # Compare source skills with generated artifacts
437
438
  super checkup # Validate skill content
@@ -466,12 +467,15 @@ super create-from-template --template base-template --name <projectName>
466
467
  super create-from-template --template base-template --name <projectName> --target /path/to/project
467
468
  super create-from-template --template base-template --name <projectName> --dry-run
468
469
  super create-from-template --template base-template --name <projectName> --force
470
+ super create-from-template --template base-template --name <projectName> --force --replace-project <oldName>
469
471
  ```
470
472
 
471
- Used by the `bi-kickoff` skill PHASE 0 Option A (start from template) so agents do not have to copy files by hand. The command copies `templates/<name>/` into `<target>/pbip-files/<projectName>.*`, renames the PBIP descriptor and the `.SemanticModel/` / `.Report/` folders, rewrites internal cross-references (`.pbip → Report.path`, `definition.pbir → datasetReference.byPath.path`), and regenerates the Fabric `logicalId` in both `.platform` files. It refuses to overwrite an existing PBIP unless `--force` is passed, skips the template's own `AGENTS.md`, skips local Desktop/editor state such as `.pbi`, `localSettings.json`, `cache.abf`, and `DAXQueries`, and when forced cleans only the destination `<projectName>.pbip`, `<projectName>.SemanticModel`, and `<projectName>.Report` paths before copying again.
473
+ Used by the `bi-kickoff` skill PHASE 0 Option A (start from template) so agents do not have to copy files by hand. The command copies `templates/<name>/` into `<target>/pbip-files/<projectName>.*`, renames the PBIP descriptor and the `.SemanticModel/` / `.Report/` folders, rewrites internal cross-references (`.pbip → Report.path`, `definition.pbir → datasetReference.byPath.path`), and regenerates the Fabric `logicalId` in both `.platform` files. It refuses to overwrite an existing PBIP unless `--force` is passed, skips the template's own `AGENTS.md`, skips local Desktop/editor state such as `.pbi`, `localSettings.json`, `cache.abf`, and `DAXQueries`, and when forced cleans only the destination project paths before copying again. If there is exactly one PBIP in the destination, `--force` replaces that project even when the new `--name` differs; if there are multiple PBIPs, pass `--replace-project <oldName>` so the command cannot guess the wrong project.
472
474
 
473
475
  The packaged template is `base-template`, the canonical dynamic-first reference for new Power BI projects. Dynamic metric format strings stay safe and unscaled for numeric visuals; compact abbreviations live in dedicated text helper measures for KPI labels.
474
476
 
477
+ `super template-path --template base-template` prints the installed template folder path. Skills use it instead of hard-coded developer machine paths.
478
+
475
479
  `super mcp-setup` is intentionally not part of normal setup. It only refreshes MCP config inside an existing local Claude Code plugin created by `super kickoff`; it refuses to write repo-local config in arbitrary projects. For Codex, GitHub Copilot, Gemini CLI, Kilo Code, and normal Claude Code user-level installs, use `super install --all --yes`.
476
480
 
477
481
  ---
@@ -623,7 +627,7 @@ node_modules/
623
627
  **/.pbi/localSettings.json
624
628
  ```
625
629
 
626
- `templates/` ships the canonical `templates/base-template/` PBIP package with `AGENTS.md`, semantic model, and report definition. It is the "template-as-reference" used by all specialist skills and the source for the `bi-kickoff` "create from template" branch invoked via `super create-from-template`, which copies `templates/base-template/` into `<user-repo>/pbip-files/<projectName>.*` with renaming, cross-reference rewriting, and regenerated logicalIds. The base template includes Power Query pre-converted currency base columns, packaged sample queries grouped under `Sample Dataset\Dimensiones` and `Sample Dataset\Hechos`, `_GC Métrica` / `_GC Tipo cálculo` calculation groups, guarded metric dispatch, metric-aware dynamic dimensions through `_PC Dimensión`, a `Equipos métricas[Equipo]` slicer for filtering the metric selector by team, multi-team metric memberships through `_Aux Métrica-Equipo`, nine Equipos (eight operating teams plus `Dirección`) for the Andina Nexus product-and-services demo company, team-specific model-view diagrams, safe unscaled numeric model formats, compact KPI label helpers, cleaned key metadata, and a `Data = "Demo"` contract on appendable business tables. Demo IDs are entity-coded text values such as `ClienteA25D`, so relationships stay on the original ID columns while real rows can append with `Data = "Real"` and their own source IDs. `/bi-powerquery` creates the user-side real staging queries; the template itself does not ship unloaded `*_Real` queries. `/bi-scorecard` uses `base-template` as a metrics-catalog reference for Service scorecards; it does not add a universal targets model to the template.
630
+ `templates/` ships the canonical `templates/base-template/` PBIP package with `AGENTS.md`, semantic model, and report definition. It is the "template-as-reference" used by all specialist skills and the source for the `bi-kickoff` "create from template" branch invoked via `super create-from-template`, which copies `templates/base-template/` into `<user-repo>/pbip-files/<projectName>.*` with renaming, cross-reference rewriting, and regenerated logicalIds. The base template includes Power Query pre-converted currency base columns, packaged sample queries grouped under `Sample Dataset\Dimensiones` and `Sample Dataset\Hechos`, `_GC Métrica` / `_GC Tipo cálculo` calculation groups, guarded metric dispatch, metric-aware dynamic dimensions through `_PC Dimensión`, a `Equipos métricas[Equipo]` slicer for filtering the metric selector by team, multi-team metric memberships through `_Aux Métrica-Equipo`, nine Equipos (eight operating teams plus `Dirección`) for the Andina Nexus product-and-services demo company, team-specific model-view diagrams, safe unscaled numeric model formats, compact KPI label helpers, cleaned key metadata, and a `Data = "Demo"` contract on appendable business tables. Demo facts now share full-calendar weekly drivers from the `FechaInicio` parameter through the current model date; sales, project execution, finance, marketing, operations, payroll, returns, tasks, and customer acquisition are derived from shared business drivers instead of independent random grids. Demo IDs are entity-coded text values such as `ClienteA25D` and shared helper values such as `EQUA00A`, so relationships stay on the original ID columns while real rows can append with `Data = "Real"` and their own source IDs; visible customer and country labels are capped at 13 values each so dynamic-dimension slicers stay readable without shrinking the customer cohort. `/bi-powerquery` creates the user-side real staging queries; the template itself does not ship unloaded `*_Real` queries. `/bi-scorecard` uses `base-template` as a metrics-catalog reference for Service scorecards; it does not add a universal targets model to the template.
627
631
  `validation/` is repo-only. It stores sanitized validation descriptors and playbooks for project QA; private project paths live in `validation.local.json`, which must never be committed.
628
632
 
629
633
  ---
@@ -716,8 +720,9 @@ For a live Power BI Desktop smoke test of the canonical template, use
716
720
  `validation/cases/base-template-smoke-test.md` after the structural validation
717
721
  passes. `super smoke-test` will probe the open Desktop sessions automatically
718
722
  and keep the one that matches the expected evidence, including seven metrics per
719
- team plus weekly fact, metric, and compatible dimension coverage for the last
720
- 720 days.
723
+ team, full `FechaInicio` current-day calendar coverage, zero business
724
+ invariant failures, and complete metric plus compatible metric-dimension
725
+ coverage.
721
726
 
722
727
  To discover the repo playbooks or print one in full:
723
728
 
@@ -743,13 +748,18 @@ npm run build:plugin
743
748
  npm test
744
749
  npm run lint
745
750
  npm run format:check
751
+ npm audit --omit=dev --audit-level=moderate
752
+ node bin/cli.js validate-projects --project base-template
753
+ node bin/cli.js smoke-test --json
754
+ node bin/cli.js scan --verbose
755
+ npm pack --dry-run --ignore-scripts
746
756
  git add package.json package-lock.json commands/ skills/ .claude-plugin/ .plugin/ .mcp.json
747
757
  git commit -m "chore: release vX.Y.Z"
748
758
  git tag -a vX.Y.Z -m "vX.Y.Z"
749
759
  git push origin main --follow-tags
750
760
  ```
751
761
 
752
- The publish workflow runs on `v*` tag pushes. Manual dispatch is constrained to an already-tagged release commit on `main`.
762
+ The publish workflow runs on `v*` tag pushes. Manual dispatch is constrained to an already-tagged release commit on `main`. CI refuses mismatched tag/package versions and publishes from GitHub Actions without npm provenance because this repository is private. Do not create retrospective tags for already-published versions.
753
763
 
754
764
  ---
755
765
 
package/bin/cli.js CHANGED
@@ -51,6 +51,7 @@ let validateCasesCommand;
51
51
  let validateProjectsCommand;
52
52
  let smokeTestCommand;
53
53
  let createFromTemplateCommand;
54
+ let templatePathCommand;
54
55
  let tui;
55
56
  try {
56
57
  lintCommand = require('./commands/lint'); // checkup: skill file validation
@@ -65,6 +66,7 @@ try {
65
66
  validateProjectsCommand = require('./commands/validate-projects'); // repo/project validation harness
66
67
  smokeTestCommand = require('./commands/smoke-test'); // live base-template smoke test
67
68
  createFromTemplateCommand = require('./commands/create-from-template'); // PBIP scaffold from templates/
69
+ templatePathCommand = require('./commands/template-path'); // portable absolute template path
68
70
  tui = require('./utils/tui'); // colors, tables, boxes for CLI output
69
71
  } catch (_) {
70
72
  // Expected during `npm install` — modules become available after deps are linked.
@@ -178,6 +180,7 @@ Primary commands:
178
180
  kickoff [path] Optional: generate a repo-local Claude Code plugin
179
181
  recharge [path] Optional: regenerate an existing repo-local Claude Code plugin
180
182
  create-from-template Scaffold a new PBIP project from templates/<name>/ into pbip-files/
183
+ template-path Print the portable absolute path of a packaged template
181
184
  build-desktop Build the .mcpb extension for Claude Desktop
182
185
  mcp-setup Refresh MCP config for an existing Claude Code local plugin
183
186
  powers List available skills and MCPs
@@ -216,6 +219,7 @@ Examples:
216
219
  super create-from-template --list # List bundled templates
217
220
  super create-from-template --template base-template --name bi-personal # Scaffold from base template
218
221
  super create-from-template --template base-template --name bi-personal --dry-run # Preview only
222
+ super template-path --template base-template # Print packaged template path
219
223
 
220
224
  Open source — MIT licensed.
221
225
  Documentation: https://bi-superpowers.dev
@@ -669,7 +673,7 @@ function getUpgradeCommand(userAgent) {
669
673
  function resetUpdateCheckStateAfterUpgrade(homeDir) {
670
674
  try {
671
675
  const { resetState } = require('./commands/update-check');
672
- resetState(path.join(homeDir, '.bi-superpowers'));
676
+ resetState(path.join(homeDir, '.bi-superpowers'), PACKAGE_NAME);
673
677
  return true;
674
678
  } catch (_) {
675
679
  return false;
@@ -762,6 +766,7 @@ function getCommandConfig() {
762
766
  return {
763
767
  skillsDir: SKILLS_DIR,
764
768
  packageDir: PACKAGE_DIR,
769
+ packageName: PACKAGE_NAME,
765
770
  version: VERSION,
766
771
  };
767
772
  }
@@ -795,6 +800,7 @@ const runCreateFromTemplate = createCommandWrapper(
795
800
  createFromTemplateCommand,
796
801
  'Create from template'
797
802
  );
803
+ const runTemplatePath = createCommandWrapper(templatePathCommand, 'Template path');
798
804
 
799
805
  // Register wrapper-based commands into the command map (phase 2).
800
806
  commands.install = runInstall;
@@ -810,6 +816,7 @@ commands['smoke-test'] = runSmokeTest;
810
816
  commands['validate-cases'] = runValidateCases;
811
817
  commands['validate-projects'] = runValidateProjects;
812
818
  commands['create-from-template'] = runCreateFromTemplate;
819
+ commands['template-path'] = runTemplatePath;
813
820
  commands.lint = runLint;
814
821
  commands.diff = runDiff;
815
822
  commands.watch = runWatch;
@@ -19,6 +19,7 @@
19
19
  * super create-from-template --list
20
20
  * super create-from-template --template base-template --name <projectName> --dry-run
21
21
  * super create-from-template --template base-template --name <projectName> --force
22
+ * super create-from-template --template base-template --name <projectName> --force --replace-project <existingName>
22
23
  */
23
24
 
24
25
  const path = require('path');
@@ -30,6 +31,7 @@ function parseArgs(args) {
30
31
  targetDir: process.cwd(),
31
32
  projectName: null,
32
33
  force: false,
34
+ replaceProject: null,
33
35
  dryRun: false,
34
36
  list: false,
35
37
  json: false,
@@ -45,6 +47,8 @@ function parseArgs(args) {
45
47
  options.projectName = readValue(args, ++index, arg);
46
48
  } else if (arg === '--force' || arg === '-f') {
47
49
  options.force = true;
50
+ } else if (arg === '--replace-project') {
51
+ options.replaceProject = readValue(args, ++index, arg);
48
52
  } else if (arg === '--dry-run') {
49
53
  options.dryRun = true;
50
54
  } else if (arg === '--list' || arg === '-l') {
@@ -146,6 +150,7 @@ async function createFromTemplateCommand(args, config = {}) {
146
150
  targetDir: options.targetDir,
147
151
  projectName: options.projectName,
148
152
  force: options.force,
153
+ replaceProject: options.replaceProject,
149
154
  dryRun: options.dryRun,
150
155
  });
151
156
 
@@ -37,6 +37,13 @@ const readline = require('readline');
37
37
  const { AGENTS, UNIVERSAL_DIR } = require('../lib/agents');
38
38
  const { writeMcpConfigForAgent } = require('../lib/mcp-config');
39
39
  const { getSkillPurpose } = require('../lib/generators/shared');
40
+ const {
41
+ readInstallManifest,
42
+ writeInstallManifest,
43
+ isManifestOwnedSymlink,
44
+ isVerifiedLegacyManagedSymlink,
45
+ createInstallManifest,
46
+ } = require('../lib/install-manifest');
40
47
 
41
48
  /**
42
49
  * Detect which agents are installed by checking their config directories.
@@ -250,7 +257,13 @@ async function resolveSelectedAgents(opts, baseDir, chalk) {
250
257
  * each selected agent's skill directory to point at the universal copy.
251
258
  * @returns {{agentResults: Array, copyFallbacks: number}}
252
259
  */
253
- function performInstall(skillsSourceDir, skillDirs, selectedAgents, baseDir) {
260
+ function performInstall(
261
+ skillsSourceDir,
262
+ skillDirs,
263
+ selectedAgents,
264
+ baseDir,
265
+ previousManifest = null
266
+ ) {
254
267
  // Always install to the universal path first. This is the source of
255
268
  // truth that all other agent dirs symlink to.
256
269
  const universalTarget = path.join(baseDir, UNIVERSAL_DIR);
@@ -265,17 +278,34 @@ function performInstall(skillsSourceDir, skillDirs, selectedAgents, baseDir) {
265
278
 
266
279
  for (const agentId of selectedAgents) {
267
280
  const agent = AGENTS[agentId];
268
- if (agent.dir === UNIVERSAL_DIR) continue; // Already handled above.
281
+ if (agent.dir === UNIVERSAL_DIR) {
282
+ agentResults.push({
283
+ agentId,
284
+ agent: agent.name,
285
+ method: 'universal',
286
+ dir: agent.dir,
287
+ path: universalTarget,
288
+ target: universalTarget,
289
+ });
290
+ continue;
291
+ }
269
292
 
270
293
  const agentTarget = path.join(baseDir, agent.dir);
294
+ const existingTarget = fs.lstatSync(agentTarget, { throwIfNoEntry: false });
271
295
 
272
296
  // If a real directory already exists (not a symlink), copy into it
273
297
  // directly so we don't destroy user data.
274
- if (fs.existsSync(agentTarget) && !fs.lstatSync(agentTarget).isSymbolicLink()) {
298
+ if (existingTarget && !existingTarget.isSymbolicLink()) {
275
299
  for (const skill of skillDirs) {
276
300
  copySkillDir(path.join(skillsSourceDir, skill), path.join(agentTarget, skill));
277
301
  }
278
- agentResults.push({ agent: agent.name, method: 'copied', dir: agent.dir });
302
+ agentResults.push({
303
+ agentId,
304
+ agent: agent.name,
305
+ method: 'copied',
306
+ dir: agent.dir,
307
+ path: agentTarget,
308
+ });
279
309
  continue;
280
310
  }
281
311
 
@@ -284,20 +314,39 @@ function performInstall(skillsSourceDir, skillDirs, selectedAgents, baseDir) {
284
314
  fs.mkdirSync(parentDir, { recursive: true });
285
315
  }
286
316
 
287
- // Remove any pre-existing symlink so we can recreate it cleanly.
288
- if (fs.existsSync(agentTarget) || fs.lstatSync(agentTarget, { throwIfNoEntry: false })) {
289
- try {
290
- fs.unlinkSync(agentTarget);
291
- } catch (_) {
292
- /* target didn't exist after all — that's fine */
317
+ // A symlink is removed only when the manifest proves ownership, or when
318
+ // it is a verified pre-manifest install that points at our universal
319
+ // skills and contains the complete shipped skill set.
320
+ if (existingTarget && existingTarget.isSymbolicLink()) {
321
+ const owned =
322
+ isManifestOwnedSymlink(previousManifest, agentId, agentTarget, universalTarget) ||
323
+ isVerifiedLegacyManagedSymlink(agentTarget, universalTarget, skillDirs);
324
+ if (!owned) {
325
+ agentResults.push({
326
+ agentId,
327
+ agent: agent.name,
328
+ method: 'preserved-foreign',
329
+ dir: agent.dir,
330
+ path: agentTarget,
331
+ error: 'Existing symlink is not owned by bi-superpowers.',
332
+ });
333
+ continue;
293
334
  }
335
+ fs.unlinkSync(agentTarget);
294
336
  }
295
337
 
296
338
  try {
297
339
  // Relative symlink from the agent's dir to the universal dir.
298
340
  const relPath = path.relative(parentDir, universalTarget);
299
341
  fs.symlinkSync(relPath, agentTarget);
300
- agentResults.push({ agent: agent.name, method: 'symlinked', dir: agent.dir });
342
+ agentResults.push({
343
+ agentId,
344
+ agent: agent.name,
345
+ method: 'symlinked',
346
+ dir: agent.dir,
347
+ path: agentTarget,
348
+ target: universalTarget,
349
+ });
301
350
  } catch (symlinkErr) {
302
351
  // Windows without admin can't create symlinks. Fall back to copy
303
352
  // and remember so we can warn the user at the end.
@@ -309,9 +358,11 @@ function performInstall(skillsSourceDir, skillDirs, selectedAgents, baseDir) {
309
358
  copySkillDir(path.join(skillsSourceDir, skill), path.join(agentTarget, skill));
310
359
  }
311
360
  agentResults.push({
361
+ agentId,
312
362
  agent: agent.name,
313
363
  method: 'copied',
314
364
  dir: agent.dir,
365
+ path: agentTarget,
315
366
  fallbackReason: symlinkErr.code || symlinkErr.message,
316
367
  });
317
368
  }
@@ -346,11 +397,11 @@ function configureMcpsForAgents(selectedAgents, packageDir, baseDir, chalk) {
346
397
  if (configPath) {
347
398
  const relPath = configPath.replace(baseDir, '~');
348
399
  console.log(chalk.green(` ✓ ${relPath} — ${agent.name}`));
349
- results.push({ agent: agent.name, configPath, success: true });
400
+ results.push({ agentId, agent: agent.name, configPath, success: true });
350
401
  }
351
402
  } catch (err) {
352
403
  console.log(chalk.red(` ✗ ${agent.name}: ${err.message}`));
353
- results.push({ agent: agent.name, success: false, error: err.message });
404
+ results.push({ agentId, agent: agent.name, success: false, error: err.message });
354
405
  }
355
406
  }
356
407
  return results;
@@ -373,7 +424,9 @@ async function installCommand(args, config) {
373
424
 
374
425
  // Locate the skills inside the installed package.
375
426
  const packageDir = config.packageDir || path.dirname(path.dirname(__dirname));
427
+ const packageName = config.packageName || 'bi-superpowers';
376
428
  const skillsSourceDir = path.join(packageDir, 'skills');
429
+ const previousManifest = readInstallManifest(baseDir, packageName);
377
430
 
378
431
  if (!fs.existsSync(skillsSourceDir)) {
379
432
  console.error(
@@ -432,7 +485,13 @@ async function installCommand(args, config) {
432
485
  let agentResults;
433
486
  let copyFallbacks;
434
487
  try {
435
- const result = performInstall(skillsSourceDir, skillDirs, selectedAgents, baseDir);
488
+ const result = performInstall(
489
+ skillsSourceDir,
490
+ skillDirs,
491
+ selectedAgents,
492
+ baseDir,
493
+ previousManifest
494
+ );
436
495
  agentResults = result.agentResults;
437
496
  copyFallbacks = result.copyFallbacks;
438
497
  } catch (err) {
@@ -449,6 +508,11 @@ async function installCommand(args, config) {
449
508
 
450
509
  // Report per agent.
451
510
  for (const result of agentResults) {
511
+ if (result.method === 'universal') continue;
512
+ if (result.method === 'preserved-foreign') {
513
+ console.log(chalk.yellow(` ⚠ ${result.dir}/ preserved — ${result.agent}: ${result.error}`));
514
+ continue;
515
+ }
452
516
  const icon = result.method === 'symlinked' ? '→' : '✓';
453
517
  console.log(chalk.green(` ${icon} ${result.dir}/ (${result.method}) — ${result.agent}`));
454
518
  }
@@ -468,7 +532,7 @@ async function installCommand(args, config) {
468
532
  const mcpResults = configureMcpsForAgents(selectedAgents, packageDir, baseDir, chalk);
469
533
 
470
534
  // Build the final summary box.
471
- const totalAgents = agentResults.length + (universalAgents.length > 0 ? 1 : 0);
535
+ const totalAgents = selectedAgents.length;
472
536
  const mcpSuccess = mcpResults.filter((r) => r.success).length;
473
537
  const mcpFailures = mcpResults.filter((r) => !r.success);
474
538
  const hasFailures = mcpFailures.length > 0;
@@ -511,10 +575,14 @@ async function installCommand(args, config) {
511
575
  );
512
576
 
513
577
  // Opt-in: register the Claude Code SessionStart auto-update hook.
578
+ let autoUpdateEnabled = Boolean(
579
+ previousManifest && previousManifest.autoUpdate && previousManifest.autoUpdate.enabled
580
+ );
514
581
  if (opts.autoUpdate) {
515
582
  try {
516
583
  const { enableAutoupdate } = require('./autoupdate');
517
584
  enableAutoupdate(packageDir);
585
+ autoUpdateEnabled = true;
518
586
  console.log(
519
587
  chalk.green('\n ✓ Auto-update enabled (Claude Code SessionStart hook).') +
520
588
  chalk.gray('\n New Claude Code sessions self-update via npm (throttled, background).')
@@ -524,6 +592,22 @@ async function installCommand(args, config) {
524
592
  }
525
593
  }
526
594
 
595
+ try {
596
+ const manifest = createInstallManifest({
597
+ packageName,
598
+ packageVersion: config.version,
599
+ skillNames: skillDirs,
600
+ universalTarget: path.join(baseDir, UNIVERSAL_DIR),
601
+ agentResults,
602
+ mcpResults,
603
+ autoUpdateEnabled,
604
+ });
605
+ writeInstallManifest(baseDir, manifest);
606
+ } catch (err) {
607
+ console.log(chalk.yellow(`\n ⚠ Could not write install ownership manifest: ${err.message}`));
608
+ process.exitCode = 2;
609
+ }
610
+
527
611
  if (hasFailures) {
528
612
  // Non-zero exit so CI/scripts know something went wrong. Exit code 2
529
613
  // distinguishes partial failure (skills ok, some MCPs failed) from
@@ -537,6 +621,7 @@ module.exports = installCommand;
537
621
  module.exports.parseArgs = parseArgs;
538
622
  module.exports.detectAgents = detectAgents;
539
623
  module.exports.copySkillDir = copySkillDir;
624
+ module.exports.performInstall = performInstall;
540
625
  module.exports.formatFsError = formatFsError;
541
626
  module.exports.AGENTS = AGENTS;
542
627
  module.exports.UNIVERSAL_DIR = UNIVERSAL_DIR;
@@ -27,6 +27,8 @@ const fs = require('fs');
27
27
  const path = require('path');
28
28
  const os = require('os');
29
29
  const { spawn, execSync } = require('child_process');
30
+ const { compareVersions, readInstalledVersion } = require('./update-check');
31
+ const { packageKey } = require('../lib/install-manifest');
30
32
 
31
33
  const PACKAGE_NAME = (() => {
32
34
  try {
@@ -38,13 +40,12 @@ const PACKAGE_NAME = (() => {
38
40
 
39
41
  const DEFAULT_THROTTLE_SECONDS = 3600; // once per hour
40
42
  const STATE_DIR = '.bi-superpowers';
41
- const STATE_FILE = 'autoupdate-state.json';
42
43
 
43
44
  /**
44
45
  * Absolute path to the auto-update state file under the given home dir.
45
46
  */
46
- function stateFilePath(homeDir) {
47
- return path.join(homeDir, STATE_DIR, STATE_FILE);
47
+ function stateFilePath(homeDir, packageName = PACKAGE_NAME) {
48
+ return path.join(homeDir, STATE_DIR, `autoupdate-state-${packageKey(packageName)}.json`);
48
49
  }
49
50
 
50
51
  /**
@@ -141,19 +142,48 @@ function applyUpdate(deps = {}) {
141
142
  const nowMs = typeof deps.nowMs === 'number' ? deps.nowMs : Date.now();
142
143
  const cliPath = deps.cliPath || path.join(__dirname, '..', 'cli.js');
143
144
  const execFn = deps.execFn || ((cmd) => execSync(cmd, { stdio: 'ignore', windowsHide: true }));
145
+ const installedVersion = deps.installedVersion || readInstalledVersion();
146
+ const getLatestVersion =
147
+ deps.getLatestVersion ||
148
+ (() => {
149
+ const raw = execSync(`npm view ${PACKAGE_NAME} version --json`, {
150
+ encoding: 'utf8',
151
+ windowsHide: true,
152
+ });
153
+ const parsed = JSON.parse(String(raw).trim());
154
+ return Array.isArray(parsed) ? parsed.at(-1) : parsed;
155
+ });
144
156
 
145
157
  const state = readState(file);
146
158
  try {
159
+ const latestVersion = deps.latestVersion || getLatestVersion();
160
+ state.installedVersion = installedVersion;
161
+ state.latestVersion = latestVersion;
162
+ state.lastVersionCheck = nowMs;
163
+
164
+ if (
165
+ installedVersion &&
166
+ latestVersion &&
167
+ compareVersions(installedVersion, latestVersion) >= 0
168
+ ) {
169
+ state.lastResult = 'up-to-date';
170
+ writeState(file, state);
171
+ return { updated: false, installedVersion, latestVersion };
172
+ }
173
+
147
174
  execFn(`npm install -g ${PACKAGE_NAME}@latest`);
148
175
  // Refresh the per-agent skill + MCP copies from the freshly installed package.
149
176
  execFn(`node "${cliPath}" install --all --yes`);
150
177
  state.lastUpgrade = nowMs;
151
178
  state.lastResult = 'ok';
179
+ writeState(file, state);
180
+ return { updated: true, installedVersion, latestVersion };
152
181
  } catch (err) {
153
182
  state.lastResult = 'error';
154
183
  state.lastError = err && err.message ? String(err.message).slice(0, 300) : 'unknown';
155
184
  }
156
185
  writeState(file, state);
186
+ return { updated: false, error: state.lastError };
157
187
  }
158
188
 
159
189
  /**
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Template Path Command
3
+ * =====================
4
+ *
5
+ * Prints the absolute path of a packaged template so skills and scripts can
6
+ * stay portable across npm, Git checkouts, and different user profiles.
7
+ */
8
+
9
+ const path = require('path');
10
+ const { resolveTemplate } = require('../lib/template-scaffold');
11
+
12
+ function parseArgs(args) {
13
+ const options = { templateName: 'base-template', json: false };
14
+ for (let index = 0; index < args.length; index++) {
15
+ const arg = args[index];
16
+ if (arg === '--template' || arg === '-t') {
17
+ const value = args[++index];
18
+ if (!value || value.startsWith('-')) {
19
+ throw new Error(`${arg} requires a value`);
20
+ }
21
+ options.templateName = value;
22
+ } else if (arg === '--json') {
23
+ options.json = true;
24
+ } else {
25
+ throw new Error(`Unknown argument: ${arg}`);
26
+ }
27
+ }
28
+ return options;
29
+ }
30
+
31
+ function templatePathCommand(args, config = {}) {
32
+ let options;
33
+ try {
34
+ options = parseArgs(args || []);
35
+ const packageDir = config.packageDir || path.resolve(__dirname, '..', '..');
36
+ const template = resolveTemplate(packageDir, options.templateName);
37
+ if (options.json) {
38
+ console.log(
39
+ JSON.stringify(
40
+ {
41
+ template: template.name,
42
+ path: template.path,
43
+ pbipFile: template.pbipFile,
44
+ },
45
+ null,
46
+ 2
47
+ )
48
+ );
49
+ return;
50
+ }
51
+ console.log(template.path);
52
+ } catch (error) {
53
+ if (options && options.json) {
54
+ console.log(JSON.stringify({ error: error.message }, null, 2));
55
+ } else {
56
+ console.error(`Error: ${error.message}`);
57
+ }
58
+ process.exitCode = 1;
59
+ }
60
+ }
61
+
62
+ module.exports = Object.assign(templatePathCommand, { parseArgs });