@luquimbo/bi-superpowers 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) 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/README.md +2 -2
  6. package/bin/build-plugin.js +6 -6
  7. package/bin/cli.js +169 -310
  8. package/bin/commands/install.js +87 -70
  9. package/bin/commands/install.test.js +2 -2
  10. package/bin/lib/agents.js +21 -2
  11. package/bin/lib/mcp-config.js +27 -5
  12. package/bin/lib/mcp-config.test.js +1 -1
  13. package/desktop-extension/manifest.json +4 -11
  14. package/desktop-extension/server.js +34 -25
  15. package/package.json +3 -9
  16. package/skills/pbi-connect/SKILL.md +1 -1
  17. package/skills/project-kickoff/SKILL.md +1 -1
  18. package/bin/commands/add.js +0 -533
  19. package/bin/commands/add.test.js +0 -77
  20. package/bin/commands/changelog.js +0 -443
  21. package/bin/commands/pull.js +0 -287
  22. package/bin/commands/pull.test.js +0 -36
  23. package/bin/commands/push.js +0 -231
  24. package/bin/commands/push.test.js +0 -14
  25. package/bin/commands/search.js +0 -344
  26. package/bin/commands/search.test.js +0 -115
  27. package/bin/commands/setup.js +0 -545
  28. package/bin/commands/setup.test.js +0 -46
  29. package/bin/commands/sync-profile.js +0 -405
  30. package/bin/commands/sync-profile.test.js +0 -14
  31. package/bin/commands/sync-source.js +0 -418
  32. package/bin/commands/sync-source.test.js +0 -14
  33. package/bin/utils/errors.js +0 -159
  34. package/bin/utils/git.js +0 -298
  35. package/bin/utils/logger.js +0 -142
  36. package/bin/utils/pbix.js +0 -305
  37. package/bin/utils/pbix.test.js +0 -37
  38. package/bin/utils/profiles.js +0 -312
  39. package/bin/utils/projects.js +0 -169
  40. package/bin/utils/readline.js +0 -206
  41. package/bin/utils/readline.test.js +0 -47
  42. package/docs/openrouter-free-models.md +0 -92
  43. package/library/examples/README.md +0 -151
  44. package/library/examples/finance-reporting/README.md +0 -351
  45. package/library/examples/finance-reporting/data-model.md +0 -267
  46. package/library/examples/finance-reporting/measures.dax +0 -557
  47. package/library/examples/hr-analytics/README.md +0 -371
  48. package/library/examples/hr-analytics/data-model.md +0 -315
  49. package/library/examples/hr-analytics/measures.dax +0 -460
  50. package/library/examples/marketing-analytics/README.md +0 -37
  51. package/library/examples/marketing-analytics/data-model.md +0 -62
  52. package/library/examples/marketing-analytics/measures.dax +0 -110
  53. package/library/examples/retail-analytics/README.md +0 -439
  54. package/library/examples/retail-analytics/data-model.md +0 -288
  55. package/library/examples/retail-analytics/measures.dax +0 -481
  56. package/library/examples/supply-chain/README.md +0 -37
  57. package/library/examples/supply-chain/data-model.md +0 -69
  58. package/library/examples/supply-chain/measures.dax +0 -77
  59. package/library/examples/udf-library/README.md +0 -228
  60. package/library/examples/udf-library/functions.dax +0 -571
  61. package/library/snippets/dax/README.md +0 -292
  62. package/library/snippets/dax/business-domains.md +0 -576
  63. package/library/snippets/dax/calculate-patterns.md +0 -276
  64. package/library/snippets/dax/calculation-groups.md +0 -489
  65. package/library/snippets/dax/error-handling.md +0 -495
  66. package/library/snippets/dax/iterators-and-aggregations.md +0 -474
  67. package/library/snippets/dax/kpis-and-metrics.md +0 -293
  68. package/library/snippets/dax/rankings-and-topn.md +0 -235
  69. package/library/snippets/dax/security-patterns.md +0 -413
  70. package/library/snippets/dax/text-and-formatting.md +0 -316
  71. package/library/snippets/dax/time-intelligence.md +0 -196
  72. package/library/snippets/dax/user-defined-functions.md +0 -477
  73. package/library/snippets/dax/virtual-tables.md +0 -546
  74. package/library/snippets/excel-formulas/README.md +0 -84
  75. package/library/snippets/excel-formulas/aggregations.md +0 -330
  76. package/library/snippets/excel-formulas/dates-and-times.md +0 -361
  77. package/library/snippets/excel-formulas/dynamic-arrays.md +0 -314
  78. package/library/snippets/excel-formulas/lookups.md +0 -169
  79. package/library/snippets/excel-formulas/text-functions.md +0 -363
  80. package/library/snippets/governance/naming-conventions.md +0 -97
  81. package/library/snippets/governance/review-checklists.md +0 -107
  82. package/library/snippets/power-query/README.md +0 -389
  83. package/library/snippets/power-query/api-integration.md +0 -707
  84. package/library/snippets/power-query/connections.md +0 -434
  85. package/library/snippets/power-query/data-cleaning.md +0 -298
  86. package/library/snippets/power-query/error-handling.md +0 -526
  87. package/library/snippets/power-query/parameters.md +0 -350
  88. package/library/snippets/power-query/performance.md +0 -506
  89. package/library/snippets/power-query/transformations.md +0 -330
  90. package/library/snippets/report-design/accessibility.md +0 -78
  91. package/library/snippets/report-design/chart-selection.md +0 -54
  92. package/library/snippets/report-design/layout-patterns.md +0 -87
  93. package/library/templates/data-models/README.md +0 -93
  94. package/library/templates/data-models/finance-model.md +0 -627
  95. package/library/templates/data-models/retail-star-schema.md +0 -473
  96. package/library/templates/excel/README.md +0 -83
  97. package/library/templates/excel/budget-tracker.md +0 -432
  98. package/library/templates/excel/data-entry-form.md +0 -533
  99. package/library/templates/power-bi/README.md +0 -72
  100. package/library/templates/power-bi/finance-report.md +0 -449
  101. package/library/templates/power-bi/kpi-scorecard.md +0 -461
  102. package/library/templates/power-bi/sales-dashboard.md +0 -281
  103. package/library/themes/excel/README.md +0 -436
  104. package/library/themes/power-bi/README.md +0 -271
  105. package/library/themes/power-bi/accessible.json +0 -307
  106. package/library/themes/power-bi/bi-superpowers-default.json +0 -858
  107. package/library/themes/power-bi/corporate-blue.json +0 -291
  108. package/library/themes/power-bi/dark-mode.json +0 -291
  109. package/library/themes/power-bi/minimal.json +0 -292
  110. package/library/themes/power-bi/print-friendly.json +0 -309
