@luquimbo/bi-superpowers 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +8 -0
- package/.mcp.json +25 -0
- package/AGENTS.md +244 -0
- package/CHANGELOG.md +265 -0
- package/LICENSE +21 -0
- package/README.md +211 -0
- package/bin/build-plugin.js +30 -0
- package/bin/cli.js +1064 -0
- package/bin/commands/add.js +533 -0
- package/bin/commands/add.test.js +77 -0
- package/bin/commands/build-desktop.js +166 -0
- package/bin/commands/changelog.js +443 -0
- package/bin/commands/diff.js +325 -0
- package/bin/commands/lint.js +419 -0
- package/bin/commands/lint.test.js +103 -0
- package/bin/commands/mcp-setup.js +246 -0
- package/bin/commands/pull.js +287 -0
- package/bin/commands/pull.test.js +36 -0
- package/bin/commands/push.js +231 -0
- package/bin/commands/push.test.js +14 -0
- package/bin/commands/search.js +344 -0
- package/bin/commands/search.test.js +115 -0
- package/bin/commands/setup.js +545 -0
- package/bin/commands/setup.test.js +46 -0
- package/bin/commands/sync-profile.js +405 -0
- package/bin/commands/sync-profile.test.js +14 -0
- package/bin/commands/sync-source.js +418 -0
- package/bin/commands/sync-source.test.js +14 -0
- package/bin/commands/watch.js +206 -0
- package/bin/lib/generators/claude-plugin.js +266 -0
- package/bin/lib/generators/claude-plugin.test.js +110 -0
- package/bin/lib/generators/index.js +116 -0
- package/bin/lib/generators/shared.js +282 -0
- package/bin/lib/licensing/index.js +35 -0
- package/bin/lib/licensing/storage.js +364 -0
- package/bin/lib/licensing/storage.test.js +55 -0
- package/bin/lib/licensing/validator.js +213 -0
- package/bin/lib/licensing/validator.test.js +137 -0
- package/bin/lib/microsoft-mcp.js +176 -0
- package/bin/lib/microsoft-mcp.test.js +106 -0
- package/bin/lib/skills.js +84 -0
- package/bin/mcp/powerbi-modeling-launcher.js +38 -0
- package/bin/postinstall.js +44 -0
- package/bin/utils/errors.js +159 -0
- package/bin/utils/git.js +298 -0
- package/bin/utils/logger.js +142 -0
- package/bin/utils/mcp-detect.js +274 -0
- package/bin/utils/mcp-detect.test.js +105 -0
- package/bin/utils/pbix.js +305 -0
- package/bin/utils/pbix.test.js +37 -0
- package/bin/utils/profiles.js +312 -0
- package/bin/utils/projects.js +168 -0
- package/bin/utils/readline.js +206 -0
- package/bin/utils/readline.test.js +47 -0
- package/bin/utils/tui.js +314 -0
- package/bin/utils/tui.test.js +127 -0
- package/commands/contributions.md +265 -0
- package/commands/data-model-design.md +468 -0
- package/commands/dax-doctor.md +248 -0
- package/commands/fabric-scripts.md +452 -0
- package/commands/migration-assistant.md +290 -0
- package/commands/model-documenter.md +242 -0
- package/commands/pbi-connect.md +239 -0
- package/commands/project-kickoff.md +905 -0
- package/commands/report-layout.md +296 -0
- package/commands/rls-design.md +533 -0
- package/commands/theme-tweaker.md +624 -0
- package/config.example.json +23 -0
- package/config.json +23 -0
- package/desktop-extension/manifest.json +37 -0
- package/desktop-extension/package.json +10 -0
- package/desktop-extension/server.js +95 -0
- package/docs/openrouter-free-models.md +92 -0
- package/library/examples/README.md +151 -0
- package/library/examples/finance-reporting/README.md +351 -0
- package/library/examples/finance-reporting/data-model.md +267 -0
- package/library/examples/finance-reporting/measures.dax +557 -0
- package/library/examples/hr-analytics/README.md +371 -0
- package/library/examples/hr-analytics/data-model.md +315 -0
- package/library/examples/hr-analytics/measures.dax +460 -0
- package/library/examples/marketing-analytics/README.md +37 -0
- package/library/examples/marketing-analytics/data-model.md +62 -0
- package/library/examples/marketing-analytics/measures.dax +110 -0
- package/library/examples/retail-analytics/README.md +439 -0
- package/library/examples/retail-analytics/data-model.md +288 -0
- package/library/examples/retail-analytics/measures.dax +481 -0
- package/library/examples/supply-chain/README.md +37 -0
- package/library/examples/supply-chain/data-model.md +69 -0
- package/library/examples/supply-chain/measures.dax +77 -0
- package/library/examples/udf-library/README.md +228 -0
- package/library/examples/udf-library/functions.dax +571 -0
- package/library/snippets/dax/README.md +292 -0
- package/library/snippets/dax/business-domains.md +576 -0
- package/library/snippets/dax/calculate-patterns.md +276 -0
- package/library/snippets/dax/calculation-groups.md +489 -0
- package/library/snippets/dax/error-handling.md +495 -0
- package/library/snippets/dax/iterators-and-aggregations.md +474 -0
- package/library/snippets/dax/kpis-and-metrics.md +293 -0
- package/library/snippets/dax/rankings-and-topn.md +235 -0
- package/library/snippets/dax/security-patterns.md +413 -0
- package/library/snippets/dax/text-and-formatting.md +316 -0
- package/library/snippets/dax/time-intelligence.md +196 -0
- package/library/snippets/dax/user-defined-functions.md +477 -0
- package/library/snippets/dax/virtual-tables.md +546 -0
- package/library/snippets/excel-formulas/README.md +84 -0
- package/library/snippets/excel-formulas/aggregations.md +330 -0
- package/library/snippets/excel-formulas/dates-and-times.md +361 -0
- package/library/snippets/excel-formulas/dynamic-arrays.md +314 -0
- package/library/snippets/excel-formulas/lookups.md +169 -0
- package/library/snippets/excel-formulas/text-functions.md +363 -0
- package/library/snippets/governance/naming-conventions.md +97 -0
- package/library/snippets/governance/review-checklists.md +107 -0
- package/library/snippets/power-query/README.md +389 -0
- package/library/snippets/power-query/api-integration.md +707 -0
- package/library/snippets/power-query/connections.md +434 -0
- package/library/snippets/power-query/data-cleaning.md +298 -0
- package/library/snippets/power-query/error-handling.md +526 -0
- package/library/snippets/power-query/parameters.md +350 -0
- package/library/snippets/power-query/performance.md +506 -0
- package/library/snippets/power-query/transformations.md +330 -0
- package/library/snippets/report-design/accessibility.md +78 -0
- package/library/snippets/report-design/chart-selection.md +54 -0
- package/library/snippets/report-design/layout-patterns.md +87 -0
- package/library/templates/data-models/README.md +93 -0
- package/library/templates/data-models/finance-model.md +627 -0
- package/library/templates/data-models/retail-star-schema.md +473 -0
- package/library/templates/excel/README.md +83 -0
- package/library/templates/excel/budget-tracker.md +432 -0
- package/library/templates/excel/data-entry-form.md +533 -0
- package/library/templates/power-bi/README.md +72 -0
- package/library/templates/power-bi/finance-report.md +449 -0
- package/library/templates/power-bi/kpi-scorecard.md +461 -0
- package/library/templates/power-bi/sales-dashboard.md +281 -0
- package/library/themes/excel/README.md +436 -0
- package/library/themes/power-bi/README.md +271 -0
- package/library/themes/power-bi/accessible.json +307 -0
- package/library/themes/power-bi/bi-superpowers-default.json +858 -0
- package/library/themes/power-bi/corporate-blue.json +291 -0
- package/library/themes/power-bi/dark-mode.json +291 -0
- package/library/themes/power-bi/minimal.json +292 -0
- package/library/themes/power-bi/print-friendly.json +309 -0
- package/package.json +93 -0
- package/skills/contributions/SKILL.md +267 -0
- package/skills/data-model-design/SKILL.md +470 -0
- package/skills/data-modeling/SKILL.md +254 -0
- package/skills/data-quality/SKILL.md +664 -0
- package/skills/dax/SKILL.md +708 -0
- package/skills/dax-doctor/SKILL.md +250 -0
- package/skills/dax-udf/SKILL.md +489 -0
- package/skills/deployment/SKILL.md +320 -0
- package/skills/excel-formulas/SKILL.md +463 -0
- package/skills/fabric-scripts/SKILL.md +454 -0
- package/skills/fast-standard/SKILL.md +509 -0
- package/skills/governance/SKILL.md +205 -0
- package/skills/migration-assistant/SKILL.md +292 -0
- package/skills/model-documenter/SKILL.md +244 -0
- package/skills/pbi-connect/SKILL.md +241 -0
- package/skills/power-query/SKILL.md +406 -0
- package/skills/project-kickoff/SKILL.md +907 -0
- package/skills/query-performance/SKILL.md +480 -0
- package/skills/report-design/SKILL.md +207 -0
- package/skills/report-layout/SKILL.md +298 -0
- package/skills/rls-design/SKILL.md +535 -0
- package/skills/semantic-model/SKILL.md +237 -0
- package/skills/testing-validation/SKILL.md +643 -0
- package/skills/theme-tweaker/SKILL.md +626 -0
- package/src/content/base.md +237 -0
- package/src/content/mcp-requirements.json +69 -0
- package/src/content/routing.md +203 -0
- package/src/content/skills/contributions.md +259 -0
- package/src/content/skills/data-model-design.md +462 -0
- package/src/content/skills/data-modeling.md +246 -0
- package/src/content/skills/data-quality.md +656 -0
- package/src/content/skills/dax-doctor.md +242 -0
- package/src/content/skills/dax-udf.md +481 -0
- package/src/content/skills/dax.md +700 -0
- package/src/content/skills/deployment.md +312 -0
- package/src/content/skills/excel-formulas.md +455 -0
- package/src/content/skills/fabric-scripts.md +446 -0
- package/src/content/skills/fast-standard.md +501 -0
- package/src/content/skills/governance.md +197 -0
- package/src/content/skills/migration-assistant.md +284 -0
- package/src/content/skills/model-documenter.md +236 -0
- package/src/content/skills/pbi-connect.md +233 -0
- package/src/content/skills/power-query.md +398 -0
- package/src/content/skills/project-kickoff.md +899 -0
- package/src/content/skills/query-performance.md +472 -0
- package/src/content/skills/report-design.md +199 -0
- package/src/content/skills/report-layout.md +290 -0
- package/src/content/skills/rls-design.md +527 -0
- package/src/content/skills/semantic-model.md +229 -0
- package/src/content/skills/testing-validation.md +635 -0
- package/src/content/skills/theme-tweaker.md +618 -0
package/bin/cli.js
ADDED
|
@@ -0,0 +1,1064 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BI Agent Superpowers - Command Line Interface
|
|
5
|
+
* ==============================================
|
|
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.
|
|
10
|
+
*
|
|
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).
|
|
15
|
+
*
|
|
16
|
+
* License System:
|
|
17
|
+
* - Premium content requires activation via `bi-superpowers unlock`
|
|
18
|
+
* - License validation happens against https://acadevor.com API
|
|
19
|
+
* - Content is cached locally in ~/.bi-superpowers/
|
|
20
|
+
*
|
|
21
|
+
* @module cli
|
|
22
|
+
* @author Lucas Sanchez (@luquimbo)
|
|
23
|
+
* @license MIT
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const fs = require('fs');
|
|
27
|
+
const path = require('path');
|
|
28
|
+
const { execSync } = require('child_process');
|
|
29
|
+
const readline = require('readline');
|
|
30
|
+
const os = require('os');
|
|
31
|
+
const { loadSkills } = require('./lib/skills');
|
|
32
|
+
|
|
33
|
+
// Import lib modules (extracted from cli.js for better organization)
|
|
34
|
+
let licensing, generators;
|
|
35
|
+
try {
|
|
36
|
+
licensing = require('./lib/licensing');
|
|
37
|
+
generators = require('./lib/generators');
|
|
38
|
+
} catch (e) {
|
|
39
|
+
// Modules may not be available during npm install phase
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Import command modules - these provide the xray, checkup, scan, sentinel, and mcp-setup commands
|
|
43
|
+
// Wrapped in try-catch because they may not be available during initial npm install
|
|
44
|
+
let searchCommand, lintCommand, diffCommand, watchCommand, mcpSetupCommand, tui;
|
|
45
|
+
let setupCommand, addCommand, pullCommand, pushCommand, syncProfileCommand, syncSourceCommand;
|
|
46
|
+
let changelogCommand, buildDesktopCommand;
|
|
47
|
+
try {
|
|
48
|
+
searchCommand = require('./commands/search'); // Fuzzy search across library content
|
|
49
|
+
lintCommand = require('./commands/lint'); // Skill file validation
|
|
50
|
+
diffCommand = require('./commands/diff'); // Compare source vs generated configs
|
|
51
|
+
watchCommand = require('./commands/watch'); // Auto-regenerate on file changes
|
|
52
|
+
mcpSetupCommand = require('./commands/mcp-setup'); // MCP server configuration
|
|
53
|
+
tui = require('./utils/tui'); // Terminal UI helpers (colors, tables, etc.)
|
|
54
|
+
|
|
55
|
+
// Repo multi-project commands (v3)
|
|
56
|
+
setupCommand = require('./commands/setup'); // Onboarding wizard for bi-repo
|
|
57
|
+
addCommand = require('./commands/add'); // Add project to repo
|
|
58
|
+
pullCommand = require('./commands/pull'); // Pull changes from original file
|
|
59
|
+
pushCommand = require('./commands/push'); // Push changes to original file
|
|
60
|
+
syncProfileCommand = require('./commands/sync-profile'); // Sync snippets to profile
|
|
61
|
+
syncSourceCommand = require('./commands/sync-source'); // Bidirectional sync
|
|
62
|
+
changelogCommand = require('./commands/changelog'); // Generate changelog from Git
|
|
63
|
+
buildDesktopCommand = require('./commands/build-desktop'); // Build MCPB for Claude Desktop
|
|
64
|
+
} catch (e) {
|
|
65
|
+
// Silent fail - commands may not be available during npm install phase
|
|
66
|
+
// This is expected behavior, not an error condition
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ============================================
|
|
70
|
+
// CONFIGURATION CONSTANTS
|
|
71
|
+
// ============================================
|
|
72
|
+
|
|
73
|
+
/** Package version from package.json */
|
|
74
|
+
const VERSION = require('../package.json').version;
|
|
75
|
+
|
|
76
|
+
/** Dynamic skill/command counts from the plugin generator (avoids hardcoding) */
|
|
77
|
+
let COMMAND_COUNT = 11;
|
|
78
|
+
let TOTAL_SKILL_COUNT = 24;
|
|
79
|
+
try {
|
|
80
|
+
const { COMMAND_SKILLS, REFERENCE_SKILLS } = require('./lib/generators/claude-plugin');
|
|
81
|
+
COMMAND_COUNT = COMMAND_SKILLS.size;
|
|
82
|
+
TOTAL_SKILL_COUNT = COMMAND_SKILLS.size + REFERENCE_SKILLS.size;
|
|
83
|
+
} catch (_) {
|
|
84
|
+
// Fallback to defaults during npm install phase
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Directory where the npm package is installed */
|
|
88
|
+
const PACKAGE_DIR = path.dirname(__dirname);
|
|
89
|
+
|
|
90
|
+
/** Directory for cached premium content (skills, snippets, themes) */
|
|
91
|
+
const CONTENT_CACHE_DIR = path.join(os.homedir(), '.bi-superpowers');
|
|
92
|
+
|
|
93
|
+
// File paths - premium content is downloaded to CONTENT_CACHE_DIR
|
|
94
|
+
/** Directory containing skill definition files (.md) */
|
|
95
|
+
const SKILLS_DIR = path.join(CONTENT_CACHE_DIR, 'src', 'content', 'skills');
|
|
96
|
+
|
|
97
|
+
/** Directory containing code snippets, templates, and themes */
|
|
98
|
+
const LIBRARY_DIR = path.join(CONTENT_CACHE_DIR, 'library');
|
|
99
|
+
|
|
100
|
+
/** Project-local config file name (stores tool selections) */
|
|
101
|
+
const CONFIG_FILE = '.bi-superpowers.json';
|
|
102
|
+
|
|
103
|
+
/** Symlink name created in projects pointing to content cache */
|
|
104
|
+
const SYMLINK_NAME = '.bi-superpowers';
|
|
105
|
+
|
|
106
|
+
/** npm package name for update commands */
|
|
107
|
+
const PACKAGE_NAME = '@luquimbo/bi-superpowers';
|
|
108
|
+
const DEFAULT_TOOLS = ['claude-plugin'];
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* AI Tools Configuration - uses generators from lib/generators module
|
|
112
|
+
* Falls back to empty object if module not loaded
|
|
113
|
+
*/
|
|
114
|
+
const AI_TOOLS = generators ? generators.AI_TOOLS : {};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Command Routing Map
|
|
118
|
+
*
|
|
119
|
+
* Maps CLI command names to their handler functions.
|
|
120
|
+
* Supports both branded names (kickoff, recharge) and legacy names (init, sync)
|
|
121
|
+
* for backward compatibility.
|
|
122
|
+
*
|
|
123
|
+
* Command Categories:
|
|
124
|
+
* - Core: Basic info commands (help, version, about, status)
|
|
125
|
+
* - Setup: Project initialization and configuration (kickoff, recharge, unlock, upgrade)
|
|
126
|
+
* - Developer: Advanced tools for content management (xray, checkup, scan, sentinel, powers)
|
|
127
|
+
* - Legacy: Old command names maintained for backward compatibility
|
|
128
|
+
*/
|
|
129
|
+
const commands = {
|
|
130
|
+
// Core commands - basic info and status
|
|
131
|
+
help: showHelp,
|
|
132
|
+
version: showVersion,
|
|
133
|
+
about: showInfo,
|
|
134
|
+
status: showLicenseStatus,
|
|
135
|
+
|
|
136
|
+
// Setup & sync - project configuration
|
|
137
|
+
kickoff: initProject, // Interactive project setup wizard
|
|
138
|
+
recharge: syncProject, // Regenerate AI tool configs from skills
|
|
139
|
+
unlock: activateLicense, // Activate license key
|
|
140
|
+
upgrade: updatePackage, // Update to latest npm version
|
|
141
|
+
|
|
142
|
+
// Developer tools - content management
|
|
143
|
+
xray: runSearch, // Fuzzy search library content
|
|
144
|
+
checkup: runLint, // Validate skill files
|
|
145
|
+
scan: runDiff, // Compare source vs generated
|
|
146
|
+
sentinel: runWatch, // Watch and auto-regenerate
|
|
147
|
+
powers: listAgents, // List available skills
|
|
148
|
+
'mcp-setup': runMcpSetup, // Configure MCP servers for AI tools
|
|
149
|
+
mcp: runMcpSetup, // Alias for mcp-setup
|
|
150
|
+
'build-desktop': runBuildDesktop, // Build MCPB extension for Claude Desktop
|
|
151
|
+
|
|
152
|
+
// Repo multi-project commands (v3)
|
|
153
|
+
setup: runSetup, // Onboarding wizard - creates bi-repo
|
|
154
|
+
add: runAdd, // Add project to bi-repo
|
|
155
|
+
pull: runPull, // Pull changes from original file to repo
|
|
156
|
+
push: runPush, // Push changes from repo to original file
|
|
157
|
+
'sync-source': runSyncSource, // Bidirectional sync with original file
|
|
158
|
+
'sync-profile': runSyncProfile, // Sync snippets to base profile
|
|
159
|
+
changelog: runChangelog, // Generate changelog from Git history
|
|
160
|
+
|
|
161
|
+
// Legacy aliases (backward compatibility with v2.0.x)
|
|
162
|
+
init: initProject,
|
|
163
|
+
sync: syncProject,
|
|
164
|
+
activate: activateLicense,
|
|
165
|
+
update: updatePackage,
|
|
166
|
+
search: runSearch,
|
|
167
|
+
lint: runLint,
|
|
168
|
+
diff: runDiff,
|
|
169
|
+
watch: runWatch,
|
|
170
|
+
list: listAgents,
|
|
171
|
+
info: showInfo,
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Main entry point - parses CLI arguments and routes to appropriate command
|
|
176
|
+
*/
|
|
177
|
+
function main() {
|
|
178
|
+
const args = process.argv.slice(2);
|
|
179
|
+
const command = args[0] || 'help';
|
|
180
|
+
|
|
181
|
+
if (commands[command]) {
|
|
182
|
+
commands[command](args.slice(1));
|
|
183
|
+
} else {
|
|
184
|
+
console.error(`Unknown command: ${command}`);
|
|
185
|
+
showHelp();
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function showHelp() {
|
|
191
|
+
console.log(`
|
|
192
|
+
BI Agent Superpowers v${VERSION}
|
|
193
|
+
================================
|
|
194
|
+
|
|
195
|
+
Claude Code plugin for Power BI, Fabric & Excel development.
|
|
196
|
+
Works with: Claude Code, 1code.dev, Claude Desktop.
|
|
197
|
+
|
|
198
|
+
Usage:
|
|
199
|
+
super <command> [options]
|
|
200
|
+
|
|
201
|
+
Commands:
|
|
202
|
+
unlock Activate your license key
|
|
203
|
+
kickoff [path] Initialize the Claude Code plugin in your project
|
|
204
|
+
recharge [path] Regenerate the plugin from source skills
|
|
205
|
+
build-desktop Build .mcpb extension for Claude Desktop
|
|
206
|
+
powers List available skills and resources
|
|
207
|
+
xray <query> Search snippets and library content
|
|
208
|
+
checkup [file] Validate skill files
|
|
209
|
+
scan Show changes between source and generated configs
|
|
210
|
+
sentinel Watch for changes and auto-regenerate
|
|
211
|
+
mcp-setup Configure official Microsoft MCP servers
|
|
212
|
+
upgrade Update to latest version
|
|
213
|
+
status Show license status
|
|
214
|
+
about Show installation info
|
|
215
|
+
help Show this help
|
|
216
|
+
|
|
217
|
+
Repo Multi-Proyecto (v3):
|
|
218
|
+
setup Create your bi-repo for version control
|
|
219
|
+
add <file> Add a .pbix/.xlsx project to the repo
|
|
220
|
+
pull [project] Pull changes from original file to repo
|
|
221
|
+
push [project] Push changes from repo to original file
|
|
222
|
+
sync-source Bidirectional sync (detects which is newer)
|
|
223
|
+
sync-profile Sync snippets to a base profile
|
|
224
|
+
|
|
225
|
+
Options:
|
|
226
|
+
--dry-run Preview changes without creating files (kickoff, recharge)
|
|
227
|
+
|
|
228
|
+
Examples:
|
|
229
|
+
super unlock # Activate your license
|
|
230
|
+
super kickoff # Initialize plugin in current directory
|
|
231
|
+
super kickoff ./my-project # Initialize in specific directory
|
|
232
|
+
super kickoff --dry-run # Preview what would be created
|
|
233
|
+
super recharge # Regenerate plugin from source skills
|
|
234
|
+
super build-desktop # Build .mcpb for Claude Desktop
|
|
235
|
+
super xray "YTD" # Search for time intelligence patterns
|
|
236
|
+
super xray --category dax # Search within a category
|
|
237
|
+
super checkup # Validate all skills
|
|
238
|
+
super mcp-setup # Configure official Microsoft MCPs
|
|
239
|
+
super powers # Show available superpowers
|
|
240
|
+
claude --plugin-dir . # Run Claude Code with the plugin
|
|
241
|
+
|
|
242
|
+
Repo Multi-Proyecto:
|
|
243
|
+
super setup # Create your bi-repo (first time)
|
|
244
|
+
super add "Sales.pbix" # Add project to repo
|
|
245
|
+
super pull # Pull changes from original
|
|
246
|
+
super push # Push changes to original
|
|
247
|
+
super sync-source # Auto-detect and sync
|
|
248
|
+
super sync-profile # Save snippets to profile
|
|
249
|
+
|
|
250
|
+
Get your license at: https://acadevor.com/bi-superpowers
|
|
251
|
+
Documentation: https://github.com/luquimbo/bi-superpowers
|
|
252
|
+
`);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function showVersion() {
|
|
256
|
+
console.log(`BI Agent Superpowers v${VERSION}`);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function showInfo() {
|
|
260
|
+
const skillCount = getSkillFiles().length;
|
|
261
|
+
const license = loadLicense();
|
|
262
|
+
const licenseStatus = license ? `Active (${license.email})` : 'Not activated';
|
|
263
|
+
const contentStatus = isContentInstalled() ? `Installed (${skillCount} skills)` : 'Not installed';
|
|
264
|
+
const aiToolsList = Object.entries(AI_TOOLS)
|
|
265
|
+
.map(([_k, v]) => ` - ${v.name}`)
|
|
266
|
+
.join('\n');
|
|
267
|
+
|
|
268
|
+
console.log(`
|
|
269
|
+
BI Agent Superpowers - Installation Info
|
|
270
|
+
========================================
|
|
271
|
+
|
|
272
|
+
Version: ${VERSION}
|
|
273
|
+
Author: Lucas Sanchez (@luquimbo)
|
|
274
|
+
Package dir: ${PACKAGE_DIR}
|
|
275
|
+
Content dir: ${CONTENT_CACHE_DIR}
|
|
276
|
+
License: ${licenseStatus}
|
|
277
|
+
Content: ${contentStatus}
|
|
278
|
+
|
|
279
|
+
Architecture: Single Source of Truth
|
|
280
|
+
Skills defined once, generated for the Claude Code plugin
|
|
281
|
+
|
|
282
|
+
Compatible with:
|
|
283
|
+
- Claude Code (plugin)
|
|
284
|
+
- 1code.dev (uses Claude Code SDK)
|
|
285
|
+
- Claude Desktop (via MCPB extension)
|
|
286
|
+
|
|
287
|
+
Plugin Generators:
|
|
288
|
+
${aiToolsList}
|
|
289
|
+
|
|
290
|
+
GitHub: https://github.com/luquimbo/bi-superpowers
|
|
291
|
+
`);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Creates a readline interface for interactive CLI prompts
|
|
296
|
+
* @returns {readline.Interface} Readline interface
|
|
297
|
+
*/
|
|
298
|
+
function createReadline() {
|
|
299
|
+
return readline.createInterface({
|
|
300
|
+
input: process.stdin,
|
|
301
|
+
output: process.stdout,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Promisified readline question
|
|
307
|
+
* @param {readline.Interface} rl - Readline interface
|
|
308
|
+
* @param {string} question - Question to display
|
|
309
|
+
* @returns {Promise<string>} User's trimmed answer
|
|
310
|
+
*/
|
|
311
|
+
function prompt(rl, question) {
|
|
312
|
+
return new Promise((resolve) => {
|
|
313
|
+
rl.question(question, (answer) => resolve(answer.trim()));
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// ============================================
|
|
318
|
+
// LICENSE MANAGEMENT
|
|
319
|
+
// ============================================
|
|
320
|
+
// These functions handle license storage, validation, and premium content downloads.
|
|
321
|
+
// Licenses are stored in ~/.bi-superpowers-license as JSON.
|
|
322
|
+
|
|
323
|
+
// License functions - delegated to lib/licensing module
|
|
324
|
+
function loadLicense() {
|
|
325
|
+
return licensing ? licensing.loadLicense() : null;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function saveLicense(data) {
|
|
329
|
+
if (licensing) licensing.saveLicense(data);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// HTTP/download/extract functions - delegated to lib/licensing module
|
|
333
|
+
function isContentInstalled() {
|
|
334
|
+
return licensing ? licensing.isContentInstalled() : false;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
async function validateLicense(licenseKey) {
|
|
338
|
+
return licensing
|
|
339
|
+
? licensing.validateLicense(licenseKey)
|
|
340
|
+
: { valid: false, error: 'Module not loaded' };
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
async function downloadPremiumContent(downloadUrl) {
|
|
344
|
+
return licensing ? licensing.downloadPremiumContent(downloadUrl) : false;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Show license status command handler
|
|
349
|
+
*
|
|
350
|
+
* Displays current license status including:
|
|
351
|
+
* - Whether a license is activated
|
|
352
|
+
* - Email and activation date if active
|
|
353
|
+
* - Instructions for activation if not active
|
|
354
|
+
*/
|
|
355
|
+
function showLicenseStatus() {
|
|
356
|
+
const license = loadLicense();
|
|
357
|
+
|
|
358
|
+
if (!license) {
|
|
359
|
+
console.log(`
|
|
360
|
+
License Status: NOT ACTIVATED
|
|
361
|
+
|
|
362
|
+
Run 'bi-superpowers unlock' to activate your license.
|
|
363
|
+
Get your license at: https://acadevor.com/bi-superpowers
|
|
364
|
+
`);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
console.log(`
|
|
369
|
+
License Status: ACTIVE ✓
|
|
370
|
+
|
|
371
|
+
Email: ${license.email}
|
|
372
|
+
License: ${license.license.substring(0, 8)}...
|
|
373
|
+
Activated: ${license.activatedAt || 'Unknown'}
|
|
374
|
+
|
|
375
|
+
Run 'bi-superpowers unlock' to re-activate or change license.
|
|
376
|
+
`);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Activate license command handler (super unlock)
|
|
381
|
+
*
|
|
382
|
+
* Interactive command that:
|
|
383
|
+
* 1. Prompts user for their license key
|
|
384
|
+
* 2. Validates the key against the API
|
|
385
|
+
* 3. Downloads premium content if validation succeeds
|
|
386
|
+
* 4. Saves the license locally for future sessions
|
|
387
|
+
*
|
|
388
|
+
* This is typically the first command users run after installation.
|
|
389
|
+
*/
|
|
390
|
+
async function activateLicense() {
|
|
391
|
+
console.log(`
|
|
392
|
+
BI Agent Superpowers - License Activation
|
|
393
|
+
=========================================
|
|
394
|
+
`);
|
|
395
|
+
|
|
396
|
+
const existingLicense = loadLicense();
|
|
397
|
+
if (existingLicense) {
|
|
398
|
+
console.log(
|
|
399
|
+
`Current license: ${existingLicense.license.substring(0, 8)}... (${existingLicense.email})`
|
|
400
|
+
);
|
|
401
|
+
console.log('');
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const rl = createReadline();
|
|
405
|
+
|
|
406
|
+
try {
|
|
407
|
+
const licenseKey = await prompt(rl, 'Enter your license key: ');
|
|
408
|
+
|
|
409
|
+
if (!licenseKey) {
|
|
410
|
+
console.log('\nNo license key provided.');
|
|
411
|
+
process.exit(1);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
console.log('\nValidating license...');
|
|
415
|
+
|
|
416
|
+
const result = await validateLicense(licenseKey);
|
|
417
|
+
|
|
418
|
+
if (!result.valid) {
|
|
419
|
+
console.log(`\n✗ License invalid: ${result.error || 'Unknown error'}`);
|
|
420
|
+
console.log('\nGet your license at: https://acadevor.com/bi-superpowers');
|
|
421
|
+
process.exit(1);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
console.log('\n✓ License validated!');
|
|
425
|
+
console.log(` Email: ${result.email}`);
|
|
426
|
+
if (result.name) {
|
|
427
|
+
console.log(` Name: ${result.name}`);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Download premium content
|
|
431
|
+
console.log('');
|
|
432
|
+
if (result.downloadUrl) {
|
|
433
|
+
const downloaded = await downloadPremiumContent(result.downloadUrl);
|
|
434
|
+
if (!downloaded) {
|
|
435
|
+
console.log('\n⚠ Content download failed. You can retry with "bi-superpowers unlock"');
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Save license
|
|
440
|
+
saveLicense({
|
|
441
|
+
license: licenseKey,
|
|
442
|
+
email: result.email,
|
|
443
|
+
name: result.name,
|
|
444
|
+
activatedAt: new Date().toISOString(),
|
|
445
|
+
contentVersion: VERSION,
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
console.log(`
|
|
449
|
+
════════════════════════════════════════════════════════════
|
|
450
|
+
License activated successfully!
|
|
451
|
+
════════════════════════════════════════════════════════════
|
|
452
|
+
|
|
453
|
+
You can now run:
|
|
454
|
+
|
|
455
|
+
super kickoff # Initialize in current project
|
|
456
|
+
super powers # See available skills
|
|
457
|
+
|
|
458
|
+
════════════════════════════════════════════════════════════
|
|
459
|
+
`);
|
|
460
|
+
} finally {
|
|
461
|
+
rl.close();
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// requireLicense - delegated to lib/licensing module
|
|
466
|
+
async function requireLicense() {
|
|
467
|
+
return licensing ? licensing.requireLicense(VERSION) : process.exit(1);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// ============================================
|
|
471
|
+
// SKILL FILE MANAGEMENT
|
|
472
|
+
// ============================================
|
|
473
|
+
// Functions for reading and parsing skill definition files.
|
|
474
|
+
// Skills are markdown files in src/content/skills/ that define
|
|
475
|
+
// AI assistant behaviors, triggers, and code patterns.
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Get all skill files from the source directory
|
|
479
|
+
*
|
|
480
|
+
* Reads all .md files from the skills directory and returns their metadata.
|
|
481
|
+
* Each skill file contains:
|
|
482
|
+
* - Trigger keywords that activate the skill
|
|
483
|
+
* - Identity/role description for the AI
|
|
484
|
+
* - Mandatory rules and constraints
|
|
485
|
+
* - Code examples and patterns
|
|
486
|
+
*
|
|
487
|
+
* @returns {Array<{name: string, path: string, content: string}>} Array of skill objects
|
|
488
|
+
*/
|
|
489
|
+
function getSkillFiles() {
|
|
490
|
+
return loadSkills({
|
|
491
|
+
packageDir: PACKAGE_DIR,
|
|
492
|
+
contentCacheDir: CONTENT_CACHE_DIR,
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Extract skill metadata from markdown content
|
|
498
|
+
* Delegates to generators module if available
|
|
499
|
+
*/
|
|
500
|
+
function parseSkillMetadata(content) {
|
|
501
|
+
if (generators && generators.parseSkillMetadata) {
|
|
502
|
+
return generators.parseSkillMetadata(content);
|
|
503
|
+
}
|
|
504
|
+
// Fallback for when module not loaded
|
|
505
|
+
const metadata = { title: '', triggers: [], identity: '' };
|
|
506
|
+
const titleMatch = content.match(/^#\s+(.+)/m);
|
|
507
|
+
if (titleMatch) metadata.title = titleMatch[1];
|
|
508
|
+
return metadata;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// ============================================
|
|
512
|
+
// PROJECT INITIALIZATION
|
|
513
|
+
// ============================================
|
|
514
|
+
// Functions for setting up BI Agent Superpowers in a user's project.
|
|
515
|
+
// This involves generating tool-specific config files and saving preferences.
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Initialize project with interactive prompts (super kickoff)
|
|
519
|
+
*
|
|
520
|
+
* This is the main setup wizard that:
|
|
521
|
+
* 1. Validates the user's license
|
|
522
|
+
* 2. Prompts for which AI tools to configure
|
|
523
|
+
* 3. Generates config files for each selected tool
|
|
524
|
+
* 4. Creates a symlink to the content cache for easy access
|
|
525
|
+
* 5. Saves the selected tools to .bi-superpowers.json
|
|
526
|
+
*
|
|
527
|
+
* Supports --dry-run flag to preview changes without writing files.
|
|
528
|
+
*
|
|
529
|
+
* @param {string[]} args - Command line arguments
|
|
530
|
+
* @param {string} [args[0]] - Target directory (defaults to cwd)
|
|
531
|
+
*/
|
|
532
|
+
async function initProject(args) {
|
|
533
|
+
const dryRun = hasDryRunFlag(args);
|
|
534
|
+
const cleanArgs = removeDryRunFlag(args);
|
|
535
|
+
const targetDir = cleanArgs[0] ? path.resolve(cleanArgs[0]) : process.cwd();
|
|
536
|
+
|
|
537
|
+
// Require valid license
|
|
538
|
+
await requireLicense();
|
|
539
|
+
|
|
540
|
+
const skills = getSkillFiles();
|
|
541
|
+
|
|
542
|
+
console.log(`
|
|
543
|
+
BI Agent Superpowers v${VERSION}
|
|
544
|
+
================================
|
|
545
|
+
Claude Code Plugin Setup
|
|
546
|
+
|
|
547
|
+
Initializing in: ${targetDir}
|
|
548
|
+
Skills available: ${skills.length}
|
|
549
|
+
`);
|
|
550
|
+
|
|
551
|
+
// Show dry-run notice
|
|
552
|
+
if (dryRun) {
|
|
553
|
+
if (tui) {
|
|
554
|
+
tui.dryRunNotice();
|
|
555
|
+
} else {
|
|
556
|
+
console.log('══════════════════════════════════════');
|
|
557
|
+
console.log(' DRY RUN MODE');
|
|
558
|
+
console.log(' No files will be created or modified');
|
|
559
|
+
console.log('══════════════════════════════════════\n');
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const selectedTools = [...DEFAULT_TOOLS];
|
|
564
|
+
|
|
565
|
+
console.log('Plugin output:');
|
|
566
|
+
console.log(' • .claude-plugin/plugin.json');
|
|
567
|
+
console.log(' • .mcp.json');
|
|
568
|
+
console.log(` • commands/ (${COMMAND_COUNT} slash commands)`);
|
|
569
|
+
console.log(` • skills/ (${TOTAL_SKILL_COUNT} SKILL.md files)\n`);
|
|
570
|
+
|
|
571
|
+
if (dryRun) {
|
|
572
|
+
console.log('[DRY RUN] Would create the following files:\n');
|
|
573
|
+
previewGeneration(targetDir, selectedTools, skills);
|
|
574
|
+
previewProjectConfigJson(targetDir);
|
|
575
|
+
console.log('\nRun without --dry-run to apply changes.');
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Save selected tools to config
|
|
580
|
+
saveToolConfig(targetDir, selectedTools);
|
|
581
|
+
|
|
582
|
+
// Ensure project-level config.json exists (used as AI preferences/context)
|
|
583
|
+
ensureProjectConfigJson(targetDir);
|
|
584
|
+
|
|
585
|
+
// Create library symlink used by generated plugin files
|
|
586
|
+
createSymlink(targetDir);
|
|
587
|
+
|
|
588
|
+
// Generate configs for selected tools
|
|
589
|
+
console.log('');
|
|
590
|
+
for (const tool of selectedTools) {
|
|
591
|
+
await generateForTool(tool, targetDir, skills);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
showCompletionMessage(targetDir, selectedTools, skills.length);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Sync project - regenerate configs without prompts (super recharge)
|
|
599
|
+
*
|
|
600
|
+
* Regenerates the Claude Code plugin and any configured legacy adapters.
|
|
601
|
+
* Uses the saved tool preferences from .bi-superpowers.json.
|
|
602
|
+
*
|
|
603
|
+
* Use this command after:
|
|
604
|
+
* - Editing skill files in src/content/skills/
|
|
605
|
+
* - Updating the package to a new version
|
|
606
|
+
* - Adding new AI tools to your project
|
|
607
|
+
*
|
|
608
|
+
* Supports --dry-run flag to preview changes without writing files.
|
|
609
|
+
*
|
|
610
|
+
* @param {string[]} args - Command line arguments
|
|
611
|
+
* @param {string} [args[0]] - Target directory (defaults to cwd)
|
|
612
|
+
*/
|
|
613
|
+
async function syncProject(args) {
|
|
614
|
+
const dryRun = hasDryRunFlag(args);
|
|
615
|
+
const cleanArgs = removeDryRunFlag(args);
|
|
616
|
+
const targetDir = cleanArgs[0] ? path.resolve(cleanArgs[0]) : process.cwd();
|
|
617
|
+
|
|
618
|
+
// Require valid license
|
|
619
|
+
await requireLicense();
|
|
620
|
+
|
|
621
|
+
const skills = getSkillFiles();
|
|
622
|
+
|
|
623
|
+
console.log(`
|
|
624
|
+
BI Agent Superpowers - Sync
|
|
625
|
+
===========================
|
|
626
|
+
Regenerating configs from ${skills.length} skills...
|
|
627
|
+
`);
|
|
628
|
+
|
|
629
|
+
// Show dry-run notice
|
|
630
|
+
if (dryRun) {
|
|
631
|
+
if (tui) {
|
|
632
|
+
tui.dryRunNotice();
|
|
633
|
+
} else {
|
|
634
|
+
console.log('══════════════════════════════════════');
|
|
635
|
+
console.log(' DRY RUN MODE');
|
|
636
|
+
console.log(' No files will be created or modified');
|
|
637
|
+
console.log('══════════════════════════════════════\n');
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// Read saved config or default to plugin only
|
|
642
|
+
const config = loadToolConfig(targetDir);
|
|
643
|
+
const selectedTools = ensurePluginTool(config.tools || [...DEFAULT_TOOLS]);
|
|
644
|
+
|
|
645
|
+
if (dryRun) {
|
|
646
|
+
// Preview what would be regenerated
|
|
647
|
+
console.log('[DRY RUN] Would regenerate the following files:\n');
|
|
648
|
+
previewGeneration(targetDir, selectedTools, skills);
|
|
649
|
+
console.log('\nRun without --dry-run to apply changes.');
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
for (const tool of selectedTools) {
|
|
654
|
+
await generateForTool(tool, targetDir, skills);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
console.log(`
|
|
658
|
+
Done! Plugin regenerated for: ${selectedTools.map((t) => AI_TOOLS[t].name).join(', ')}
|
|
659
|
+
|
|
660
|
+
If you modified skills in src/content/skills/,
|
|
661
|
+
your Claude Code plugin is now updated.
|
|
662
|
+
|
|
663
|
+
Tip: Run 'super build-desktop' to rebuild the Claude Desktop extension.
|
|
664
|
+
`);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Preview what files would be generated (for dry-run mode)
|
|
669
|
+
* Delegates to the generators module
|
|
670
|
+
*/
|
|
671
|
+
function previewGeneration(targetDir, tools, skills) {
|
|
672
|
+
if (generators) {
|
|
673
|
+
generators.previewGeneration(targetDir, tools, skills, CONFIG_FILE);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Save tool configuration to project directory
|
|
679
|
+
* @param {string} targetDir - Project directory path
|
|
680
|
+
* @param {string[]} tools - Array of selected AI tool IDs
|
|
681
|
+
*/
|
|
682
|
+
function ensurePluginTool(tools = []) {
|
|
683
|
+
const normalized = Array.from(new Set((tools || []).filter(Boolean)));
|
|
684
|
+
if (!normalized.includes('claude-plugin')) {
|
|
685
|
+
normalized.unshift('claude-plugin');
|
|
686
|
+
}
|
|
687
|
+
return normalized;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Resolve generation options for a target directory.
|
|
692
|
+
*
|
|
693
|
+
* @param {string} targetDir - Target project directory
|
|
694
|
+
* @returns {Object} Options passed into generators
|
|
695
|
+
*/
|
|
696
|
+
function getGenerationOptions(targetDir) {
|
|
697
|
+
const usePluginRootLauncher = path.resolve(targetDir) === PACKAGE_DIR;
|
|
698
|
+
const libraryPrefix = fs.existsSync(path.join(targetDir, 'library'))
|
|
699
|
+
? 'library'
|
|
700
|
+
: `${SYMLINK_NAME}/library`;
|
|
701
|
+
|
|
702
|
+
return {
|
|
703
|
+
packageDir: PACKAGE_DIR,
|
|
704
|
+
version: VERSION,
|
|
705
|
+
usePluginRootLauncher,
|
|
706
|
+
libraryPrefix,
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
function saveToolConfig(targetDir, tools) {
|
|
711
|
+
const configPath = path.join(targetDir, CONFIG_FILE);
|
|
712
|
+
const normalizedTools = ensurePluginTool(tools);
|
|
713
|
+
const config = {
|
|
714
|
+
tools: normalizedTools,
|
|
715
|
+
plugin: {
|
|
716
|
+
name: 'bi-superpowers',
|
|
717
|
+
enabled: true,
|
|
718
|
+
},
|
|
719
|
+
legacyTools: normalizedTools.filter((tool) => tool !== 'claude-plugin'),
|
|
720
|
+
version: VERSION,
|
|
721
|
+
lastSync: new Date().toISOString(),
|
|
722
|
+
};
|
|
723
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* Preview project-level config.json creation (for dry-run mode)
|
|
728
|
+
* This file is used by AI assistants as preferences/context, not by the CLI runtime.
|
|
729
|
+
* @param {string} targetDir - Project directory path
|
|
730
|
+
*/
|
|
731
|
+
function previewProjectConfigJson(targetDir) {
|
|
732
|
+
const projectConfigPath = path.join(targetDir, 'config.json');
|
|
733
|
+
if (fs.existsSync(projectConfigPath)) {
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
if (tui) {
|
|
738
|
+
tui.info(`Would create: ${tui.formatPath(projectConfigPath)}`);
|
|
739
|
+
} else {
|
|
740
|
+
console.log(`[DRY RUN] Would create: ${projectConfigPath}`);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Ensure project-level config.json exists
|
|
746
|
+
* Copies the package template config.json into the project directory if missing.
|
|
747
|
+
* @param {string} targetDir - Project directory path
|
|
748
|
+
* @returns {{created: boolean, path: string, reason?: string, error?: string}}
|
|
749
|
+
*/
|
|
750
|
+
function ensureProjectConfigJson(targetDir) {
|
|
751
|
+
const projectConfigPath = path.join(targetDir, 'config.json');
|
|
752
|
+
if (fs.existsSync(projectConfigPath)) {
|
|
753
|
+
return { created: false, path: projectConfigPath, reason: 'already-exists' };
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
const templatePath = path.join(PACKAGE_DIR, 'config.json');
|
|
757
|
+
if (!fs.existsSync(templatePath)) {
|
|
758
|
+
if (process.env.DEBUG === 'true') {
|
|
759
|
+
console.error(`[DEBUG] Missing config.json template at: ${templatePath}`);
|
|
760
|
+
}
|
|
761
|
+
return { created: false, path: projectConfigPath, reason: 'template-missing' };
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
try {
|
|
765
|
+
fs.copyFileSync(templatePath, projectConfigPath);
|
|
766
|
+
return { created: true, path: projectConfigPath };
|
|
767
|
+
} catch (e) {
|
|
768
|
+
if (process.env.DEBUG === 'true') {
|
|
769
|
+
console.error(`[DEBUG] Failed to create config.json: ${e.message}`);
|
|
770
|
+
}
|
|
771
|
+
return { created: false, path: projectConfigPath, reason: 'copy-failed', error: e.message };
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* Load tool configuration from project directory
|
|
777
|
+
* @param {string} targetDir - Project directory path
|
|
778
|
+
* @returns {Object} Configuration object or empty object if not found
|
|
779
|
+
*/
|
|
780
|
+
function loadToolConfig(targetDir) {
|
|
781
|
+
const configPath = path.join(targetDir, CONFIG_FILE);
|
|
782
|
+
if (fs.existsSync(configPath)) {
|
|
783
|
+
try {
|
|
784
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
785
|
+
config.tools = ensurePluginTool(config.tools || []);
|
|
786
|
+
config.legacyTools = config.tools.filter((tool) => tool !== 'claude-plugin');
|
|
787
|
+
if (!config.plugin) {
|
|
788
|
+
config.plugin = {
|
|
789
|
+
name: 'bi-superpowers',
|
|
790
|
+
enabled: true,
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
return config;
|
|
794
|
+
} catch (e) {
|
|
795
|
+
return {};
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
return {
|
|
799
|
+
tools: [...DEFAULT_TOOLS],
|
|
800
|
+
legacyTools: [],
|
|
801
|
+
plugin: {
|
|
802
|
+
name: 'bi-superpowers',
|
|
803
|
+
enabled: true,
|
|
804
|
+
},
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Generate config for a specific AI tool
|
|
810
|
+
* Delegates to the tool-specific generator from lib/generators module
|
|
811
|
+
*/
|
|
812
|
+
async function generateForTool(tool, targetDir, skills) {
|
|
813
|
+
if (generators) {
|
|
814
|
+
await generators.generateForTool(tool, targetDir, skills, getGenerationOptions(targetDir));
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
/**
|
|
819
|
+
* Create symlink to content cache directory for easy access to library
|
|
820
|
+
*/
|
|
821
|
+
function createSymlink(targetDir) {
|
|
822
|
+
if (generators) {
|
|
823
|
+
generators.createSymlink(targetDir, CONTENT_CACHE_DIR, SYMLINK_NAME);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
function showCompletionMessage(targetDir, tools, skillCount) {
|
|
828
|
+
console.log(`
|
|
829
|
+
════════════════════════════════════════════════════════════
|
|
830
|
+
BI Agent Superpowers configured successfully!
|
|
831
|
+
════════════════════════════════════════════════════════════
|
|
832
|
+
|
|
833
|
+
Skills: ${skillCount} skills generated
|
|
834
|
+
Library: ${LIBRARY_DIR}
|
|
835
|
+
|
|
836
|
+
────────────────────────────────────────────────────────────
|
|
837
|
+
CLAUDE CODE / 1CODE.DEV
|
|
838
|
+
────────────────────────────────────────────────────────────
|
|
839
|
+
|
|
840
|
+
Plugin files:
|
|
841
|
+
${path.join(targetDir, '.claude-plugin', 'plugin.json')}
|
|
842
|
+
${path.join(targetDir, '.mcp.json')}
|
|
843
|
+
${path.join(targetDir, 'commands')}/ (${COMMAND_COUNT} slash commands)
|
|
844
|
+
${path.join(targetDir, 'skills')}/ (${skillCount} SKILL.md)
|
|
845
|
+
|
|
846
|
+
To run with Claude Code:
|
|
847
|
+
|
|
848
|
+
claude --plugin-dir ${targetDir}
|
|
849
|
+
|
|
850
|
+
────────────────────────────────────────────────────────────
|
|
851
|
+
CLAUDE DESKTOP
|
|
852
|
+
────────────────────────────────────────────────────────────
|
|
853
|
+
|
|
854
|
+
To build the Desktop extension:
|
|
855
|
+
|
|
856
|
+
super build-desktop
|
|
857
|
+
|
|
858
|
+
Then double-click bi-superpowers.mcpb to install.
|
|
859
|
+
|
|
860
|
+
────────────────────────────────────────────────────────────
|
|
861
|
+
|
|
862
|
+
Regenerate after changes: super recharge
|
|
863
|
+
Free models (OpenRouter): See docs/openrouter-free-models.md
|
|
864
|
+
|
|
865
|
+
════════════════════════════════════════════════════════════
|
|
866
|
+
`);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Update the package to the latest version using detected package manager
|
|
871
|
+
*/
|
|
872
|
+
function updatePackage() {
|
|
873
|
+
console.log(`Updating ${PACKAGE_NAME}...\n`);
|
|
874
|
+
|
|
875
|
+
try {
|
|
876
|
+
const userAgent = process.env.npm_config_user_agent || '';
|
|
877
|
+
let pm = 'npm';
|
|
878
|
+
if (userAgent.includes('pnpm')) pm = 'pnpm';
|
|
879
|
+
else if (userAgent.includes('yarn')) pm = 'yarn';
|
|
880
|
+
else if (userAgent.includes('bun')) pm = 'bun';
|
|
881
|
+
|
|
882
|
+
const cmd =
|
|
883
|
+
pm === 'yarn'
|
|
884
|
+
? `yarn global add ${PACKAGE_NAME}@latest`
|
|
885
|
+
: `${pm} install -g ${PACKAGE_NAME}@latest`;
|
|
886
|
+
|
|
887
|
+
console.log(`Running: ${cmd}\n`);
|
|
888
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
889
|
+
console.log('\n✓ Update complete!');
|
|
890
|
+
} catch (error) {
|
|
891
|
+
console.error('Update failed:', error.message);
|
|
892
|
+
console.log(`\nTry manually: npm install -g ${PACKAGE_NAME}@latest`);
|
|
893
|
+
process.exit(1);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
function listAgents() {
|
|
898
|
+
const skills = getSkillFiles();
|
|
899
|
+
const license = loadLicense();
|
|
900
|
+
const contentInstalled = isContentInstalled();
|
|
901
|
+
|
|
902
|
+
console.log(`
|
|
903
|
+
BI Agent Superpowers - Skills & Resources
|
|
904
|
+
=========================================
|
|
905
|
+
Single Source of Truth: ${skills.length} skills
|
|
906
|
+
License: ${license ? `Active (${license.email})` : 'Not activated'}
|
|
907
|
+
Content: ${contentInstalled ? 'Installed' : 'Not installed (run "bi-superpowers unlock")'}
|
|
908
|
+
`);
|
|
909
|
+
|
|
910
|
+
if (!contentInstalled) {
|
|
911
|
+
console.log('⚠ Premium content not installed. Run "bi-superpowers unlock" first.\n');
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
console.log('Skills (source content for the plugin and optional adapters):');
|
|
916
|
+
for (const skill of skills) {
|
|
917
|
+
const meta = parseSkillMetadata(skill.content);
|
|
918
|
+
console.log(` /${skill.name.padEnd(20)} ${meta.title || ''}`);
|
|
919
|
+
}
|
|
920
|
+
console.log('');
|
|
921
|
+
|
|
922
|
+
// List snippets
|
|
923
|
+
const snippetsDir = path.join(LIBRARY_DIR, 'snippets');
|
|
924
|
+
if (fs.existsSync(snippetsDir)) {
|
|
925
|
+
console.log('Snippets:');
|
|
926
|
+
fs.readdirSync(snippetsDir).forEach((category) => {
|
|
927
|
+
const categoryPath = path.join(snippetsDir, category);
|
|
928
|
+
try {
|
|
929
|
+
if (fs.statSync(categoryPath).isDirectory()) {
|
|
930
|
+
const count = fs.readdirSync(categoryPath).filter((f) => f.endsWith('.md')).length;
|
|
931
|
+
console.log(` 📝 ${category} (${count} patterns)`);
|
|
932
|
+
}
|
|
933
|
+
} catch (e) {
|
|
934
|
+
// Skip directories that can't be read
|
|
935
|
+
}
|
|
936
|
+
});
|
|
937
|
+
console.log('');
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
// List themes
|
|
941
|
+
const themesDir = path.join(LIBRARY_DIR, 'themes', 'power-bi');
|
|
942
|
+
if (fs.existsSync(themesDir)) {
|
|
943
|
+
console.log('Themes:');
|
|
944
|
+
fs.readdirSync(themesDir).forEach((file) => {
|
|
945
|
+
if (file.endsWith('.json')) {
|
|
946
|
+
console.log(` 🎨 ${file.replace('.json', '')}`);
|
|
947
|
+
}
|
|
948
|
+
});
|
|
949
|
+
console.log('');
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
console.log('Supported AI Tools:');
|
|
953
|
+
Object.entries(AI_TOOLS).forEach(([, config]) => {
|
|
954
|
+
console.log(` • ${config.name}`);
|
|
955
|
+
});
|
|
956
|
+
console.log('');
|
|
957
|
+
|
|
958
|
+
console.log("Run 'bi-superpowers recharge' to regenerate configs after editing skills.");
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
// ============================================
|
|
962
|
+
// COMMAND WRAPPERS
|
|
963
|
+
// ============================================
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* Get configuration object for commands
|
|
967
|
+
*/
|
|
968
|
+
function getCommandConfig() {
|
|
969
|
+
return {
|
|
970
|
+
skillsDir: SKILLS_DIR,
|
|
971
|
+
libraryDir: LIBRARY_DIR,
|
|
972
|
+
contentCacheDir: CONTENT_CACHE_DIR,
|
|
973
|
+
packageDir: PACKAGE_DIR,
|
|
974
|
+
version: VERSION,
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
/**
|
|
979
|
+
* Create a command wrapper with error handling
|
|
980
|
+
* Factory pattern to reduce boilerplate in command handlers
|
|
981
|
+
*
|
|
982
|
+
* @param {Function|null} commandModule - The command module function
|
|
983
|
+
* @param {string} commandName - Display name for error messages
|
|
984
|
+
* @returns {Function} Wrapped command handler
|
|
985
|
+
*/
|
|
986
|
+
function createCommandWrapper(commandModule, commandName) {
|
|
987
|
+
return (args) => {
|
|
988
|
+
if (!commandModule) {
|
|
989
|
+
console.error(`${commandName} command not available. Try reinstalling the package.`);
|
|
990
|
+
process.exit(1);
|
|
991
|
+
}
|
|
992
|
+
commandModule(args, getCommandConfig());
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
// Command wrappers using factory pattern
|
|
997
|
+
const runSearch = createCommandWrapper(searchCommand, 'Search');
|
|
998
|
+
const runLint = createCommandWrapper(lintCommand, 'Lint');
|
|
999
|
+
const runDiff = createCommandWrapper(diffCommand, 'Diff');
|
|
1000
|
+
const runMcpSetup = createCommandWrapper(mcpSetupCommand, 'MCP setup');
|
|
1001
|
+
const runSetup = createCommandWrapper(setupCommand, 'Setup');
|
|
1002
|
+
const runAdd = createCommandWrapper(addCommand, 'Add');
|
|
1003
|
+
const runPull = createCommandWrapper(pullCommand, 'Pull');
|
|
1004
|
+
const runPush = createCommandWrapper(pushCommand, 'Push');
|
|
1005
|
+
const runSyncSource = createCommandWrapper(syncSourceCommand, 'Sync-source');
|
|
1006
|
+
const runSyncProfile = createCommandWrapper(syncProfileCommand, 'Sync-profile');
|
|
1007
|
+
const runChangelog = createCommandWrapper(changelogCommand, 'Changelog');
|
|
1008
|
+
const runBuildDesktop = createCommandWrapper(buildDesktopCommand, 'Build Desktop');
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* Run watch command (special case - needs additional context)
|
|
1012
|
+
*/
|
|
1013
|
+
function runWatch(args) {
|
|
1014
|
+
if (!watchCommand) {
|
|
1015
|
+
console.error('Watch command not available. Try reinstalling the package.');
|
|
1016
|
+
process.exit(1);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
// Create a reference to sync function for watch to use
|
|
1020
|
+
const cliModule = {
|
|
1021
|
+
syncProjectInternal: (targetDir, tools) => {
|
|
1022
|
+
const skills = getSkillFiles();
|
|
1023
|
+
for (const tool of tools) {
|
|
1024
|
+
const config = AI_TOOLS[tool];
|
|
1025
|
+
if (config && config.generate) {
|
|
1026
|
+
config.generate(targetDir, skills, { packageDir: PACKAGE_DIR });
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
},
|
|
1030
|
+
};
|
|
1031
|
+
|
|
1032
|
+
watchCommand(args, getCommandConfig(), cliModule);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
/**
|
|
1036
|
+
* Check if --dry-run flag is present in args
|
|
1037
|
+
*/
|
|
1038
|
+
function hasDryRunFlag(args) {
|
|
1039
|
+
return args.includes('--dry-run') || args.includes('-n');
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Remove --dry-run flag from args
|
|
1044
|
+
*/
|
|
1045
|
+
function removeDryRunFlag(args) {
|
|
1046
|
+
return args.filter((a) => a !== '--dry-run' && a !== '-n');
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
// ============================================
|
|
1050
|
+
// EXPORT FOR INTERNAL USE
|
|
1051
|
+
// ============================================
|
|
1052
|
+
|
|
1053
|
+
module.exports = {
|
|
1054
|
+
getSkillFiles,
|
|
1055
|
+
loadToolConfig,
|
|
1056
|
+
saveToolConfig,
|
|
1057
|
+
AI_TOOLS,
|
|
1058
|
+
SKILLS_DIR,
|
|
1059
|
+
LIBRARY_DIR,
|
|
1060
|
+
CONTENT_CACHE_DIR,
|
|
1061
|
+
VERSION,
|
|
1062
|
+
};
|
|
1063
|
+
|
|
1064
|
+
main();
|