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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.claude-plugin/skill-manifest.json +1 -1
- package/.plugin/plugin.json +1 -1
- package/LICENSE +21 -21
- package/README.md +16 -6
- package/bin/cli.js +8 -1
- package/bin/commands/create-from-template.js +5 -0
- package/bin/commands/install.js +100 -15
- package/bin/commands/session-update.js +33 -3
- package/bin/commands/template-path.js +62 -0
- package/bin/commands/uninstall.js +76 -16
- package/bin/commands/update-check.js +29 -18
- package/bin/lib/base-template-smoke.js +80 -40
- package/bin/lib/install-manifest.js +198 -0
- package/bin/lib/powerbi-mcp-session.js +63 -17
- package/bin/lib/template-scaffold.js +40 -5
- package/bin/postinstall.js +0 -0
- package/commands/bi-powerquery.md +2 -1
- package/config.example.json +23 -23
- package/config.json +23 -23
- package/desktop-extension/manifest.json +30 -30
- package/desktop-extension/package.json +10 -10
- package/desktop-extension/server.js +76 -76
- package/package.json +1 -1
- package/skills/bi-connect/SKILL.md +1 -1
- package/skills/bi-connect/scripts/update-check.js +30 -19
- package/skills/bi-dax/SKILL.md +1 -1
- package/skills/bi-dax/scripts/update-check.js +30 -19
- package/skills/bi-kickoff/SKILL.md +1 -1
- package/skills/bi-kickoff/scripts/update-check.js +30 -19
- package/skills/bi-modeling/SKILL.md +1 -1
- package/skills/bi-modeling/scripts/update-check.js +30 -19
- package/skills/bi-performance/SKILL.md +1 -1
- package/skills/bi-performance/scripts/update-check.js +30 -19
- package/skills/bi-powerquery/SKILL.md +3 -2
- package/skills/bi-powerquery/references/base-template-data-contract.md +5 -2
- package/skills/bi-powerquery/scripts/test-powerquery-contract.ps1 +24 -2
- package/skills/bi-powerquery/scripts/update-check.js +30 -19
- package/skills/bi-refactor/SKILL.md +1 -1
- package/skills/bi-refactor/scripts/update-check.js +30 -19
- package/skills/bi-scorecard/SKILL.md +1 -1
- package/skills/bi-scorecard/scripts/update-check.js +30 -19
- package/skills/bi-start/SKILL.md +1 -1
- package/skills/bi-start/scripts/update-check.js +30 -19
- package/src/content/mcp-requirements.json +57 -57
- package/src/content/skills/bi-powerquery/SKILL.md +2 -1
- package/src/content/skills/bi-powerquery/references/base-template-data-contract.md +5 -2
- package/src/content/skills/bi-powerquery/scripts/test-powerquery-contract.ps1 +24 -2
- package/templates/base-template/base-template.Report/.platform +10 -10
- package/templates/base-template/base-template.Report/StaticResources/RegisteredResources/BISuperpowers.json +3887 -3887
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BaseThemes/CY18SU07.json +176 -176
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BaseThemes/Fluent2-CY26SU03.json +4103 -4103
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleCityPark.json +25 -25
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleDefault.json +25 -25
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleNeutral.json +25 -25
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleOrchid.json +25 -25
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleTidal.json +25 -25
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Bloom.json +138 -138
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/CityPark.json +39 -39
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Classroom.json +39 -39
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/ColorblindSafe.json +47 -47
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/CopilotDefault.json +1860 -1860
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Divergent.json +126 -126
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Electric.json +47 -47
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Frontier.json +135 -135
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/HighContrast.json +39 -39
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Highrise.json +40 -40
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Innovate.json +226 -226
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/NewExecutive.json +40 -40
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Solar.json +32 -32
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Storm.json +24 -24
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Sunset.json +47 -47
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Temperature.json +32 -32
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Tidal.json +99 -99
- package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Twilight.json +39 -39
- package/templates/base-template/base-template.Report/definition/bookmarks/1d40d43c7ade66e8603c.bookmark.json +2296 -2296
- package/templates/base-template/base-template.Report/definition/bookmarks/af068ff51c0ca3089ea7.bookmark.json +2299 -2299
- package/templates/base-template/base-template.Report/definition/bookmarks/bookmarks.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/page.json +129 -129
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/0352fd80d074693a65db/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/0352fd80d074693a65db/visual.json +668 -668
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/1c5a14bf493697344b68/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/1c5a14bf493697344b68/visual.json +722 -722
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/3486cf7624c5b109b4e5/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/3486cf7624c5b109b4e5/visual.json +332 -332
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/4d8b989008edc0db28d1/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/4d8b989008edc0db28d1/visual.json +108 -108
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/55e10ac7d76a1954f94f/mobile.json +30 -30
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/55e10ac7d76a1954f94f/visual.json +377 -377
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/57f52ecf4490f70e4da1/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/57f52ecf4490f70e4da1/visual.json +174 -174
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/5f4d76bbc870118e9840/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/5f4d76bbc870118e9840/visual.json +467 -467
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/73629e1abebb7a444b59/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/73629e1abebb7a444b59/visual.json +359 -358
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/749cb1388c7e0a88161c/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/749cb1388c7e0a88161c/visual.json +689 -689
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/90677f13cea5d1275990/visual.json +15 -16
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/92cf92e3da10493adb78/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/92cf92e3da10493adb78/visual.json +467 -467
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/9fe17b1971f68443fc15/mobile.json +9 -9
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/9fe17b1971f68443fc15/visual.json +327 -327
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a30bd0950630ed94e8a3/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a30bd0950630ed94e8a3/visual.json +577 -577
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a56e91d9400a835e4814/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a56e91d9400a835e4814/visual.json +431 -431
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/aded24cd205c0b528642/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/aded24cd205c0b528642/visual.json +800 -800
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/af34b26f14a8a724c9a9/mobile.json +36 -36
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/af34b26f14a8a724c9a9/visual.json +1317 -1317
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/b529688fe5a226643322/visual.json +208 -208
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/c4c6f332d05e72e2eb06/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/c4c6f332d05e72e2eb06/visual.json +173 -173
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/fa81f184e2cb0e8b087c/mobile.json +28 -28
- package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/fa81f184e2cb0e8b087c/visual.json +240 -240
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/page.json +129 -129
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/07e9c4302e29029c5462/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/07e9c4302e29029c5462/visual.json +689 -689
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/109ceede4bc015b0c006/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/109ceede4bc015b0c006/visual.json +467 -467
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/118257e006d472277e10/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/118257e006d472277e10/visual.json +358 -358
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/2caf02e0137c4a1280cc/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/2caf02e0137c4a1280cc/visual.json +668 -668
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/311e76fe3c9edad68204/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/311e76fe3c9edad68204/visual.json +108 -108
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/31c21f8cbeb3b208940a/visual.json +208 -208
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/3ab72c25062437149b03/visual.json +16 -16
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5959867442abcb0ce2b3/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5959867442abcb0ce2b3/visual.json +787 -787
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5b96e0f88d192b044a13/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5b96e0f88d192b044a13/visual.json +591 -591
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/64e749a63d0786000e22/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/64e749a63d0786000e22/visual.json +467 -467
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/7ae1ca604edac6586ad0/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/7ae1ca604edac6586ad0/visual.json +1309 -1309
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/840300733885141a6603/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/840300733885141a6603/visual.json +174 -174
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/a38448cdb203279273d2/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/a38448cdb203279273d2/visual.json +515 -515
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d1e86f213a3841d12e20/visual.json +327 -327
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d4a484c1bcc8ee3075e2/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d4a484c1bcc8ee3075e2/visual.json +431 -431
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d87cb5cf06acca19bbb5/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d87cb5cf06acca19bbb5/visual.json +240 -240
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/e243da2677209ed69408/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/e243da2677209ed69408/visual.json +173 -173
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/f3aaf24f5b22b67573b0/mobile.json +10 -10
- package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/f3aaf24f5b22b67573b0/visual.json +332 -332
- package/templates/base-template/base-template.Report/definition/pages/pages.json +7 -7
- package/templates/base-template/base-template.Report/definition/report.json +88 -88
- package/templates/base-template/base-template.Report/definition/version.json +3 -3
- package/templates/base-template/base-template.Report/definition.pbir +8 -8
- package/templates/base-template/base-template.SemanticModel/.platform +10 -10
- package/templates/base-template/base-template.SemanticModel/definition/cultures/es-AR.tmdl +11185 -11185
- package/templates/base-template/base-template.SemanticModel/definition/database.tmdl +5 -3
- package/templates/base-template/base-template.SemanticModel/definition/expressions.tmdl +340 -234
- package/templates/base-template/base-template.SemanticModel/definition/functions.tmdl +637 -637
- package/templates/base-template/base-template.SemanticModel/definition/model.tmdl +85 -82
- package/templates/base-template/base-template.SemanticModel/definition/relationships.tmdl +263 -271
- package/templates/base-template/base-template.SemanticModel/definition/tables/Calendario.tmdl +200 -200
- package/templates/base-template/base-template.SemanticModel/definition/tables/Campa/303/261as.tmdl +75 -75
- package/templates/base-template/base-template.SemanticModel/definition/tables/Canales.tmdl +84 -84
- package/templates/base-template/base-template.SemanticModel/definition/tables/Clientes.tmdl +126 -143
- package/templates/base-template/base-template.SemanticModel/definition/tables/Devoluciones.tmdl +64 -95
- package/templates/base-template/base-template.SemanticModel/definition/tables/Ejecuci/303/263n proyectos.tmdl" +98 -130
- package/templates/base-template/base-template.SemanticModel/definition/tables/Entregas.tmdl +77 -122
- package/templates/base-template/base-template.SemanticModel/definition/tables/Equipos m/303/251tricas.tmdl" +40 -40
- package/templates/base-template/base-template.SemanticModel/definition/tables/Equipos.tmdl +47 -73
- package/templates/base-template/base-template.SemanticModel/definition/tables/Horas.tmdl +91 -122
- package/templates/base-template/base-template.SemanticModel/definition/tables/Interacciones clientes.tmdl +95 -146
- package/templates/base-template/base-template.SemanticModel/definition/tables/Leads.tmdl +90 -119
- package/templates/base-template/base-template.SemanticModel/definition/tables/Monedas.tmdl +44 -44
- package/templates/base-template/base-template.SemanticModel/definition/tables/Movimientos financieros.tmdl +146 -145
- package/templates/base-template/base-template.SemanticModel/definition/tables/M/303/251tricas.tmdl +1324 -1294
- package/templates/base-template/base-template.SemanticModel/definition/tables/N/303/263mina.tmdl +82 -110
- package/templates/base-template/base-template.SemanticModel/definition/tables/Oportunidades.tmdl +83 -135
- package/templates/base-template/base-template.SemanticModel/definition/tables/Presupuesto.tmdl +101 -125
- package/templates/base-template/base-template.SemanticModel/definition/tables/Productos.tmdl +98 -98
- package/templates/base-template/base-template.SemanticModel/definition/tables/Proyectos.tmdl +77 -77
- package/templates/base-template/base-template.SemanticModel/definition/tables/Servicios.tmdl +75 -75
- package/templates/base-template/base-template.SemanticModel/definition/tables/Tareas proyecto.tmdl +73 -102
- package/templates/base-template/base-template.SemanticModel/definition/tables/Tipo de cambio.tmdl +67 -67
- package/templates/base-template/base-template.SemanticModel/definition/tables/Ventas.tmdl +142 -180
- package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux An/303/241lisis dimensiones.tmdl" +38 -38
- package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Comparaciones.tmdl +227 -227
- package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Compatibilidad m/303/251trica-dimensi/303/263n.tmdl" +68 -68
- package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Modelo configuraci/303/263n.tmdl" +44 -44
- package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Modo fechas.tmdl +36 -36
- package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux M/303/251trica-Equipo.tmdl" +101 -102
- package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Overrides m/303/251trica-dimensi/303/263n.tmdl" +57 -54
- package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Per/303/255odos.tmdl" +182 -182
- package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Rango fechas modo.tmdl +36 -36
- package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Rango fechas.tmdl +27 -27
- package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Vista de calendario.tmdl +30 -30
- package/templates/base-template/base-template.SemanticModel/definition/tables/_GC C/303/241lculo.tmdl" +70 -70
- package/templates/base-template/base-template.SemanticModel/definition/tables/_GC Eje X.tmdl +63 -63
- package/templates/base-template/base-template.SemanticModel/definition/tables/_GC M/303/251trica.tmdl" +374 -374
- package/templates/base-template/base-template.SemanticModel/definition/tables/_GC Tipo c/303/241lculo.tmdl" +223 -223
- package/templates/base-template/base-template.SemanticModel/definition/tables/_PC Dimensi/303/263n.tmdl" +98 -98
- package/templates/base-template/base-template.SemanticModel/definition/tables/_PC Eje X.tmdl +68 -68
- package/templates/base-template/base-template.SemanticModel/definition/tables//303/223rdenes servicio.tmdl" +121 -151
- package/templates/base-template/base-template.SemanticModel/definition.pbism +4 -4
- package/templates/base-template/base-template.SemanticModel/diagramLayout.json +567 -567
- package/templates/base-template/base-template.pbip +13 -13
- 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.
|
|
9
|
+
"version": "1.1.1",
|
|
10
10
|
"repository": "https://github.com/luquimbo/bi-superpowers"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
package/.plugin/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"spec": "open-plugin-spec@1",
|
|
3
3
|
"name": "bi-superpowers",
|
|
4
|
-
"version": "1.
|
|
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.
|
|
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
|
|
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
|
|
720
|
-
|
|
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
|
|
package/bin/commands/install.js
CHANGED
|
@@ -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(
|
|
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)
|
|
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 (
|
|
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({
|
|
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
|
-
//
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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({
|
|
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(
|
|
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 =
|
|
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,
|
|
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 });
|