package/bin/cli.js CHANGED
@@ -1,21 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * BI Agent Superpowers - Command Line Interface
4
+ * BI Agent Superpowers Command Line Interface
5
5
  * ==============================================
6
6
  *
7
- * This is the main entry point for the BI Agent Superpowers CLI tool.
8
- * It provides commands to initialize, configure, and manage AI-powered
9
- * assistance for Power BI, Fabric, and Excel development.
7
+ * Main entry point for the `super` CLI. Provides commands to install
8
+ * skills and MCP servers into AI coding agents, and to generate the
9
+ * native Claude Code plugin into a project.
10
10
  *
11
11
  * Architecture:
12
- * - Single Source of Truth: Skills are defined ONCE in src/content/skills/
13
- * and generated for the Claude Code plugin.
14
- * - Supports: Claude Code, 1code.dev, Claude Desktop (via MCPB).
12
+ * - Skills are authored once in src/content/skills/ and copied out to
13
+ * each supported agent by `super install`.
14
+ * - `super kickoff` generates a full Claude Code plugin tree in a
15
+ * user project (skills + commands + MCP config).
16
+ * - `super recharge` regenerates that plugin after local edits.
15
17
  *
16
- * Licensing:
17
- * - Open source (MIT) — no license activation required
18
- * - All skills and library content ship with the npm package
18
+ * Supported agents: Claude Code, GitHub Copilot, Codex, Gemini CLI, Kilo Code.
19
+ * License: MIT. This project is fully open source — no activation, no keys.
19
20
  *
20
21
  * @module cli
21
22
  * @author Lucas Sanchez (@luquimbo)
@@ -27,114 +28,96 @@ const path = require('path');
27
28
  const { execSync } = require('child_process');
28
29
  const { loadSkills } = require('./lib/skills');
29
30
 
30
- // Import lib modules (extracted from cli.js for better organization)
31
+ // Optional lib import may not be available during npm install phase.
31
32
  let generators;
32
33
  try {
33
34
  generators = require('./lib/generators');
34
- } catch (e) {
35
- // Modules may not be available during npm install phase
35
+ } catch (_) {
36
+ // Silent fallback; commands will report a useful error when invoked.
36
37
  }
37
38
 
38
- // Import command modules - these provide the xray, checkup, scan, sentinel, and mcp-setup commands
39
- // Wrapped in try-catch because they may not be available during initial npm install
40
- let searchCommand, lintCommand, diffCommand, watchCommand, mcpSetupCommand, tui;
41
- let setupCommand, addCommand, pullCommand, pushCommand, syncProfileCommand, syncSourceCommand;
42
- let changelogCommand, buildDesktopCommand, installCommand;
39
+ // Optional command imports each module may fail to load during npm
40
+ // install before dependencies are wired up. The CLI still renders `help`
41
+ // and `version` because those are hoisted, module-free functions.
42
+ let lintCommand;
43
+ let diffCommand;
44
+ let watchCommand;
45
+ let mcpSetupCommand;
46
+ let buildDesktopCommand;
47
+ let installCommand;
48
+ let tui;
43
49
  try {
44
- searchCommand = require('./commands/search'); // Fuzzy search across library content
45
- lintCommand = require('./commands/lint'); // Skill file validation
46
- diffCommand = require('./commands/diff'); // Compare source vs generated configs
47
- watchCommand = require('./commands/watch'); // Auto-regenerate on file changes
50
+ lintCommand = require('./commands/lint'); // checkup: skill file validation
51
+ diffCommand = require('./commands/diff'); // scan: diff source vs generated
52
+ watchCommand = require('./commands/watch'); // sentinel: watch + auto regen
48
53
  mcpSetupCommand = require('./commands/mcp-setup'); // MCP server configuration
49
- tui = require('./utils/tui'); // Terminal UI helpers (colors, tables, etc.)
50
-
51
- // Repo multi-project commands (v3)
52
- setupCommand = require('./commands/setup'); // Onboarding wizard for bi-repo
53
- addCommand = require('./commands/add'); // Add project to repo
54
- pullCommand = require('./commands/pull'); // Pull changes from original file
55
- pushCommand = require('./commands/push'); // Push changes to original file
56
- syncProfileCommand = require('./commands/sync-profile'); // Sync snippets to profile
57
- syncSourceCommand = require('./commands/sync-source'); // Bidirectional sync
58
- changelogCommand = require('./commands/changelog'); // Generate changelog from Git
59
- buildDesktopCommand = require('./commands/build-desktop'); // Build MCPB for Claude Desktop
60
- installCommand = require('./commands/install'); // Multi-agent skill installer
61
- } catch (e) {
62
- // Silent fail - commands may not be available during npm install phase
63
- // This is expected behavior, not an error condition
54
+ buildDesktopCommand = require('./commands/build-desktop'); // .mcpb for Claude Desktop
55
+ installCommand = require('./commands/install'); // multi-agent skill + MCP installer
56
+ tui = require('./utils/tui'); // colors, tables, boxes for CLI output
57
+ } catch (_) {
58
+ // Expected during `npm install` modules become available after deps are linked.
64
59
  }
