@luquimbo/bi-superpowers 3.1.1 → 4.1.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.
- package/.claude-plugin/marketplace.json +5 -3
- package/.claude-plugin/plugin.json +28 -2
- package/.claude-plugin/skill-manifest.json +22 -6
- package/.plugin/plugin.json +1 -1
- package/AGENTS.md +52 -36
- package/CHANGELOG.md +295 -0
- package/README.md +75 -26
- package/bin/build-plugin.js +17 -10
- package/bin/cli.js +278 -322
- package/bin/commands/build-desktop.js +35 -16
- package/bin/commands/diff.js +31 -13
- package/bin/commands/install.js +93 -72
- package/bin/commands/lint.js +40 -26
- package/bin/commands/mcp-setup.js +3 -10
- package/bin/commands/update-check.js +389 -0
- package/bin/lib/agents.js +19 -0
- package/bin/lib/generators/claude-plugin.js +144 -6
- package/bin/lib/generators/shared.js +29 -33
- package/bin/lib/mcp-config.js +191 -16
- package/bin/lib/skills.js +115 -27
- package/bin/postinstall.js +4 -2
- package/bin/utils/mcp-detect.js +2 -2
- package/commands/bi-start.md +218 -0
- package/commands/pbi-connect.md +43 -65
- package/commands/project-kickoff.md +393 -673
- package/commands/report-design.md +403 -0
- package/desktop-extension/manifest.json +5 -12
- package/desktop-extension/server.js +34 -25
- package/package.json +6 -10
- package/skills/bi-start/SKILL.md +220 -0
- package/skills/bi-start/scripts/update-check.js +389 -0
- package/skills/pbi-connect/SKILL.md +45 -67
- package/skills/pbi-connect/scripts/update-check.js +389 -0
- package/skills/project-kickoff/SKILL.md +395 -675
- package/skills/project-kickoff/scripts/update-check.js +389 -0
- package/skills/report-design/SKILL.md +405 -0
- package/skills/report-design/references/cli-commands.md +184 -0
- package/skills/report-design/references/cli-setup.md +101 -0
- package/skills/report-design/references/close-write-open-pattern.md +80 -0
- package/skills/report-design/references/layouts/finance.md +65 -0
- package/skills/report-design/references/layouts/generic.md +46 -0
- package/skills/report-design/references/layouts/hr.md +48 -0
- package/skills/report-design/references/layouts/marketing.md +45 -0
- package/skills/report-design/references/layouts/operations.md +44 -0
- package/skills/report-design/references/layouts/sales.md +50 -0
- package/skills/report-design/references/native-visuals.md +341 -0
- package/skills/report-design/references/pbi-desktop-installation.md +87 -0
- package/skills/report-design/references/pbir-preview-activation.md +40 -0
- package/skills/report-design/references/slicer.md +89 -0
- package/skills/report-design/references/textbox.md +101 -0
- package/skills/report-design/references/themes/BISuperpowers.json +915 -0
- package/skills/report-design/references/troubleshooting.md +135 -0
- package/skills/report-design/references/visual-types.md +78 -0
- package/skills/report-design/scripts/apply-theme.js +243 -0
- package/skills/report-design/scripts/create-visual.js +878 -0
- package/skills/report-design/scripts/ensure-pbi-cli.sh +41 -0
- package/skills/report-design/scripts/update-check.js +389 -0
- package/skills/report-design/scripts/validate-pbir.js +322 -0
- package/src/content/base.md +12 -68
- package/src/content/mcp-requirements.json +0 -25
- package/src/content/routing.md +19 -74
- package/src/content/skills/bi-start.md +191 -0
- package/src/content/skills/pbi-connect.md +22 -65
- package/src/content/skills/project-kickoff.md +372 -673
- package/src/content/skills/report-design/SKILL.md +376 -0
- package/src/content/skills/report-design/references/cli-commands.md +184 -0
- package/src/content/skills/report-design/references/cli-setup.md +101 -0
- package/src/content/skills/report-design/references/close-write-open-pattern.md +80 -0
- package/src/content/skills/report-design/references/layouts/finance.md +65 -0
- package/src/content/skills/report-design/references/layouts/generic.md +46 -0
- package/src/content/skills/report-design/references/layouts/hr.md +48 -0
- package/src/content/skills/report-design/references/layouts/marketing.md +45 -0
- package/src/content/skills/report-design/references/layouts/operations.md +44 -0
- package/src/content/skills/report-design/references/layouts/sales.md +50 -0
- package/src/content/skills/report-design/references/native-visuals.md +341 -0
- package/src/content/skills/report-design/references/pbi-desktop-installation.md +87 -0
- package/src/content/skills/report-design/references/pbir-preview-activation.md +40 -0
- package/src/content/skills/report-design/references/slicer.md +89 -0
- package/src/content/skills/report-design/references/textbox.md +101 -0
- package/src/content/skills/report-design/references/themes/BISuperpowers.json +915 -0
- package/src/content/skills/report-design/references/troubleshooting.md +135 -0
- package/src/content/skills/report-design/references/visual-types.md +78 -0
- package/src/content/skills/report-design/scripts/apply-theme.js +243 -0
- package/src/content/skills/report-design/scripts/create-visual.js +878 -0
- package/src/content/skills/report-design/scripts/ensure-pbi-cli.sh +41 -0
- package/src/content/skills/report-design/scripts/validate-pbir.js +322 -0
- package/bin/commands/add.js +0 -533
- package/bin/commands/add.test.js +0 -77
- package/bin/commands/changelog.js +0 -443
- package/bin/commands/install.test.js +0 -289
- package/bin/commands/lint.test.js +0 -103
- package/bin/commands/pull.js +0 -287
- package/bin/commands/pull.test.js +0 -36
- package/bin/commands/push.js +0 -231
- package/bin/commands/push.test.js +0 -14
- package/bin/commands/search.js +0 -344
- package/bin/commands/search.test.js +0 -115
- package/bin/commands/setup.js +0 -545
- package/bin/commands/setup.test.js +0 -46
- package/bin/commands/sync-profile.js +0 -405
- package/bin/commands/sync-profile.test.js +0 -14
- package/bin/commands/sync-source.js +0 -418
- package/bin/commands/sync-source.test.js +0 -14
- package/bin/lib/generators/claude-plugin.test.js +0 -111
- package/bin/lib/mcp-config.test.js +0 -310
- package/bin/lib/microsoft-mcp.test.js +0 -115
- package/bin/utils/errors.js +0 -159
- package/bin/utils/git.js +0 -298
- package/bin/utils/logger.js +0 -142
- package/bin/utils/mcp-detect.test.js +0 -81
- package/bin/utils/pbix.js +0 -305
- package/bin/utils/pbix.test.js +0 -37
- package/bin/utils/profiles.js +0 -312
- package/bin/utils/projects.js +0 -169
- package/bin/utils/readline.js +0 -206
- package/bin/utils/readline.test.js +0 -47
- package/bin/utils/tui.test.js +0 -127
- package/docs/openrouter-free-models.md +0 -92
- package/library/examples/README.md +0 -151
- package/library/examples/finance-reporting/README.md +0 -351
- package/library/examples/finance-reporting/data-model.md +0 -267
- package/library/examples/finance-reporting/measures.dax +0 -557
- package/library/examples/hr-analytics/README.md +0 -371
- package/library/examples/hr-analytics/data-model.md +0 -315
- package/library/examples/hr-analytics/measures.dax +0 -460
- package/library/examples/marketing-analytics/README.md +0 -37
- package/library/examples/marketing-analytics/data-model.md +0 -62
- package/library/examples/marketing-analytics/measures.dax +0 -110
- package/library/examples/retail-analytics/README.md +0 -439
- package/library/examples/retail-analytics/data-model.md +0 -288
- package/library/examples/retail-analytics/measures.dax +0 -481
- package/library/examples/supply-chain/README.md +0 -37
- package/library/examples/supply-chain/data-model.md +0 -69
- package/library/examples/supply-chain/measures.dax +0 -77
- package/library/examples/udf-library/README.md +0 -228
- package/library/examples/udf-library/functions.dax +0 -571
- package/library/snippets/dax/README.md +0 -292
- package/library/snippets/dax/business-domains.md +0 -576
- package/library/snippets/dax/calculate-patterns.md +0 -276
- package/library/snippets/dax/calculation-groups.md +0 -489
- package/library/snippets/dax/error-handling.md +0 -495
- package/library/snippets/dax/iterators-and-aggregations.md +0 -474
- package/library/snippets/dax/kpis-and-metrics.md +0 -293
- package/library/snippets/dax/rankings-and-topn.md +0 -235
- package/library/snippets/dax/security-patterns.md +0 -413
- package/library/snippets/dax/text-and-formatting.md +0 -316
- package/library/snippets/dax/time-intelligence.md +0 -196
- package/library/snippets/dax/user-defined-functions.md +0 -477
- package/library/snippets/dax/virtual-tables.md +0 -546
- package/library/snippets/excel-formulas/README.md +0 -84
- package/library/snippets/excel-formulas/aggregations.md +0 -330
- package/library/snippets/excel-formulas/dates-and-times.md +0 -361
- package/library/snippets/excel-formulas/dynamic-arrays.md +0 -314
- package/library/snippets/excel-formulas/lookups.md +0 -169
- package/library/snippets/excel-formulas/text-functions.md +0 -363
- package/library/snippets/governance/naming-conventions.md +0 -97
- package/library/snippets/governance/review-checklists.md +0 -107
- package/library/snippets/power-query/README.md +0 -389
- package/library/snippets/power-query/api-integration.md +0 -707
- package/library/snippets/power-query/connections.md +0 -434
- package/library/snippets/power-query/data-cleaning.md +0 -298
- package/library/snippets/power-query/error-handling.md +0 -526
- package/library/snippets/power-query/parameters.md +0 -350
- package/library/snippets/power-query/performance.md +0 -506
- package/library/snippets/power-query/transformations.md +0 -330
- package/library/snippets/report-design/accessibility.md +0 -78
- package/library/snippets/report-design/chart-selection.md +0 -54
- package/library/snippets/report-design/layout-patterns.md +0 -87
- package/library/templates/data-models/README.md +0 -93
- package/library/templates/data-models/finance-model.md +0 -627
- package/library/templates/data-models/retail-star-schema.md +0 -473
- package/library/templates/excel/README.md +0 -83
- package/library/templates/excel/budget-tracker.md +0 -432
- package/library/templates/excel/data-entry-form.md +0 -533
- package/library/templates/power-bi/README.md +0 -72
- package/library/templates/power-bi/finance-report.md +0 -449
- package/library/templates/power-bi/kpi-scorecard.md +0 -461
- package/library/templates/power-bi/sales-dashboard.md +0 -281
- package/library/themes/excel/README.md +0 -436
- package/library/themes/power-bi/README.md +0 -271
- package/library/themes/power-bi/accessible.json +0 -307
- package/library/themes/power-bi/bi-superpowers-default.json +0 -858
- package/library/themes/power-bi/corporate-blue.json +0 -291
- package/library/themes/power-bi/dark-mode.json +0 -291
- package/library/themes/power-bi/minimal.json +0 -292
- 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
|
|
4
|
+
* BI Agent Superpowers — Command Line Interface
|
|
5
5
|
* ==============================================
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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
|
-
* -
|
|
13
|
-
*
|
|
14
|
-
* -
|
|
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
|
-
*
|
|
17
|
-
*
|
|
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,124 @@ const path = require('path');
|
|
|
27
28
|
const { execSync } = require('child_process');
|
|
28
29
|
const { loadSkills } = require('./lib/skills');
|
|
29
30
|
|
|
30
|
-
//
|
|
31
|
+
// Background update check. update-notifier spawns a detached child process
|
|
32
|
+
// that fetches the latest version from npm and caches it; the banner that
|
|
33
|
+
// `notify()` schedules is printed at process exit, so this is zero-latency
|
|
34
|
+
// on the command path. Errors are swallowed silently — the CLI must not
|
|
35
|
+
// break because of a failed update check.
|
|
36
|
+
let _updateNotifierNotify = null;
|
|
37
|
+
try {
|
|
38
|
+
const updateNotifier = require('update-notifier');
|
|
39
|
+
const pkg = require('../package.json');
|
|
40
|
+
const notifier = updateNotifier({
|
|
41
|
+
pkg,
|
|
42
|
+
updateCheckInterval: 1000 * 60 * 60 * 24, // 24h
|
|
43
|
+
shouldNotifyInNpmScript: false,
|
|
44
|
+
});
|
|
45
|
+
_updateNotifierNotify = () =>
|
|
46
|
+
notifier.notify({
|
|
47
|
+
defer: true,
|
|
48
|
+
isGlobal: true,
|
|
49
|
+
message:
|
|
50
|
+
'Update available {currentVersion} → {latestVersion}\n' +
|
|
51
|
+
'Run {updateCommand} to update,\n' +
|
|
52
|
+
'then `super install --yes` to propagate the new skills.',
|
|
53
|
+
});
|
|
54
|
+
} catch (_) {
|
|
55
|
+
// update-notifier not available during npm install phase, or network
|
|
56
|
+
// probe failed — skip silently.
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Optional lib import — may not be available during npm install phase.
|
|
31
60
|
let generators;
|
|
32
61
|
try {
|
|
33
62
|
generators = require('./lib/generators');
|
|
34
|
-
} catch (
|
|
35
|
-
//
|
|
63
|
+
} catch (_) {
|
|
64
|
+
// Silent fallback; commands will report a useful error when invoked.
|
|
36
65
|
}
|
|
37
66
|
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
let
|
|
42
|
-
let
|
|
67
|
+
// Optional command imports — each module may fail to load during npm
|
|
68
|
+
// install before dependencies are wired up. The CLI still renders `help`
|
|
69
|
+
// and `version` because those are hoisted, module-free functions.
|
|
70
|
+
let lintCommand;
|
|
71
|
+
let diffCommand;
|
|
72
|
+
let watchCommand;
|
|
73
|
+
let mcpSetupCommand;
|
|
74
|
+
let buildDesktopCommand;
|
|
75
|
+
let installCommand;
|
|
76
|
+
let tui;
|
|
43
77
|
try {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
watchCommand = require('./commands/watch'); // Auto-regenerate on file changes
|
|
78
|
+
lintCommand = require('./commands/lint'); // checkup: skill file validation
|
|
79
|
+
diffCommand = require('./commands/diff'); // scan: diff source vs generated
|
|
80
|
+
watchCommand = require('./commands/watch'); // sentinel: watch + auto regen
|
|
48
81
|
mcpSetupCommand = require('./commands/mcp-setup'); // MCP server configuration
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
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
|
|
82
|
+
buildDesktopCommand = require('./commands/build-desktop'); // .mcpb for Claude Desktop
|
|
83
|
+
installCommand = require('./commands/install'); // multi-agent skill + MCP installer
|
|
84
|
+
tui = require('./utils/tui'); // colors, tables, boxes for CLI output
|
|
85
|
+
} catch (_) {
|
|
86
|
+
// Expected during `npm install` — modules become available after deps are linked.
|
|
64
87
|
}
|
|
65
88
|
|
|
66
89
|
// ============================================
|
|
67
90
|
// CONFIGURATION CONSTANTS
|
|
68
91
|
// ============================================
|
|
69
92
|
|
|
70
|
-
/** Package version from package.json */
|
|
93
|
+
/** Package version (read from package.json at runtime) */
|
|
71
94
|
const VERSION = require('../package.json').version;
|
|
72
95
|
|
|
73
|
-
/**
|
|
74
|
-
|
|
75
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Skill and command counts used by the help text and dry-run previews.
|
|
98
|
+
* Pulled dynamically from the generator so we never hardcode outdated totals.
|
|
99
|
+
*/
|
|
100
|
+
let COMMAND_COUNT = 0;
|
|
101
|
+
let TOTAL_SKILL_COUNT = 0;
|
|
76
102
|
try {
|
|
77
103
|
const { COMMAND_SKILLS, REFERENCE_SKILLS } = require('./lib/generators/claude-plugin');
|
|
78
104
|
COMMAND_COUNT = COMMAND_SKILLS.size;
|
|
79
105
|
TOTAL_SKILL_COUNT = COMMAND_SKILLS.size + REFERENCE_SKILLS.size;
|
|
80
106
|
} catch (_) {
|
|
81
|
-
// Fallback
|
|
107
|
+
// Fallback during npm install phase — values stay at 0 until the module loads.
|
|
82
108
|
}
|
|
83
109
|
|
|
84
|
-
/**
|
|
110
|
+
/** Absolute path to the installed package directory (one level above bin/) */
|
|
85
111
|
const PACKAGE_DIR = path.dirname(__dirname);
|
|
86
112
|
|
|
87
|
-
/** Directory containing
|
|
113
|
+
/** Directory containing the authoring source for each skill */
|
|
88
114
|
const SKILLS_DIR = path.join(PACKAGE_DIR, 'src', 'content', 'skills');
|
|
89
115
|
|
|
90
|
-
/**
|
|
91
|
-
const LIBRARY_DIR = path.join(PACKAGE_DIR, 'library');
|
|
92
|
-
|
|
93
|
-
/** Project-local config file name (stores tool selections) */
|
|
116
|
+
/** Project-local config file name used by kickoff/recharge */
|
|
94
117
|
const CONFIG_FILE = '.bi-superpowers.json';
|
|
95
118
|
|
|
96
|
-
/** npm package name for
|
|
119
|
+
/** npm package name for the upgrade command */
|
|
97
120
|
const PACKAGE_NAME = '@luquimbo/bi-superpowers';
|
|
121
|
+
|
|
122
|
+
/** Default tool set generated by kickoff (currently only the Claude Code plugin) */
|
|
98
123
|
const DEFAULT_TOOLS = ['claude-plugin'];
|
|
99
124
|
|
|
100
|
-
/**
|
|
101
|
-
* AI Tools Configuration - uses generators from lib/generators module
|
|
102
|
-
* Falls back to empty object if module not loaded
|
|
103
|
-
*/
|
|
125
|
+
/** Generator registry (populated from lib/generators if available) */
|
|
104
126
|
const AI_TOOLS = generators ? generators.AI_TOOLS : {};
|
|
105
127
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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.
|
|
128
|
+
// ============================================
|
|
129
|
+
// COMMAND ROUTING
|
|
130
|
+
// ============================================
|
|
131
|
+
// Commands are registered in two phases to avoid temporal-dead-zone errors.
|
|
132
|
+
// Phase 1: hoisted function declarations (help, version, about, kickoff...)
|
|
133
|
+
// go directly into the object literal below.
|
|
134
|
+
// Phase 2: wrapper-based commands that depend on createCommandWrapper
|
|
135
|
+
// (defined further below) are attached imperatively.
|
|
125
136
|
const commands = {
|
|
126
|
-
// Core commands
|
|
137
|
+
// Core commands — hoisted functions, safe to reference here.
|
|
127
138
|
help: showHelp,
|
|
128
139
|
version: showVersion,
|
|
129
140
|
about: showInfo,
|
|
130
141
|
|
|
131
|
-
//
|
|
142
|
+
// Primary flow — also hoisted functions.
|
|
132
143
|
kickoff: initProject,
|
|
133
144
|
recharge: syncProject,
|
|
134
145
|
upgrade: updatePackage,
|
|
135
146
|
powers: listAgents,
|
|
136
147
|
|
|
137
|
-
// Legacy aliases
|
|
148
|
+
// Legacy aliases kept for backwards compatibility.
|
|
138
149
|
init: initProject,
|
|
139
150
|
sync: syncProject,
|
|
140
151
|
update: updatePackage,
|
|
@@ -143,12 +154,20 @@ const commands = {
|
|
|
143
154
|
};
|
|
144
155
|
|
|
145
156
|
/**
|
|
146
|
-
* Main entry point
|
|
157
|
+
* Main entry point — parses CLI arguments and routes to the handler.
|
|
147
158
|
*/
|
|
148
159
|
function main() {
|
|
149
160
|
const args = process.argv.slice(2);
|
|
150
161
|
const command = args[0] || 'help';
|
|
151
162
|
|
|
163
|
+
// Schedule the update-notifier banner to print at process exit. Only fire
|
|
164
|
+
// for "normal" commands — skipping machine-readable and ultra-hot paths so
|
|
165
|
+
// tools that parse super output don't get surprised by the banner.
|
|
166
|
+
const SKIP_NOTIFY_COMMANDS = new Set(['version', 'help', 'about', 'info']);
|
|
167
|
+
if (_updateNotifierNotify && !SKIP_NOTIFY_COMMANDS.has(command)) {
|
|
168
|
+
_updateNotifierNotify();
|
|
169
|
+
}
|
|
170
|
+
|
|
152
171
|
if (commands[command]) {
|
|
153
172
|
commands[command](args.slice(1));
|
|
154
173
|
} else {
|
|
@@ -163,67 +182,47 @@ function showHelp() {
|
|
|
163
182
|
BI Agent Superpowers v${VERSION}
|
|
164
183
|
================================
|
|
165
184
|
|
|
166
|
-
|
|
185
|
+
Open-source toolkit for Power BI Desktop development across 5 AI coding agents:
|
|
186
|
+
Claude Code · GitHub Copilot · Codex · Gemini CLI · Kilo Code.
|
|
167
187
|
|
|
168
188
|
Quick Start:
|
|
169
|
-
super
|
|
170
|
-
|
|
189
|
+
super install # Install skills + MCPs for all your AI agents
|
|
190
|
+
super kickoff # Generate the Claude Code plugin in a project
|
|
171
191
|
|
|
172
192
|
Usage:
|
|
173
193
|
super <command> [options]
|
|
174
194
|
|
|
175
|
-
Primary commands
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
195
|
+
Primary commands:
|
|
196
|
+
install Install the 4 skills + 2 MCPs across your AI agents
|
|
197
|
+
kickoff [path] Generate the full Claude Code plugin in a project
|
|
198
|
+
recharge [path] Regenerate the plugin after editing source skills
|
|
199
|
+
build-desktop Build the .mcpb extension for Claude Desktop
|
|
200
|
+
mcp-setup Configure the official Microsoft MCP servers
|
|
201
|
+
powers List available skills and MCPs
|
|
202
|
+
upgrade Update to the latest version on npm
|
|
203
|
+
about Show installation info
|
|
204
|
+
help Show this help
|
|
184
205
|
|
|
185
206
|
Developer tools:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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)
|
|
207
|
+
checkup [file] Lint/validate skill source files
|
|
208
|
+
scan Diff between source skills and generated plugin
|
|
209
|
+
sentinel Watch skill sources and auto-regenerate
|
|
201
210
|
|
|
202
211
|
Options:
|
|
203
|
-
--dry-run Preview
|
|
212
|
+
--dry-run Preview changes without writing files (kickoff, recharge)
|
|
204
213
|
|
|
205
214
|
Examples:
|
|
206
|
-
super
|
|
207
|
-
super
|
|
208
|
-
super
|
|
209
|
-
super
|
|
210
|
-
super
|
|
211
|
-
super
|
|
212
|
-
super
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
|
215
|
+
super install # Interactive installer for all agents
|
|
216
|
+
super install --all --yes # Non-interactive install for every agent
|
|
217
|
+
super install -a claude-code # Install only for Claude Code
|
|
218
|
+
super kickoff # Initialize plugin in current directory
|
|
219
|
+
super kickoff ./my-project # Initialize in a specific directory
|
|
220
|
+
super kickoff --dry-run # Preview what would be created
|
|
221
|
+
super recharge # Regenerate plugin after editing skills
|
|
222
|
+
super build-desktop # Build .mcpb for Claude Desktop
|
|
223
|
+
super mcp-setup # Configure the local Power BI Modeling MCP
|
|
224
|
+
|
|
225
|
+
Open source — MIT licensed.
|
|
227
226
|
Documentation: https://github.com/luquimbo/bi-superpowers
|
|
228
227
|
`);
|
|
229
228
|
}
|
|
@@ -235,11 +234,11 @@ function showVersion() {
|
|
|
235
234
|
function showInfo() {
|
|
236
235
|
const skillCount = getSkillFiles().length;
|
|
237
236
|
const aiToolsList = Object.entries(AI_TOOLS)
|
|
238
|
-
.map(([
|
|
237
|
+
.map(([, v]) => ` - ${v.name}`)
|
|
239
238
|
.join('\n');
|
|
240
239
|
|
|
241
240
|
console.log(`
|
|
242
|
-
BI Agent Superpowers
|
|
241
|
+
BI Agent Superpowers — Installation Info
|
|
243
242
|
========================================
|
|
244
243
|
|
|
245
244
|
Version: ${VERSION}
|
|
@@ -248,62 +247,41 @@ Package dir: ${PACKAGE_DIR}
|
|
|
248
247
|
Skills: ${skillCount} available
|
|
249
248
|
License: MIT (open source)
|
|
250
249
|
|
|
251
|
-
|
|
252
|
-
|
|
250
|
+
Supported AI agents:
|
|
251
|
+
- Claude Code (native plugin + MCP)
|
|
252
|
+
- GitHub Copilot (agent skills + MCP)
|
|
253
|
+
- Codex (OpenAI) (agent skills + MCP)
|
|
254
|
+
- Gemini CLI (agent skills + MCP)
|
|
255
|
+
- Kilo Code (agent skills + MCP)
|
|
253
256
|
|
|
254
|
-
|
|
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:
|
|
257
|
+
Plugin generators:
|
|
263
258
|
${aiToolsList}
|
|
264
259
|
|
|
265
260
|
GitHub: https://github.com/luquimbo/bi-superpowers
|
|
266
261
|
`);
|
|
267
262
|
}
|
|
268
263
|
|
|
269
|
-
// ============================================
|
|
270
|
-
// LICENSE MANAGEMENT
|
|
271
|
-
// ============================================
|
|
272
264
|
// ============================================
|
|
273
265
|
// SKILL FILE MANAGEMENT
|
|
274
266
|
// ============================================
|
|
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
267
|
|
|
279
268
|
/**
|
|
280
|
-
*
|
|
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
|
|
269
|
+
* Load all skill source files from the package.
|
|
270
|
+
* @returns {Array<{name: string, path: string, content: string}>}
|
|
290
271
|
*/
|
|
291
272
|
function getSkillFiles() {
|
|
292
|
-
return loadSkills({
|
|
293
|
-
packageDir: PACKAGE_DIR,
|
|
294
|
-
preferLocal: true,
|
|
295
|
-
});
|
|
273
|
+
return loadSkills({ packageDir: PACKAGE_DIR });
|
|
296
274
|
}
|
|
297
275
|
|
|
298
276
|
/**
|
|
299
|
-
* Extract
|
|
300
|
-
* Delegates to generators module
|
|
277
|
+
* Extract lightweight metadata (title, triggers, identity) from a skill's
|
|
278
|
+
* markdown content. Delegates to the generators module when available.
|
|
301
279
|
*/
|
|
302
280
|
function parseSkillMetadata(content) {
|
|
303
281
|
if (generators && generators.parseSkillMetadata) {
|
|
304
282
|
return generators.parseSkillMetadata(content);
|
|
305
283
|
}
|
|
306
|
-
//
|
|
284
|
+
// Minimal fallback when the module isn't loaded yet.
|
|
307
285
|
const metadata = { title: '', triggers: [], identity: '' };
|
|
308
286
|
const titleMatch = content.match(/^#\s+(.+)/m);
|
|
309
287
|
if (titleMatch) metadata.title = titleMatch[1];
|
|
@@ -311,23 +289,20 @@ function parseSkillMetadata(content) {
|
|
|
311
289
|
}
|
|
312
290
|
|
|
313
291
|
// ============================================
|
|
314
|
-
// PROJECT INITIALIZATION
|
|
292
|
+
// PROJECT INITIALIZATION (kickoff / recharge)
|
|
315
293
|
// ============================================
|
|
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
294
|
|
|
319
295
|
/**
|
|
320
|
-
*
|
|
296
|
+
* `super kickoff` — generate the Claude Code plugin in the target directory.
|
|
321
297
|
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
298
|
+
* What it does:
|
|
299
|
+
* 1. Generates .claude-plugin/, .mcp.json, commands/, skills/ in the target.
|
|
300
|
+
* 2. Writes .bi-superpowers.json tracking tool selections.
|
|
301
|
+
* 3. Copies a default config.json template if none exists yet.
|
|
326
302
|
*
|
|
327
|
-
* Supports --dry-run
|
|
303
|
+
* Supports --dry-run to preview without writing files.
|
|
328
304
|
*
|
|
329
|
-
* @param {string[]} args -
|
|
330
|
-
* @param {string} [args[0]] - Target directory (defaults to cwd)
|
|
305
|
+
* @param {string[]} args - CLI arguments (first positional = target dir)
|
|
331
306
|
*/
|
|
332
307
|
async function initProject(args) {
|
|
333
308
|
const dryRun = hasDryRunFlag(args);
|
|
@@ -345,7 +320,6 @@ Initializing in: ${targetDir}
|
|
|
345
320
|
Skills available: ${skills.length}
|
|
346
321
|
`);
|
|
347
322
|
|
|
348
|
-
// Show dry-run notice
|
|
349
323
|
if (dryRun) {
|
|
350
324
|
if (tui) {
|
|
351
325
|
tui.dryRunNotice();
|
|
@@ -373,13 +347,9 @@ Skills available: ${skills.length}
|
|
|
373
347
|
return;
|
|
374
348
|
}
|
|
375
349
|
|
|
376
|
-
// Save selected tools to config
|
|
377
350
|
saveToolConfig(targetDir, selectedTools);
|
|
378
|
-
|
|
379
|
-
// Ensure project-level config.json exists (used as AI preferences/context)
|
|
380
351
|
ensureProjectConfigJson(targetDir);
|
|
381
352
|
|
|
382
|
-
// Generate configs for selected tools
|
|
383
353
|
console.log('');
|
|
384
354
|
for (const tool of selectedTools) {
|
|
385
355
|
await generateForTool(tool, targetDir, skills);
|
|
@@ -389,20 +359,15 @@ Skills available: ${skills.length}
|
|
|
389
359
|
}
|
|
390
360
|
|
|
391
361
|
/**
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
* Regenerates the Claude Code plugin and any configured legacy adapters.
|
|
395
|
-
* Uses the saved tool preferences from .bi-superpowers.json.
|
|
362
|
+
* `super recharge` — regenerate the Claude Code plugin without prompts.
|
|
396
363
|
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
364
|
+
* Re-reads the saved tool preferences from .bi-superpowers.json (or falls
|
|
365
|
+
* back to the default toolset) and regenerates everything. Useful after:
|
|
366
|
+
* - editing files in src/content/skills/
|
|
367
|
+
* - bumping the package version
|
|
368
|
+
* - adding new supported tools
|
|
401
369
|
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
* @param {string[]} args - Command line arguments
|
|
405
|
-
* @param {string} [args[0]] - Target directory (defaults to cwd)
|
|
370
|
+
* @param {string[]} args - CLI arguments (first positional = target dir)
|
|
406
371
|
*/
|
|
407
372
|
async function syncProject(args) {
|
|
408
373
|
const dryRun = hasDryRunFlag(args);
|
|
@@ -412,12 +377,11 @@ async function syncProject(args) {
|
|
|
412
377
|
const skills = getSkillFiles();
|
|
413
378
|
|
|
414
379
|
console.log(`
|
|
415
|
-
BI Agent Superpowers
|
|
380
|
+
BI Agent Superpowers — Sync
|
|
416
381
|
===========================
|
|
417
382
|
Regenerating configs from ${skills.length} skills...
|
|
418
383
|
`);
|
|
419
384
|
|
|
420
|
-
// Show dry-run notice
|
|
421
385
|
if (dryRun) {
|
|
422
386
|
if (tui) {
|
|
423
387
|
tui.dryRunNotice();
|
|
@@ -429,12 +393,10 @@ Regenerating configs from ${skills.length} skills...
|
|
|
429
393
|
}
|
|
430
394
|
}
|
|
431
395
|
|
|
432
|
-
// Read saved config or default to plugin only
|
|
433
396
|
const config = loadToolConfig(targetDir);
|
|
434
397
|
const selectedTools = ensurePluginTool(config.tools || [...DEFAULT_TOOLS]);
|
|
435
398
|
|
|
436
399
|
if (dryRun) {
|
|
437
|
-
// Preview what would be regenerated
|
|
438
400
|
console.log('[DRY RUN] Would regenerate the following files:\n');
|
|
439
401
|
previewGeneration(targetDir, selectedTools, skills);
|
|
440
402
|
console.log('\nRun without --dry-run to apply changes.');
|
|
@@ -446,18 +408,16 @@ Regenerating configs from ${skills.length} skills...
|
|
|
446
408
|
}
|
|
447
409
|
|
|
448
410
|
console.log(`
|
|
449
|
-
Done
|
|
411
|
+
Done. Plugin regenerated for: ${selectedTools.map((t) => AI_TOOLS[t].name).join(', ')}
|
|
450
412
|
|
|
451
|
-
If you modified skills in src/content/skills/,
|
|
452
|
-
your Claude Code plugin is now updated.
|
|
413
|
+
If you modified skills in src/content/skills/, your Claude Code plugin is now up to date.
|
|
453
414
|
|
|
454
|
-
Tip:
|
|
415
|
+
Tip: run 'super build-desktop' to rebuild the Claude Desktop MCPB extension.
|
|
455
416
|
`);
|
|
456
417
|
}
|
|
457
418
|
|
|
458
419
|
/**
|
|
459
|
-
*
|
|
460
|
-
* Delegates to the generators module
|
|
420
|
+
* Delegate to the generators module to preview what would be written.
|
|
461
421
|
*/
|
|
462
422
|
function previewGeneration(targetDir, tools, skills) {
|
|
463
423
|
if (generators) {
|
|
@@ -466,9 +426,8 @@ function previewGeneration(targetDir, tools, skills) {
|
|
|
466
426
|
}
|
|
467
427
|
|
|
468
428
|
/**
|
|
469
|
-
*
|
|
470
|
-
*
|
|
471
|
-
* @param {string[]} tools - Array of selected AI tool IDs
|
|
429
|
+
* Ensure the tool list always includes the Claude Code plugin as the
|
|
430
|
+
* primary target. Deduplicates and preserves order.
|
|
472
431
|
*/
|
|
473
432
|
function ensurePluginTool(tools = []) {
|
|
474
433
|
const normalized = Array.from(new Set((tools || []).filter(Boolean)));
|
|
@@ -479,15 +438,13 @@ function ensurePluginTool(tools = []) {
|
|
|
479
438
|
}
|
|
480
439
|
|
|
481
440
|
/**
|
|
482
|
-
*
|
|
483
|
-
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
441
|
+
* Build the options object passed into individual generators.
|
|
442
|
+
* If the target directory has its own local `library/` folder, skills
|
|
443
|
+
* will reference that; otherwise they reference the library bundled
|
|
444
|
+
* inside the installed npm package.
|
|
486
445
|
*/
|
|
487
446
|
function getGenerationOptions(targetDir) {
|
|
488
447
|
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
448
|
const libraryPrefix = fs.existsSync(path.join(targetDir, 'library'))
|
|
492
449
|
? 'library'
|
|
493
450
|
: path.join(PACKAGE_DIR, 'library');
|
|
@@ -500,6 +457,9 @@ function getGenerationOptions(targetDir) {
|
|
|
500
457
|
};
|
|
501
458
|
}
|
|
502
459
|
|
|
460
|
+
/**
|
|
461
|
+
* Write .bi-superpowers.json with the current tool selection and metadata.
|
|
462
|
+
*/
|
|
503
463
|
function saveToolConfig(targetDir, tools) {
|
|
504
464
|
const configPath = path.join(targetDir, CONFIG_FILE);
|
|
505
465
|
const normalizedTools = ensurePluginTool(tools);
|
|
@@ -509,7 +469,6 @@ function saveToolConfig(targetDir, tools) {
|
|
|
509
469
|
name: 'bi-superpowers',
|
|
510
470
|
enabled: true,
|
|
511
471
|
},
|
|
512
|
-
legacyTools: normalizedTools.filter((tool) => tool !== 'claude-plugin'),
|
|
513
472
|
version: VERSION,
|
|
514
473
|
lastSync: new Date().toISOString(),
|
|
515
474
|
};
|
|
@@ -517,16 +476,13 @@ function saveToolConfig(targetDir, tools) {
|
|
|
517
476
|
}
|
|
518
477
|
|
|
519
478
|
/**
|
|
520
|
-
*
|
|
521
|
-
* This file is used by AI assistants as preferences/context, not by the CLI runtime.
|
|
522
|
-
* @param {string} targetDir - Project directory path
|
|
479
|
+
* Log what config.json the kickoff would create (dry-run only).
|
|
523
480
|
*/
|
|
524
481
|
function previewProjectConfigJson(targetDir) {
|
|
525
482
|
const projectConfigPath = path.join(targetDir, 'config.json');
|
|
526
483
|
if (fs.existsSync(projectConfigPath)) {
|
|
527
484
|
return;
|
|
528
485
|
}
|
|
529
|
-
|
|
530
486
|
if (tui) {
|
|
531
487
|
tui.info(`Would create: ${tui.formatPath(projectConfigPath)}`);
|
|
532
488
|
} else {
|
|
@@ -535,9 +491,8 @@ function previewProjectConfigJson(targetDir) {
|
|
|
535
491
|
}
|
|
536
492
|
|
|
537
493
|
/**
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
* @param {string} targetDir - Project directory path
|
|
494
|
+
* Copy the package's config.json template into the target directory
|
|
495
|
+
* unless one already exists there.
|
|
541
496
|
* @returns {{created: boolean, path: string, reason?: string, error?: string}}
|
|
542
497
|
*/
|
|
543
498
|
function ensureProjectConfigJson(targetDir) {
|
|
@@ -566,9 +521,8 @@ function ensureProjectConfigJson(targetDir) {
|
|
|
566
521
|
}
|
|
567
522
|
|
|
568
523
|
/**
|
|
569
|
-
* Load tool
|
|
570
|
-
*
|
|
571
|
-
* @returns {Object} Configuration object or empty object if not found
|
|
524
|
+
* Load the previously saved tool selection from .bi-superpowers.json.
|
|
525
|
+
* Falls back to the default toolset if the file is missing or invalid.
|
|
572
526
|
*/
|
|
573
527
|
function loadToolConfig(targetDir) {
|
|
574
528
|
const configPath = path.join(targetDir, CONFIG_FILE);
|
|
@@ -576,31 +530,22 @@ function loadToolConfig(targetDir) {
|
|
|
576
530
|
try {
|
|
577
531
|
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
578
532
|
config.tools = ensurePluginTool(config.tools || []);
|
|
579
|
-
config.legacyTools = config.tools.filter((tool) => tool !== 'claude-plugin');
|
|
580
533
|
if (!config.plugin) {
|
|
581
|
-
config.plugin = {
|
|
582
|
-
name: 'bi-superpowers',
|
|
583
|
-
enabled: true,
|
|
584
|
-
};
|
|
534
|
+
config.plugin = { name: 'bi-superpowers', enabled: true };
|
|
585
535
|
}
|
|
586
536
|
return config;
|
|
587
|
-
} catch (
|
|
537
|
+
} catch (_) {
|
|
588
538
|
return {};
|
|
589
539
|
}
|
|
590
540
|
}
|
|
591
541
|
return {
|
|
592
542
|
tools: [...DEFAULT_TOOLS],
|
|
593
|
-
|
|
594
|
-
plugin: {
|
|
595
|
-
name: 'bi-superpowers',
|
|
596
|
-
enabled: true,
|
|
597
|
-
},
|
|
543
|
+
plugin: { name: 'bi-superpowers', enabled: true },
|
|
598
544
|
};
|
|
599
545
|
}
|
|
600
546
|
|
|
601
547
|
/**
|
|
602
|
-
*
|
|
603
|
-
* Delegates to the tool-specific generator from lib/generators module
|
|
548
|
+
* Dispatch to the tool-specific generator.
|
|
604
549
|
*/
|
|
605
550
|
async function generateForTool(tool, targetDir, skills) {
|
|
606
551
|
if (generators) {
|
|
@@ -615,10 +560,9 @@ function showCompletionMessage(targetDir, tools, skillCount) {
|
|
|
615
560
|
════════════════════════════════════════════════════════════
|
|
616
561
|
|
|
617
562
|
Skills: ${skillCount} skills generated
|
|
618
|
-
Library: ${LIBRARY_DIR}
|
|
619
563
|
|
|
620
564
|
────────────────────────────────────────────────────────────
|
|
621
|
-
CLAUDE CODE
|
|
565
|
+
CLAUDE CODE
|
|
622
566
|
────────────────────────────────────────────────────────────
|
|
623
567
|
|
|
624
568
|
Plugin files:
|
|
@@ -643,34 +587,90 @@ function showCompletionMessage(targetDir, tools, skillCount) {
|
|
|
643
587
|
|
|
644
588
|
────────────────────────────────────────────────────────────
|
|
645
589
|
|
|
646
|
-
Regenerate after
|
|
647
|
-
Free models (OpenRouter): See docs/openrouter-free-models.md
|
|
590
|
+
Regenerate after edits: super recharge
|
|
648
591
|
|
|
649
592
|
════════════════════════════════════════════════════════════
|
|
650
593
|
`);
|
|
651
594
|
}
|
|
652
595
|
|
|
653
596
|
/**
|
|
654
|
-
*
|
|
597
|
+
* Detect the package manager the user ran from the npm_config_user_agent.
|
|
598
|
+
* Returns the pm name ('npm', 'pnpm', 'yarn', 'bun') and the install command
|
|
599
|
+
* string appropriate for a global install to @latest.
|
|
600
|
+
*
|
|
601
|
+
* Exported (via module.exports) so tests can exercise the detection without
|
|
602
|
+
* spawning a real install.
|
|
655
603
|
*/
|
|
656
|
-
function
|
|
657
|
-
|
|
604
|
+
function getUpgradeCommand(userAgent) {
|
|
605
|
+
const agent = userAgent || '';
|
|
606
|
+
let pm = 'npm';
|
|
607
|
+
if (agent.includes('pnpm')) pm = 'pnpm';
|
|
608
|
+
else if (agent.includes('yarn')) pm = 'yarn';
|
|
609
|
+
else if (agent.includes('bun')) pm = 'bun';
|
|
610
|
+
|
|
611
|
+
const cmd =
|
|
612
|
+
pm === 'yarn'
|
|
613
|
+
? `yarn global add ${PACKAGE_NAME}@latest`
|
|
614
|
+
: `${pm} install -g ${PACKAGE_NAME}@latest`;
|
|
615
|
+
|
|
616
|
+
return { pm, cmd };
|
|
617
|
+
}
|
|
658
618
|
|
|
619
|
+
/**
|
|
620
|
+
* `super upgrade` — reinstall the package at the latest version.
|
|
621
|
+
*
|
|
622
|
+
* After the reinstall, prints a "next steps" block with both update paths
|
|
623
|
+
* (Claude Code `/plugin update` vs npm-based `super install --yes`) so
|
|
624
|
+
* users know how to propagate the new skills into their agents. We
|
|
625
|
+
* intentionally don't auto-chain into `super install`:
|
|
626
|
+
* - Claude Code users who installed via the plugin marketplace refresh
|
|
627
|
+
* from inside Claude Code (`/plugin update bi-superpowers`), they don't
|
|
628
|
+
* need `super install`.
|
|
629
|
+
* - npm users want to be able to opt out of re-propagation (e.g. testing
|
|
630
|
+
* a version before rolling it across all agents).
|
|
631
|
+
*/
|
|
632
|
+
/**
|
|
633
|
+
* Wipe ~/.bi-superpowers/update-state.json after a successful upgrade so
|
|
634
|
+
* the new version starts with a clean cache (no stale snooze TTL, no
|
|
635
|
+
* cached "latest" from the previous version). Best-effort: any failure
|
|
636
|
+
* is swallowed — the reset is a convenience, not a correctness gate.
|
|
637
|
+
*
|
|
638
|
+
* Separate function + exported so tests can exercise it without spawning
|
|
639
|
+
* a real `super upgrade`.
|
|
640
|
+
*/
|
|
641
|
+
function resetUpdateCheckStateAfterUpgrade(homeDir) {
|
|
659
642
|
try {
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
643
|
+
const { resetState } = require('./commands/update-check');
|
|
644
|
+
resetState(path.join(homeDir, '.bi-superpowers'));
|
|
645
|
+
return true;
|
|
646
|
+
} catch (_) {
|
|
647
|
+
return false;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
665
650
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
? `yarn global add ${PACKAGE_NAME}@latest`
|
|
669
|
-
: `${pm} install -g ${PACKAGE_NAME}@latest`;
|
|
651
|
+
function updatePackage() {
|
|
652
|
+
console.log(`Updating ${PACKAGE_NAME}...\n`);
|
|
670
653
|
|
|
654
|
+
try {
|
|
655
|
+
const { cmd } = getUpgradeCommand(process.env.npm_config_user_agent);
|
|
671
656
|
console.log(`Running: ${cmd}\n`);
|
|
672
657
|
execSync(cmd, { stdio: 'inherit' });
|
|
673
|
-
console.log('\n✓
|
|
658
|
+
console.log('\n✓ CLI upgraded.');
|
|
659
|
+
|
|
660
|
+
// Clear the update-check cache + snooze state so the newly-installed
|
|
661
|
+
// version gets a fresh read on next skill invocation.
|
|
662
|
+
resetUpdateCheckStateAfterUpgrade(require('os').homedir());
|
|
663
|
+
|
|
664
|
+
console.log('\nNext step — refresh the skills + MCPs in your agents:\n');
|
|
665
|
+
console.log(' Claude Code (installed via marketplace):');
|
|
666
|
+
console.log(' /plugin update bi-superpowers');
|
|
667
|
+
console.log('');
|
|
668
|
+
console.log(' Any other install path (npm + super install):');
|
|
669
|
+
console.log(' super install --yes');
|
|
670
|
+
console.log('');
|
|
671
|
+
console.log(
|
|
672
|
+
'If you only wanted the CLI updated (e.g. developing locally), you can skip the above.'
|
|
673
|
+
);
|
|
674
674
|
} catch (error) {
|
|
675
675
|
console.error('Update failed:', error.message);
|
|
676
676
|
console.log(`\nTry manually: npm install -g ${PACKAGE_NAME}@latest`);
|
|
@@ -678,59 +678,32 @@ function updatePackage() {
|
|
|
678
678
|
}
|
|
679
679
|
}
|
|
680
680
|
|
|
681
|
+
/**
|
|
682
|
+
* `super powers` — list the available skills (and their titles).
|
|
683
|
+
*/
|
|
681
684
|
function listAgents() {
|
|
682
685
|
const skills = getSkillFiles();
|
|
683
686
|
|
|
684
687
|
console.log(`
|
|
685
|
-
BI Agent Superpowers
|
|
686
|
-
|
|
688
|
+
BI Agent Superpowers — Skills
|
|
689
|
+
=============================
|
|
687
690
|
Single Source of Truth: ${skills.length} skills (open source)
|
|
688
691
|
`);
|
|
689
692
|
|
|
690
|
-
console.log('Skills
|
|
693
|
+
console.log('Skills:');
|
|
691
694
|
for (const skill of skills) {
|
|
692
695
|
const meta = parseSkillMetadata(skill.content);
|
|
693
696
|
console.log(` /${skill.name.padEnd(20)} ${meta.title || ''}`);
|
|
694
697
|
}
|
|
695
698
|
console.log('');
|
|
696
699
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
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}`);
|
|
700
|
+
console.log('Supported AI tools:');
|
|
701
|
+
Object.entries(AI_TOOLS).forEach(([, cfg]) => {
|
|
702
|
+
console.log(` • ${cfg.name}`);
|
|
730
703
|
});
|
|
731
704
|
console.log('');
|
|
732
705
|
|
|
733
|
-
console.log("Run '
|
|
706
|
+
console.log("Run 'super recharge' to regenerate configs after editing skills.");
|
|
734
707
|
}
|
|
735
708
|
|
|
736
709
|
// ============================================
|
|
@@ -738,24 +711,19 @@ Single Source of Truth: ${skills.length} skills (open source)
|
|
|
738
711
|
// ============================================
|
|
739
712
|
|
|
740
713
|
/**
|
|
741
|
-
*
|
|
714
|
+
* Shared config object passed into every command module.
|
|
742
715
|
*/
|
|
743
716
|
function getCommandConfig() {
|
|
744
717
|
return {
|
|
745
718
|
skillsDir: SKILLS_DIR,
|
|
746
|
-
libraryDir: LIBRARY_DIR,
|
|
747
719
|
packageDir: PACKAGE_DIR,
|
|
748
720
|
version: VERSION,
|
|
749
721
|
};
|
|
750
722
|
}
|
|
751
723
|
|
|
752
724
|
/**
|
|
753
|
-
*
|
|
754
|
-
*
|
|
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
|
|
725
|
+
* Factory that wraps a command module with a consistent "missing module"
|
|
726
|
+
* error so every non-core command fails the same way during `npm install`.
|
|
759
727
|
*/
|
|
760
728
|
function createCommandWrapper(commandModule, commandName) {
|
|
761
729
|
return (args) => {
|
|
@@ -767,44 +735,29 @@ function createCommandWrapper(commandModule, commandName) {
|
|
|
767
735
|
};
|
|
768
736
|
}
|
|
769
737
|
|
|
770
|
-
//
|
|
771
|
-
const runSearch = createCommandWrapper(searchCommand, 'Search');
|
|
738
|
+
// Wrapper instances — created after createCommandWrapper is defined.
|
|
772
739
|
const runLint = createCommandWrapper(lintCommand, 'Lint');
|
|
773
740
|
const runDiff = createCommandWrapper(diffCommand, 'Diff');
|
|
774
741
|
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
742
|
const runBuildDesktop = createCommandWrapper(buildDesktopCommand, 'Build Desktop');
|
|
783
743
|
const runInstall = createCommandWrapper(installCommand, 'Install');
|
|
784
744
|
|
|
785
|
-
// Register commands
|
|
745
|
+
// Register wrapper-based commands into the command map (phase 2).
|
|
786
746
|
commands.install = runInstall;
|
|
787
|
-
commands.xray = runSearch;
|
|
788
747
|
commands.checkup = runLint;
|
|
789
748
|
commands.scan = runDiff;
|
|
790
749
|
commands.sentinel = runWatch;
|
|
791
750
|
commands['mcp-setup'] = runMcpSetup;
|
|
792
751
|
commands.mcp = runMcpSetup;
|
|
793
752
|
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
753
|
commands.lint = runLint;
|
|
803
754
|
commands.diff = runDiff;
|
|
804
755
|
commands.watch = runWatch;
|
|
805
756
|
|
|
806
757
|
/**
|
|
807
|
-
*
|
|
758
|
+
* `super sentinel` — watch skill sources and auto-regenerate the plugin.
|
|
759
|
+
* Needs extra context (a reference to the sync function) so it has its
|
|
760
|
+
* own wrapper instead of using createCommandWrapper.
|
|
808
761
|
*/
|
|
809
762
|
function runWatch(args) {
|
|
810
763
|
if (!watchCommand) {
|
|
@@ -812,14 +765,13 @@ function runWatch(args) {
|
|
|
812
765
|
process.exit(1);
|
|
813
766
|
}
|
|
814
767
|
|
|
815
|
-
// Create a reference to sync function for watch to use
|
|
816
768
|
const cliModule = {
|
|
817
769
|
syncProjectInternal: (targetDir, tools) => {
|
|
818
770
|
const skills = getSkillFiles();
|
|
819
771
|
for (const tool of tools) {
|
|
820
|
-
const
|
|
821
|
-
if (
|
|
822
|
-
|
|
772
|
+
const cfg = AI_TOOLS[tool];
|
|
773
|
+
if (cfg && cfg.generate) {
|
|
774
|
+
cfg.generate(targetDir, skills, { packageDir: PACKAGE_DIR });
|
|
823
775
|
}
|
|
824
776
|
}
|
|
825
777
|
},
|
|
@@ -829,14 +781,14 @@ function runWatch(args) {
|
|
|
829
781
|
}
|
|
830
782
|
|
|
831
783
|
/**
|
|
832
|
-
* Check if --dry-run
|
|
784
|
+
* Check if --dry-run (or -n) is present in the argument list.
|
|
833
785
|
*/
|
|
834
786
|
function hasDryRunFlag(args) {
|
|
835
787
|
return args.includes('--dry-run') || args.includes('-n');
|
|
836
788
|
}
|
|
837
789
|
|
|
838
790
|
/**
|
|
839
|
-
*
|
|
791
|
+
* Strip the --dry-run / -n flag from the argument list.
|
|
840
792
|
*/
|
|
841
793
|
function removeDryRunFlag(args) {
|
|
842
794
|
return args.filter((a) => a !== '--dry-run' && a !== '-n');
|
|
@@ -850,10 +802,14 @@ module.exports = {
|
|
|
850
802
|
getSkillFiles,
|
|
851
803
|
loadToolConfig,
|
|
852
804
|
saveToolConfig,
|
|
805
|
+
getUpgradeCommand,
|
|
806
|
+
resetUpdateCheckStateAfterUpgrade,
|
|
853
807
|
AI_TOOLS,
|
|
854
808
|
SKILLS_DIR,
|
|
855
|
-
LIBRARY_DIR,
|
|
856
809
|
VERSION,
|
|
857
810
|
};
|
|
858
811
|
|
|
859
|
-
main()
|
|
812
|
+
// Only run main() when invoked as the binary (not when required from tests).
|
|
813
|
+
if (require.main === module) {
|
|
814
|
+
main();
|
|
815
|
+
}
|