65
60
 
66
61
  // ============================================
67
62
  // CONFIGURATION CONSTANTS
68
63
  // ============================================
69
64
 
70
- /** Package version from package.json */
65
+ /** Package version (read from package.json at runtime) */
71
66
  const VERSION = require('../package.json').version;
72
67
 
73
- /** Dynamic skill/command counts from the plugin generator (avoids hardcoding) */
74
- let COMMAND_COUNT = 11;
75
- let TOTAL_SKILL_COUNT = 24;
68
+ /**
69
+ * Skill and command counts used by the help text and dry-run previews.
70
+ * Pulled dynamically from the generator so we never hardcode outdated totals.
71
+ */
72
+ let COMMAND_COUNT = 0;
73
+ let TOTAL_SKILL_COUNT = 0;
76
74
  try {
77
75
  const { COMMAND_SKILLS, REFERENCE_SKILLS } = require('./lib/generators/claude-plugin');
78
76
  COMMAND_COUNT = COMMAND_SKILLS.size;
79
77
  TOTAL_SKILL_COUNT = COMMAND_SKILLS.size + REFERENCE_SKILLS.size;
80
78
  } catch (_) {
81
- // Fallback to defaults during npm install phase
79
+ // Fallback during npm install phase — values stay at 0 until the module loads.
82
80
  }
83
81
 
84
- /** Directory where the npm package is installed */
82
+ /** Absolute path to the installed package directory (one level above bin/) */
85
83
  const PACKAGE_DIR = path.dirname(__dirname);
86
84
 
87
- /** Directory containing skill source files (.md) */
85
+ /** Directory containing the authoring source for each skill */
88
86
  const SKILLS_DIR = path.join(PACKAGE_DIR, 'src', 'content', 'skills');
89
87
 
90
- /** Directory containing code snippets, templates, and themes */
91
- const LIBRARY_DIR = path.join(PACKAGE_DIR, 'library');
92
-
93
- /** Project-local config file name (stores tool selections) */
88
+ /** Project-local config file name used by kickoff/recharge */
94
89
  const CONFIG_FILE = '.bi-superpowers.json';
95
90
 
96
- /** npm package name for update commands */
91
+ /** npm package name for the upgrade command */
97
92
  const PACKAGE_NAME = '@luquimbo/bi-superpowers';
93
+
94
+ /** Default tool set generated by kickoff (currently only the Claude Code plugin) */
98
95
  const DEFAULT_TOOLS = ['claude-plugin'];
99
96
 
100
- /**
101
- * AI Tools Configuration - uses generators from lib/generators module
102
- * Falls back to empty object if module not loaded
103
- */
97
+ /** Generator registry (populated from lib/generators if available) */
104
98
  const AI_TOOLS = generators ? generators.AI_TOOLS : {};
105
99
 
106
- /**
107
- * Command Routing Map
108
- *
109
- * Maps CLI command names to their handler functions.
110
- * Supports both branded names (kickoff, recharge) and legacy names (init, sync)
111
- * for backward compatibility.
112
- *
113
- * Command Categories:
114
- * - Core: Basic info commands (help, version, about, status)
115
- * - Setup: Project initialization and configuration (kickoff, recharge, upgrade)
116
- * - Developer: Advanced tools for content management (xray, checkup, scan, sentinel, powers)
117
- * - Legacy: Old command names maintained for backward compatibility
118
- */
119
- // Commands are registered in two phases to avoid TDZ (temporal dead zone) errors.
120
- // Phase 1: hoisted function declarations (showHelp, initProject, etc.) go directly
121
- // into the object literal below — safe because `function` declarations hoist.
122
- // Phase 2: wrapper-based commands that depend on `createCommandWrapper` (defined
123
- // further down in the file) are attached imperatively after that function exists.
124
- // See the `commands.xray = runSearch;` block after the wrapper `const`s.
100
+ // ============================================
101
+ // COMMAND ROUTING
102
+ // ============================================
103
+ // Commands are registered in two phases to avoid temporal-dead-zone errors.
104
+ // Phase 1: hoisted function declarations (help, version, about, kickoff...)
105
+ // go directly into the object literal below.
106
+ // Phase 2: wrapper-based commands that depend on createCommandWrapper
107
+ // (defined further below) are attached imperatively.
125
108
  const commands = {
126
- // Core commands - basic info (hoisted functions, safe here)
109
+ // Core commands hoisted functions, safe to reference here.
127
110
  help: showHelp,
128
111
  version: showVersion,
129
112
  about: showInfo,
130
113
 
131
- // Setup & sync - project configuration (hoisted functions, safe here)
114
+ // Primary flow also hoisted functions.
132
115
  kickoff: initProject,
133
116
  recharge: syncProject,
134
117
  upgrade: updatePackage,
135
118
  powers: listAgents,
136
119
 
137
- // Legacy aliases (hoisted functions, safe here)
120
+ // Legacy aliases kept for backwards compatibility.
138
121
  init: initProject,
139
122
  sync: syncProject,
140
123
  update: updatePackage,
@@ -143,7 +126,7 @@ const commands = {
143
126
  };
144
127
 
145
128
  /**
146
- * Main entry point - parses CLI arguments and routes to appropriate command
129
+ * Main entry point parses CLI arguments and routes to the handler.
147
130
  */
148
131
  function main() {
149
132
  const args = process.argv.slice(2);
@@ -163,67 +146,47 @@ function showHelp() {
163
146
  BI Agent Superpowers v${VERSION}
164
147
  ================================
165
148
 
166
- Claude Code plugin for Power BI, Fabric & Excel development.
149
+ Open-source toolkit for Power BI Desktop development across 5 AI coding agents:
150
+ Claude Code · GitHub Copilot · Codex · Gemini CLI · Kilo Code.
167
151
 
168
152
  Quick Start:
169
- super kickoff # Genera el plugin en tu proyecto
170
- claude --plugin-dir . # Abrí Claude Code con el plugin
153
+ super install # Install skills + MCPs for all your AI agents
154
+ super kickoff # Generate the Claude Code plugin in a project
171
155
 
172
156
  Usage:
173
157
  super <command> [options]
174
158
 
175
- Primary commands (Claude Code):
176
- kickoff [path] Genera el plugin completo (skills + commands + MCPs)
177
- recharge [path] Regenerá el plugin tras editar skills fuente
178
- build-desktop Buildea la extensión .mcpb para Claude Desktop
179
- mcp-setup Configurá los MCP servers de Microsoft
180
- powers Listá skills y recursos disponibles
181
- upgrade Actualizá a la última versión
182
- about Info de la instalación
183
- help Mostrá esta ayuda
159
+ Primary commands:
160
+ install Install the 2 skills + 2 MCPs across your AI agents
161
+ kickoff [path] Generate the full Claude Code plugin in a project
162
+ recharge [path] Regenerate the plugin after editing source skills
163
+ build-desktop Build the .mcpb extension for Claude Desktop
164
+ mcp-setup Configure the official Microsoft MCP servers
165
+ powers List available skills and MCPs
166
+ upgrade Update to the latest version on npm
167
+ about Show installation info
168
+ help Show this help
184
169
 
185
170
  Developer tools:
186
- xray <query> Buscá snippets y contenido de la biblioteca
187
- checkup [file] Validá archivos de skills
188
- scan Diff entre source y generated
189
- sentinel Watch y auto-regenerá
190
-
191
- Repo Multi-Proyecto:
192
- setup Creá tu bi-repo para version control
193
- add <file> Agregá un proyecto .pbix/.xlsx al repo
194
- pull [project] Pull changes desde el archivo original
195
- push [project] Push changes al archivo original
196
- sync-source Bidirectional sync (detecta cuál es más nuevo)
197
- sync-profile Sync snippets al profile base
198
-
199
- Experimental (solo skills, sin commands ni MCPs):
200
- install Instalá skills en otros agentes AI (Copilot, Codex, Gemini, Kilo)
171
+ checkup [file] Lint/validate skill source files
172
+ scan Diff between source skills and generated plugin
173
+ sentinel Watch skill sources and auto-regenerate
201
174
 
202
175
  Options:
203
- --dry-run Preview de cambios sin escribir archivos (kickoff, recharge)
176
+ --dry-run Preview changes without writing files (kickoff, recharge)
204
177
 
205
178
  Examples:
206
- super kickoff # Inicializá el plugin en el directorio actual
207
- super kickoff ./my-project # Inicializá en un directorio específico
208
- super kickoff --dry-run # Preview de qué archivos se crearían
209
- super recharge # Regenerá el plugin tras editar skills
210
- super build-desktop # Buildeá .mcpb para Claude Desktop
211
- super mcp-setup # Configurá los MCPs de Microsoft
212
- super powers # Mostrá todos los skills disponibles
213
- claude --plugin-dir . # Corré Claude Code con el plugin
214
-
215
- super install # [Experimental] Instalá skills en otros agentes
216
- super install -a claude-code # Instalá solo para un agente específico
217
-
218
- Repo Multi-Proyecto:
219
- super setup # Create your bi-repo (first time)
220
- super add "Sales.pbix" # Add project to repo
221
- super pull # Pull changes from original
222
- super push # Push changes to original
223
- super sync-source # Auto-detect and sync
224
- super sync-profile # Save snippets to profile
225
-
226
- Open source — MIT licensed
179
+ super install # Interactive installer for all agents
180
+ super install --all --yes # Non-interactive install for every agent
181
+ super install -a claude-code # Install only for Claude Code
182
+ super kickoff # Initialize plugin in current directory
183
+ super kickoff ./my-project # Initialize in a specific directory
184
+ super kickoff --dry-run # Preview what would be created
185
+ super recharge # Regenerate plugin after editing skills
186
+ super build-desktop # Build .mcpb for Claude Desktop
187
+ super mcp-setup # Configure the local Power BI Modeling MCP
188
+
189
+ Open source MIT licensed.
227
190
  Documentation: https://github.com/luquimbo/bi-superpowers
228
191
  `);
229
192
  }
@@ -235,11 +198,11 @@ function showVersion() {
235
198
  function showInfo() {
236
199
  const skillCount = getSkillFiles().length;
237
200
  const aiToolsList = Object.entries(AI_TOOLS)
238
- .map(([_k, v]) => ` - ${v.name}`)
201
+ .map(([, v]) => ` - ${v.name}`)
239
202
  .join('\n');
240
203
 
241
204
  console.log(`
242
- BI Agent Superpowers - Installation Info
205
+ BI Agent Superpowers Installation Info
243
206
  ========================================
244
207
 
245
208
  Version: ${VERSION}
@@ -248,62 +211,41 @@ Package dir: ${PACKAGE_DIR}
248
211
  Skills: ${skillCount} available
249
212
  License: MIT (open source)
250
213
 
251
- Architecture: Single Source of Truth
252
- Skills defined once, generated for the Claude Code plugin
214
+ Supported AI agents:
215
+ - Claude Code (native plugin + MCP)
216
+ - GitHub Copilot (agent skills + MCP)
217
+ - Codex (OpenAI) (agent skills + MCP)
218
+ - Gemini CLI (agent skills + MCP)
219
+ - Kilo Code (agent skills + MCP)
253
220
 
254
- Compatible with:
255
- - Claude Code (plugin)
256
- - GitHub Copilot (agent skills)
257
- - Codex (OpenAI)
258
- - Gemini CLI
259
- - Kilo Code
260
- - Claude Desktop (via MCPB extension)
261
-
262
- Plugin Generators:
221
+ Plugin generators:
263
222
  ${aiToolsList}
264
223
 
265
224
  GitHub: https://github.com/luquimbo/bi-superpowers
266
225
  `);
267
226
  }
268
227
 
269
- // ============================================
270
- // LICENSE MANAGEMENT
271
- // ============================================
272
228
  // ============================================
273
229
  // SKILL FILE MANAGEMENT
274
230
  // ============================================
275
- // Functions for reading and parsing skill definition files.
276
- // Skills are markdown files in src/content/skills/ that define
277
- // AI assistant behaviors, triggers, and code patterns.
278
231
 
279
232
  /**
280
- * Get all skill files from the source directory
281
- *
282
- * Reads all .md files from the skills directory and returns their metadata.
283
- * Each skill file contains:
284
- * - Trigger keywords that activate the skill
285
- * - Identity/role description for the AI
286
- * - Mandatory rules and constraints
287
- * - Code examples and patterns
288
- *
289
- * @returns {Array<{name: string, path: string, content: string}>} Array of skill objects
233
+ * Load all skill source files from the package.
234
+ * @returns {Array<{name: string, path: string, content: string}>}
290
235
  */
291
236
  function getSkillFiles() {
292
- return loadSkills({
293
- packageDir: PACKAGE_DIR,
294
- preferLocal: true,
295
- });
237
+ return loadSkills({ packageDir: PACKAGE_DIR });
296
238
  }
297
239
 
298
240
  /**
299
- * Extract skill metadata from markdown content
300
- * Delegates to generators module if available
241
+ * Extract lightweight metadata (title, triggers, identity) from a skill's
242
+ * markdown content. Delegates to the generators module when available.
301
243
  */
302
244
  function parseSkillMetadata(content) {
303
245
  if (generators && generators.parseSkillMetadata) {
304
246
  return generators.parseSkillMetadata(content);
305
247
  }
306
- // Fallback for when module not loaded
248
+ // Minimal fallback when the module isn't loaded yet.
307
249
  const metadata = { title: '', triggers: [], identity: '' };
308
250
  const titleMatch = content.match(/^#\s+(.+)/m);
309
251
  if (titleMatch) metadata.title = titleMatch[1];
@@ -311,23 +253,20 @@ function parseSkillMetadata(content) {
311
253
  }
312
254
 
313
255
  // ============================================
314
- // PROJECT INITIALIZATION
256
+ // PROJECT INITIALIZATION (kickoff / recharge)
315
257
  // ============================================
316
- // Functions for setting up BI Agent Superpowers in a user's project.
317
- // This involves generating tool-specific config files and saving preferences.
318
258
 
319
259
  /**
320
- * Initialize project with interactive prompts (super kickoff)
260
+ * `super kickoff` generate the Claude Code plugin in the target directory.
321
261
  *
322
- * This is the main setup wizard that:
323
- * 1. Generates config files for the Claude Code plugin in the target directory
324
- * 2. Saves the selected tools to .bi-superpowers.json
325
- * 3. Copies a default config.json template if none exists
262
+ * What it does:
263
+ * 1. Generates .claude-plugin/, .mcp.json, commands/, skills/ in the target.
264
+ * 2. Writes .bi-superpowers.json tracking tool selections.
265
+ * 3. Copies a default config.json template if none exists yet.
326
266
  *
327
- * Supports --dry-run flag to preview changes without writing files.
267
+ * Supports --dry-run to preview without writing files.
328
268
  *
329
- * @param {string[]} args - Command line arguments
330
- * @param {string} [args[0]] - Target directory (defaults to cwd)
269
+ * @param {string[]} args - CLI arguments (first positional = target dir)
331
270
  */
332
271
  async function initProject(args) {
333
272
  const dryRun = hasDryRunFlag(args);
@@ -345,7 +284,6 @@ Initializing in: ${targetDir}
345
284
  Skills available: ${skills.length}
346
285
  `);
347
286
 
348
- // Show dry-run notice
349
287
  if (dryRun) {
350
288
  if (tui) {
351
289
  tui.dryRunNotice();
@@ -373,13 +311,9 @@ Skills available: ${skills.length}
373
311
  return;
374
312
  }
375
313
 
376
- // Save selected tools to config
377
314
  saveToolConfig(targetDir, selectedTools);
378
-
379
- // Ensure project-level config.json exists (used as AI preferences/context)
380
315
  ensureProjectConfigJson(targetDir);
381
316
 
382
- // Generate configs for selected tools
383
317
  console.log('');
384
318
  for (const tool of selectedTools) {
385
319
  await generateForTool(tool, targetDir, skills);
@@ -389,20 +323,15 @@ Skills available: ${skills.length}
389
323
  }
390
324
 
391
325
  /**
392
- * Sync project - regenerate configs without prompts (super recharge)
393
- *
394
- * Regenerates the Claude Code plugin and any configured legacy adapters.
395
- * Uses the saved tool preferences from .bi-superpowers.json.
396
- *
397
- * Use this command after:
398
- * - Editing skill files in src/content/skills/
399
- * - Updating the package to a new version
400
- * - Adding new AI tools to your project
326
+ * `super recharge` regenerate the Claude Code plugin without prompts.
401
327
  *
402
- * Supports --dry-run flag to preview changes without writing files.
328
+ * Re-reads the saved tool preferences from .bi-superpowers.json (or falls
329
+ * back to the default toolset) and regenerates everything. Useful after:
330
+ * - editing files in src/content/skills/
331
+ * - bumping the package version
332
+ * - adding new supported tools
403
333
  *
404
- * @param {string[]} args - Command line arguments
405
- * @param {string} [args[0]] - Target directory (defaults to cwd)
334
+ * @param {string[]} args - CLI arguments (first positional = target dir)
406
335
  */
407
336
  async function syncProject(args) {
408
337
  const dryRun = hasDryRunFlag(args);
@@ -412,12 +341,11 @@ async function syncProject(args) {
412
341
  const skills = getSkillFiles();
413
342
 
414
343
  console.log(`
415
- BI Agent Superpowers - Sync
344
+ BI Agent Superpowers Sync
416
345
  ===========================
417
346
  Regenerating configs from ${skills.length} skills...
418
347
  `);
419
348
 
420
- // Show dry-run notice
421
349
  if (dryRun) {
422
350
  if (tui) {
423
351
  tui.dryRunNotice();
@@ -429,12 +357,10 @@ Regenerating configs from ${skills.length} skills...
429
357
  }
430
358
  }
431
359
 
432
- // Read saved config or default to plugin only
433
360
  const config = loadToolConfig(targetDir);
434
361
  const selectedTools = ensurePluginTool(config.tools || [...DEFAULT_TOOLS]);
435
362
 
436
363
  if (dryRun) {
437
- // Preview what would be regenerated
438
364
  console.log('[DRY RUN] Would regenerate the following files:\n');
439
365
  previewGeneration(targetDir, selectedTools, skills);
440
366
  console.log('\nRun without --dry-run to apply changes.');
@@ -446,18 +372,16 @@ Regenerating configs from ${skills.length} skills...
446
372
  }
447
373
 
448
374
  console.log(`
449
- Done! Plugin regenerated for: ${selectedTools.map((t) => AI_TOOLS[t].name).join(', ')}
375
+ Done. Plugin regenerated for: ${selectedTools.map((t) => AI_TOOLS[t].name).join(', ')}
450
376
 
451
- If you modified skills in src/content/skills/,
452
- your Claude Code plugin is now updated.
377
+ If you modified skills in src/content/skills/, your Claude Code plugin is now up to date.
453
378
 
454
- Tip: Run 'super build-desktop' to rebuild the Claude Desktop extension.
379
+ Tip: run 'super build-desktop' to rebuild the Claude Desktop MCPB extension.
455
380
  `);
456
381
  }
457
382
 
458
383
  /**
459
- * Preview what files would be generated (for dry-run mode)
460
- * Delegates to the generators module
384
+ * Delegate to the generators module to preview what would be written.
461
385
  */
462
386
  function previewGeneration(targetDir, tools, skills) {
463
387
  if (generators) {
@@ -466,9 +390,8 @@ function previewGeneration(targetDir, tools, skills) {
466
390
  }
467
391
 
468
392
  /**
469
- * Save tool configuration to project directory
470
- * @param {string} targetDir - Project directory path
471
- * @param {string[]} tools - Array of selected AI tool IDs
393
+ * Ensure the tool list always includes the Claude Code plugin as the
394
+ * primary target. Deduplicates and preserves order.
472
395
  */
473
396
  function ensurePluginTool(tools = []) {
474
397
  const normalized = Array.from(new Set((tools || []).filter(Boolean)));
@@ -479,15 +402,13 @@ function ensurePluginTool(tools = []) {
479
402
  }
480
403
 
481
404
  /**
482
- * Resolve generation options for a target directory.
483
- *
484
- * @param {string} targetDir - Target project directory
485
- * @returns {Object} Options passed into generators
405
+ * Build the options object passed into individual generators.
406
+ * If the target directory has its own local `library/` folder, skills
407
+ * will reference that; otherwise they reference the library bundled
408
+ * inside the installed npm package.
486
409
  */
487
410
  function getGenerationOptions(targetDir) {
488
411
  const usePluginRootLauncher = path.resolve(targetDir) === PACKAGE_DIR;
489
- // If the project has a local library/ folder, use it; otherwise point to
490
- // the library bundled inside the installed npm package.
491
412
  const libraryPrefix = fs.existsSync(path.join(targetDir, 'library'))
492
413
  ? 'library'
493
414
  : path.join(PACKAGE_DIR, 'library');
@@ -500,6 +421,9 @@ function getGenerationOptions(targetDir) {
500
421
  };
501
422
  }
502
423
 
424
+ /**
425
+ * Write .bi-superpowers.json with the current tool selection and metadata.
426
+ */
503
427
  function saveToolConfig(targetDir, tools) {
504
428
  const configPath = path.join(targetDir, CONFIG_FILE);
505
429
  const normalizedTools = ensurePluginTool(tools);
@@ -509,7 +433,6 @@ function saveToolConfig(targetDir, tools) {
509
433
  name: 'bi-superpowers',
510
434
  enabled: true,
511
435
  },
512
- legacyTools: normalizedTools.filter((tool) => tool !== 'claude-plugin'),
513
436
  version: VERSION,
514
437
  lastSync: new Date().toISOString(),
515
438
  };
@@ -517,16 +440,13 @@ function saveToolConfig(targetDir, tools) {
517
440
  }
518
441
 
519
442
  /**
520
- * Preview project-level config.json creation (for dry-run mode)
521
- * This file is used by AI assistants as preferences/context, not by the CLI runtime.
522
- * @param {string} targetDir - Project directory path
443
+ * Log what config.json the kickoff would create (dry-run only).
523
444
  */
524
445
  function previewProjectConfigJson(targetDir) {
525
446
  const projectConfigPath = path.join(targetDir, 'config.json');
526
447
  if (fs.existsSync(projectConfigPath)) {
527
448
  return;
528
449
  }
529
-
530
450
  if (tui) {
531
451
  tui.info(`Would create: ${tui.formatPath(projectConfigPath)}`);
532
452
  } else {
@@ -535,9 +455,8 @@ function previewProjectConfigJson(targetDir) {
535
455
  }
536
456
 
537
457
  /**
538
- * Ensure project-level config.json exists
539
- * Copies the package template config.json into the project directory if missing.
540
- * @param {string} targetDir - Project directory path
458
+ * Copy the package's config.json template into the target directory
459
+ * unless one already exists there.
541
460
  * @returns {{created: boolean, path: string, reason?: string, error?: string}}
542
461
  */
543
462
  function ensureProjectConfigJson(targetDir) {
@@ -566,9 +485,8 @@ function ensureProjectConfigJson(targetDir) {
566
485
  }
567
486
 
568
487
  /**
569
- * Load tool configuration from project directory
570
- * @param {string} targetDir - Project directory path
571
- * @returns {Object} Configuration object or empty object if not found
488
+ * Load the previously saved tool selection from .bi-superpowers.json.
489
+ * Falls back to the default toolset if the file is missing or invalid.
572
490
  */
573
491
  function loadToolConfig(targetDir) {
574
492
  const configPath = path.join(targetDir, CONFIG_FILE);
@@ -576,31 +494,22 @@ function loadToolConfig(targetDir) {
576
494
  try {
577
495
  const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
578
496
  config.tools = ensurePluginTool(config.tools || []);
579
- config.legacyTools = config.tools.filter((tool) => tool !== 'claude-plugin');
580
497
  if (!config.plugin) {
581
- config.plugin = {
582
- name: 'bi-superpowers',
583
- enabled: true,
584
- };
498
+ config.plugin = { name: 'bi-superpowers', enabled: true };
585
499
  }
586
500
  return config;
587
- } catch (e) {
501
+ } catch (_) {
588
502
  return {};
589
503
  }
590
504
  }
591
505
  return {
592
506
  tools: [...DEFAULT_TOOLS],
593
- legacyTools: [],
594
- plugin: {
595
- name: 'bi-superpowers',
596
- enabled: true,
597
- },
507
+ plugin: { name: 'bi-superpowers', enabled: true },
598
508
  };
599
509
  }
600
510
 
601
511
  /**
602
- * Generate config for a specific AI tool
603
- * Delegates to the tool-specific generator from lib/generators module
512
+ * Dispatch to the tool-specific generator.
604
513
  */
605
514
  async function generateForTool(tool, targetDir, skills) {
606
515
  if (generators) {
@@ -615,10 +524,9 @@ function showCompletionMessage(targetDir, tools, skillCount) {
615
524
  ════════════════════════════════════════════════════════════
616
525
 
617
526
  Skills: ${skillCount} skills generated
618
- Library: ${LIBRARY_DIR}
619
527
 
620
528
  ────────────────────────────────────────────────────────────
621
- CLAUDE CODE / 1CODE.DEV
529
+ CLAUDE CODE
622
530
  ────────────────────────────────────────────────────────────
623
531
 
624
532
  Plugin files:
@@ -643,15 +551,15 @@ function showCompletionMessage(targetDir, tools, skillCount) {
643
551
 
644
552
  ────────────────────────────────────────────────────────────
645
553
 
646
- Regenerate after changes: super recharge
647
- Free models (OpenRouter): See docs/openrouter-free-models.md
554
+ Regenerate after edits: super recharge
648
555
 
649
556
  ════════════════════════════════════════════════════════════
650
557
  `);
651
558
  }
652
559
 
653
560
  /**
654
- * Update the package to the latest version using detected package manager
561
+ * `super upgrade` — reinstall the package at the latest version using
562
+ * whichever package manager the user ran npm with.
655
563
  */
656
564
  function updatePackage() {
657
565
  console.log(`Updating ${PACKAGE_NAME}...\n`);
@@ -670,7 +578,7 @@ function updatePackage() {
670
578
 
671
579
  console.log(`Running: ${cmd}\n`);
672
580
  execSync(cmd, { stdio: 'inherit' });
673
- console.log('\n✓ Update complete!');
581
+ console.log('\n✓ Update complete.');
674
582
  } catch (error) {
675
583
  console.error('Update failed:', error.message);
676
584
  console.log(`\nTry manually: npm install -g ${PACKAGE_NAME}@latest`);
@@ -678,59 +586,32 @@ function updatePackage() {
678
586
  }
679
587
  }
680
588
 
589
+ /**
590
+ * `super powers` — list the available skills (and their titles).
591
+ */
681
592
  function listAgents() {
682
593
  const skills = getSkillFiles();
683
594
 
684
595
  console.log(`
685
- BI Agent Superpowers - Skills & Resources
686
- =========================================
596
+ BI Agent Superpowers Skills
597
+ =============================
687
598
  Single Source of Truth: ${skills.length} skills (open source)
688
599
  `);
689
600
 
690
- console.log('Skills (source content for the plugin and optional adapters):');
601
+ console.log('Skills:');
691
602
  for (const skill of skills) {
692
603
  const meta = parseSkillMetadata(skill.content);
693
604
  console.log(` /${skill.name.padEnd(20)} ${meta.title || ''}`);
694
605
  }
695
606
  console.log('');
696
607
 
697
- // List snippets
698
- const snippetsDir = path.join(LIBRARY_DIR, 'snippets');
699
- if (fs.existsSync(snippetsDir)) {
700
- console.log('Snippets:');
701
- fs.readdirSync(snippetsDir).forEach((category) => {
702
- const categoryPath = path.join(snippetsDir, category);
703
- try {
704
- if (fs.statSync(categoryPath).isDirectory()) {
705
- const count = fs.readdirSync(categoryPath).filter((f) => f.endsWith('.md')).length;
706
- console.log(` 📝 ${category} (${count} patterns)`);
707
- }
708
- } catch (e) {
709
- // Skip directories that can't be read
710
- }
711
- });
712
- console.log('');
713
- }
714
-
715
- // List themes
716
- const themesDir = path.join(LIBRARY_DIR, 'themes', 'power-bi');
717
- if (fs.existsSync(themesDir)) {
718
- console.log('Themes:');
719
- fs.readdirSync(themesDir).forEach((file) => {
720
- if (file.endsWith('.json')) {
721
- console.log(` 🎨 ${file.replace('.json', '')}`);
722
- }
723
- });
724
- console.log('');
725
- }
726
-
727
- console.log('Supported AI Tools:');
728
- Object.entries(AI_TOOLS).forEach(([, config]) => {
729
- console.log(` • ${config.name}`);
608
+ console.log('Supported AI tools:');
609
+ Object.entries(AI_TOOLS).forEach(([, cfg]) => {
610
+ console.log(` ${cfg.name}`);
730
611
  });
731
612
  console.log('');
732
613
 
733
- console.log("Run 'bi-superpowers recharge' to regenerate configs after editing skills.");
614
+ console.log("Run 'super recharge' to regenerate configs after editing skills.");
734
615
  }
735
616
 
736
617
  // ============================================
@@ -738,24 +619,19 @@ Single Source of Truth: ${skills.length} skills (open source)
738
619
  // ============================================
739
620
 
740
621
  /**
741
- * Get configuration object for commands
622
+ * Shared config object passed into every command module.
742
623
  */
743
624
  function getCommandConfig() {
744
625
  return {
745
626
  skillsDir: SKILLS_DIR,
746
- libraryDir: LIBRARY_DIR,
747
627
  packageDir: PACKAGE_DIR,
748
628
  version: VERSION,
749
629
  };
750
630
  }
751
631
 
752
632
  /**
753
- * Create a command wrapper with error handling
754
- * Factory pattern to reduce boilerplate in command handlers
755
- *
756
- * @param {Function|null} commandModule - The command module function
757
- * @param {string} commandName - Display name for error messages
758
- * @returns {Function} Wrapped command handler
633
+ * Factory that wraps a command module with a consistent "missing module"
634
+ * error so every non-core command fails the same way during `npm install`.
759
635
  */
760
636
  function createCommandWrapper(commandModule, commandName) {
761
637
  return (args) => {
@@ -767,44 +643,29 @@ function createCommandWrapper(commandModule, commandName) {
767
643
  };
768
644
  }
769
645
 
770
- // Command wrappers using factory pattern
771
- const runSearch = createCommandWrapper(searchCommand, 'Search');
646
+ // Wrapper instances created after createCommandWrapper is defined.
772
647
  const runLint = createCommandWrapper(lintCommand, 'Lint');
773
648
  const runDiff = createCommandWrapper(diffCommand, 'Diff');
774
649
  const runMcpSetup = createCommandWrapper(mcpSetupCommand, 'MCP setup');
775
- const runSetup = createCommandWrapper(setupCommand, 'Setup');
776
- const runAdd = createCommandWrapper(addCommand, 'Add');
777
- const runPull = createCommandWrapper(pullCommand, 'Pull');
778
- const runPush = createCommandWrapper(pushCommand, 'Push');
779
- const runSyncSource = createCommandWrapper(syncSourceCommand, 'Sync-source');
780
- const runSyncProfile = createCommandWrapper(syncProfileCommand, 'Sync-profile');
781
- const runChangelog = createCommandWrapper(changelogCommand, 'Changelog');
782
650
  const runBuildDesktop = createCommandWrapper(buildDesktopCommand, 'Build Desktop');
783
651
  const runInstall = createCommandWrapper(installCommand, 'Install');
784
652
 
785
- // Register commands that depend on createCommandWrapper (avoids TDZ in object literal)
653
+ // Register wrapper-based commands into the command map (phase 2).
786
654
  commands.install = runInstall;
787
- commands.xray = runSearch;
788
655
  commands.checkup = runLint;
789
656
  commands.scan = runDiff;
790
657
  commands.sentinel = runWatch;
791
658
  commands['mcp-setup'] = runMcpSetup;
792
659
  commands.mcp = runMcpSetup;
793
660
  commands['build-desktop'] = runBuildDesktop;
794
- commands.setup = runSetup;
795
- commands.add = runAdd;
796
- commands.pull = runPull;
797
- commands.push = runPush;
798
- commands['sync-source'] = runSyncSource;
799
- commands['sync-profile'] = runSyncProfile;
800
- commands.changelog = runChangelog;
801
- commands.search = runSearch;
802
661
  commands.lint = runLint;
803
662
  commands.diff = runDiff;
804
663
  commands.watch = runWatch;
805
664
 
806
665
  /**
807
- * Run watch command (special case - needs additional context)
666
+ * `super sentinel` — watch skill sources and auto-regenerate the plugin.
667
+ * Needs extra context (a reference to the sync function) so it has its
668
+ * own wrapper instead of using createCommandWrapper.
808
669
  */
809
670
  function runWatch(args) {
810
671
  if (!watchCommand) {
@@ -812,14 +673,13 @@ function runWatch(args) {
812
673
  process.exit(1);
813
674
  }
814
675
 
815
- // Create a reference to sync function for watch to use
816
676
  const cliModule = {
817
677
  syncProjectInternal: (targetDir, tools) => {
818
678
  const skills = getSkillFiles();
819
679
  for (const tool of tools) {
820
- const config = AI_TOOLS[tool];
821
- if (config && config.generate) {
822
- config.generate(targetDir, skills, { packageDir: PACKAGE_DIR });
680
+ const cfg = AI_TOOLS[tool];
681
+ if (cfg && cfg.generate) {
682
+ cfg.generate(targetDir, skills, { packageDir: PACKAGE_DIR });
823
683
  }
824
684
  }
825
685
  },
@@ -829,14 +689,14 @@ function runWatch(args) {
829
689
  }
830
690
 
831
691
  /**
832
- * Check if --dry-run flag is present in args
692
+ * Check if --dry-run (or -n) is present in the argument list.
833
693
  */
834
694
  function hasDryRunFlag(args) {
835
695
  return args.includes('--dry-run') || args.includes('-n');
836
696
  }
837
697
 
838
698
  /**
839
- * Remove --dry-run flag from args
699
+ * Strip the --dry-run / -n flag from the argument list.
840
700
  */
841
701
  function removeDryRunFlag(args) {
842
702
  return args.filter((a) => a !== '--dry-run' && a !== '-n');
@@ -852,7 +712,6 @@ module.exports = {
852
712
  saveToolConfig,
853
713
  AI_TOOLS,
854
714
  SKILLS_DIR,
855
- LIBRARY_DIR,
856
715
  VERSION,
857
716
  };
858
717