@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.
Files changed (193) hide show
  1. package/.claude-plugin/plugin.json +8 -0
  2. package/.mcp.json +25 -0
  3. package/AGENTS.md +244 -0
  4. package/CHANGELOG.md +265 -0
  5. package/LICENSE +21 -0
  6. package/README.md +211 -0
  7. package/bin/build-plugin.js +30 -0
  8. package/bin/cli.js +1064 -0
  9. package/bin/commands/add.js +533 -0
  10. package/bin/commands/add.test.js +77 -0
  11. package/bin/commands/build-desktop.js +166 -0
  12. package/bin/commands/changelog.js +443 -0
  13. package/bin/commands/diff.js +325 -0
  14. package/bin/commands/lint.js +419 -0
  15. package/bin/commands/lint.test.js +103 -0
  16. package/bin/commands/mcp-setup.js +246 -0
  17. package/bin/commands/pull.js +287 -0
  18. package/bin/commands/pull.test.js +36 -0
  19. package/bin/commands/push.js +231 -0
  20. package/bin/commands/push.test.js +14 -0
  21. package/bin/commands/search.js +344 -0
  22. package/bin/commands/search.test.js +115 -0
  23. package/bin/commands/setup.js +545 -0
  24. package/bin/commands/setup.test.js +46 -0
  25. package/bin/commands/sync-profile.js +405 -0
  26. package/bin/commands/sync-profile.test.js +14 -0
  27. package/bin/commands/sync-source.js +418 -0
  28. package/bin/commands/sync-source.test.js +14 -0
  29. package/bin/commands/watch.js +206 -0
  30. package/bin/lib/generators/claude-plugin.js +266 -0
  31. package/bin/lib/generators/claude-plugin.test.js +110 -0
  32. package/bin/lib/generators/index.js +116 -0
  33. package/bin/lib/generators/shared.js +282 -0
  34. package/bin/lib/licensing/index.js +35 -0
  35. package/bin/lib/licensing/storage.js +364 -0
  36. package/bin/lib/licensing/storage.test.js +55 -0
  37. package/bin/lib/licensing/validator.js +213 -0
  38. package/bin/lib/licensing/validator.test.js +137 -0
  39. package/bin/lib/microsoft-mcp.js +176 -0
  40. package/bin/lib/microsoft-mcp.test.js +106 -0
  41. package/bin/lib/skills.js +84 -0
  42. package/bin/mcp/powerbi-modeling-launcher.js +38 -0
  43. package/bin/postinstall.js +44 -0
  44. package/bin/utils/errors.js +159 -0
  45. package/bin/utils/git.js +298 -0
  46. package/bin/utils/logger.js +142 -0
  47. package/bin/utils/mcp-detect.js +274 -0
  48. package/bin/utils/mcp-detect.test.js +105 -0
  49. package/bin/utils/pbix.js +305 -0
  50. package/bin/utils/pbix.test.js +37 -0
  51. package/bin/utils/profiles.js +312 -0
  52. package/bin/utils/projects.js +168 -0
  53. package/bin/utils/readline.js +206 -0
  54. package/bin/utils/readline.test.js +47 -0
  55. package/bin/utils/tui.js +314 -0
  56. package/bin/utils/tui.test.js +127 -0
  57. package/commands/contributions.md +265 -0
  58. package/commands/data-model-design.md +468 -0
  59. package/commands/dax-doctor.md +248 -0
  60. package/commands/fabric-scripts.md +452 -0
  61. package/commands/migration-assistant.md +290 -0
  62. package/commands/model-documenter.md +242 -0
  63. package/commands/pbi-connect.md +239 -0
  64. package/commands/project-kickoff.md +905 -0
  65. package/commands/report-layout.md +296 -0
  66. package/commands/rls-design.md +533 -0
  67. package/commands/theme-tweaker.md +624 -0
  68. package/config.example.json +23 -0
  69. package/config.json +23 -0
  70. package/desktop-extension/manifest.json +37 -0
  71. package/desktop-extension/package.json +10 -0
  72. package/desktop-extension/server.js +95 -0
  73. package/docs/openrouter-free-models.md +92 -0
  74. package/library/examples/README.md +151 -0
  75. package/library/examples/finance-reporting/README.md +351 -0
  76. package/library/examples/finance-reporting/data-model.md +267 -0
  77. package/library/examples/finance-reporting/measures.dax +557 -0
  78. package/library/examples/hr-analytics/README.md +371 -0
  79. package/library/examples/hr-analytics/data-model.md +315 -0
  80. package/library/examples/hr-analytics/measures.dax +460 -0
  81. package/library/examples/marketing-analytics/README.md +37 -0
  82. package/library/examples/marketing-analytics/data-model.md +62 -0
  83. package/library/examples/marketing-analytics/measures.dax +110 -0
  84. package/library/examples/retail-analytics/README.md +439 -0
  85. package/library/examples/retail-analytics/data-model.md +288 -0
  86. package/library/examples/retail-analytics/measures.dax +481 -0
  87. package/library/examples/supply-chain/README.md +37 -0
  88. package/library/examples/supply-chain/data-model.md +69 -0
  89. package/library/examples/supply-chain/measures.dax +77 -0
  90. package/library/examples/udf-library/README.md +228 -0
  91. package/library/examples/udf-library/functions.dax +571 -0
  92. package/library/snippets/dax/README.md +292 -0
  93. package/library/snippets/dax/business-domains.md +576 -0
  94. package/library/snippets/dax/calculate-patterns.md +276 -0
  95. package/library/snippets/dax/calculation-groups.md +489 -0
  96. package/library/snippets/dax/error-handling.md +495 -0
  97. package/library/snippets/dax/iterators-and-aggregations.md +474 -0
  98. package/library/snippets/dax/kpis-and-metrics.md +293 -0
  99. package/library/snippets/dax/rankings-and-topn.md +235 -0
  100. package/library/snippets/dax/security-patterns.md +413 -0
  101. package/library/snippets/dax/text-and-formatting.md +316 -0
  102. package/library/snippets/dax/time-intelligence.md +196 -0
  103. package/library/snippets/dax/user-defined-functions.md +477 -0
  104. package/library/snippets/dax/virtual-tables.md +546 -0
  105. package/library/snippets/excel-formulas/README.md +84 -0
  106. package/library/snippets/excel-formulas/aggregations.md +330 -0
  107. package/library/snippets/excel-formulas/dates-and-times.md +361 -0
  108. package/library/snippets/excel-formulas/dynamic-arrays.md +314 -0
  109. package/library/snippets/excel-formulas/lookups.md +169 -0
  110. package/library/snippets/excel-formulas/text-functions.md +363 -0
  111. package/library/snippets/governance/naming-conventions.md +97 -0
  112. package/library/snippets/governance/review-checklists.md +107 -0
  113. package/library/snippets/power-query/README.md +389 -0
  114. package/library/snippets/power-query/api-integration.md +707 -0
  115. package/library/snippets/power-query/connections.md +434 -0
  116. package/library/snippets/power-query/data-cleaning.md +298 -0
  117. package/library/snippets/power-query/error-handling.md +526 -0
  118. package/library/snippets/power-query/parameters.md +350 -0
  119. package/library/snippets/power-query/performance.md +506 -0
  120. package/library/snippets/power-query/transformations.md +330 -0
  121. package/library/snippets/report-design/accessibility.md +78 -0
  122. package/library/snippets/report-design/chart-selection.md +54 -0
  123. package/library/snippets/report-design/layout-patterns.md +87 -0
  124. package/library/templates/data-models/README.md +93 -0
  125. package/library/templates/data-models/finance-model.md +627 -0
  126. package/library/templates/data-models/retail-star-schema.md +473 -0
  127. package/library/templates/excel/README.md +83 -0
  128. package/library/templates/excel/budget-tracker.md +432 -0
  129. package/library/templates/excel/data-entry-form.md +533 -0
  130. package/library/templates/power-bi/README.md +72 -0
  131. package/library/templates/power-bi/finance-report.md +449 -0
  132. package/library/templates/power-bi/kpi-scorecard.md +461 -0
  133. package/library/templates/power-bi/sales-dashboard.md +281 -0
  134. package/library/themes/excel/README.md +436 -0
  135. package/library/themes/power-bi/README.md +271 -0
  136. package/library/themes/power-bi/accessible.json +307 -0
  137. package/library/themes/power-bi/bi-superpowers-default.json +858 -0
  138. package/library/themes/power-bi/corporate-blue.json +291 -0
  139. package/library/themes/power-bi/dark-mode.json +291 -0
  140. package/library/themes/power-bi/minimal.json +292 -0
  141. package/library/themes/power-bi/print-friendly.json +309 -0
  142. package/package.json +93 -0
  143. package/skills/contributions/SKILL.md +267 -0
  144. package/skills/data-model-design/SKILL.md +470 -0
  145. package/skills/data-modeling/SKILL.md +254 -0
  146. package/skills/data-quality/SKILL.md +664 -0
  147. package/skills/dax/SKILL.md +708 -0
  148. package/skills/dax-doctor/SKILL.md +250 -0
  149. package/skills/dax-udf/SKILL.md +489 -0
  150. package/skills/deployment/SKILL.md +320 -0
  151. package/skills/excel-formulas/SKILL.md +463 -0
  152. package/skills/fabric-scripts/SKILL.md +454 -0
  153. package/skills/fast-standard/SKILL.md +509 -0
  154. package/skills/governance/SKILL.md +205 -0
  155. package/skills/migration-assistant/SKILL.md +292 -0
  156. package/skills/model-documenter/SKILL.md +244 -0
  157. package/skills/pbi-connect/SKILL.md +241 -0
  158. package/skills/power-query/SKILL.md +406 -0
  159. package/skills/project-kickoff/SKILL.md +907 -0
  160. package/skills/query-performance/SKILL.md +480 -0
  161. package/skills/report-design/SKILL.md +207 -0
  162. package/skills/report-layout/SKILL.md +298 -0
  163. package/skills/rls-design/SKILL.md +535 -0
  164. package/skills/semantic-model/SKILL.md +237 -0
  165. package/skills/testing-validation/SKILL.md +643 -0
  166. package/skills/theme-tweaker/SKILL.md +626 -0
  167. package/src/content/base.md +237 -0
  168. package/src/content/mcp-requirements.json +69 -0
  169. package/src/content/routing.md +203 -0
  170. package/src/content/skills/contributions.md +259 -0
  171. package/src/content/skills/data-model-design.md +462 -0
  172. package/src/content/skills/data-modeling.md +246 -0
  173. package/src/content/skills/data-quality.md +656 -0
  174. package/src/content/skills/dax-doctor.md +242 -0
  175. package/src/content/skills/dax-udf.md +481 -0
  176. package/src/content/skills/dax.md +700 -0
  177. package/src/content/skills/deployment.md +312 -0
  178. package/src/content/skills/excel-formulas.md +455 -0
  179. package/src/content/skills/fabric-scripts.md +446 -0
  180. package/src/content/skills/fast-standard.md +501 -0
  181. package/src/content/skills/governance.md +197 -0
  182. package/src/content/skills/migration-assistant.md +284 -0
  183. package/src/content/skills/model-documenter.md +236 -0
  184. package/src/content/skills/pbi-connect.md +233 -0
  185. package/src/content/skills/power-query.md +398 -0
  186. package/src/content/skills/project-kickoff.md +899 -0
  187. package/src/content/skills/query-performance.md +472 -0
  188. package/src/content/skills/report-design.md +199 -0
  189. package/src/content/skills/report-layout.md +290 -0
  190. package/src/content/skills/rls-design.md +527 -0
  191. package/src/content/skills/semantic-model.md +229 -0
  192. package/src/content/skills/testing-validation.md +635 -0
  193. package/src/content/skills/theme-tweaker.md +618 -0
@@ -0,0 +1,545 @@
1
+ /**
2
+ * Setup Command - Onboarding Wizard
3
+ * ==================================
4
+ *
5
+ * Creates the bi-repo structure for multi-project BI version control.
6
+ * This is the first command users run after installing BI Superpowers.
7
+ *
8
+ * Usage:
9
+ * super setup Interactive wizard
10
+ * super setup --path ~/bi-repo Specify location
11
+ * super setup --skip-vscode Don't open VS Code
12
+ *
13
+ * @module commands/setup
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const os = require('os');
19
+ const { spawn } = require('child_process');
20
+
21
+ const git = require('../utils/git');
22
+ const profiles = require('../utils/profiles');
23
+ const rl = require('../utils/readline');
24
+ const { createMcpConfigForFormat } = require('../lib/microsoft-mcp');
25
+
26
+ /**
27
+ * Default repo name
28
+ */
29
+ const DEFAULT_REPO_NAME = 'bi-repo';
30
+
31
+ /**
32
+ * Parse command line arguments
33
+ * @param {string[]} args - CLI arguments
34
+ * @returns {Object} Parsed options
35
+ */
36
+ function parseArgs(args) {
37
+ const options = {
38
+ path: null,
39
+ skipVscode: false,
40
+ help: false,
41
+ };
42
+
43
+ for (let i = 0; i < args.length; i++) {
44
+ const arg = args[i];
45
+
46
+ if (arg === '--path' || arg === '-p') {
47
+ options.path = args[++i];
48
+ } else if (arg === '--skip-vscode') {
49
+ options.skipVscode = true;
50
+ } else if (arg === '--help' || arg === '-h') {
51
+ options.help = true;
52
+ }
53
+ }
54
+
55
+ return options;
56
+ }
57
+
58
+ // Using shared readline utilities from ../utils/readline.js
59
+ const { createReadline, prompt } = rl;
60
+
61
+ /**
62
+ * Show the welcome banner
63
+ */
64
+ function showWelcome() {
65
+ console.log(`
66
+ ╔══════════════════════════════════════════════════════════════╗
67
+ ║ BI Agent Superpowers - Setup Wizard ║
68
+ ╠══════════════════════════════════════════════════════════════╣
69
+ ║ ║
70
+ ║ Vamos a crear tu repositorio de proyectos BI. ║
71
+ ║ ║
72
+ ║ Este repo te permite: ║
73
+ ║ • Versionar todos tus proyectos con Git ║
74
+ ║ • Revertir cambios si algo sale mal ║
75
+ ║ • Mantener tus archivos originales seguros ║
76
+ ║ • Organizar múltiples proyectos en un solo lugar ║
77
+ ║ • Configurar MCPs compartidos para todo el equipo ║
78
+ ║ ║
79
+ ╚══════════════════════════════════════════════════════════════╝
80
+ `);
81
+ }
82
+
83
+ /**
84
+ * Ask user about MCP configuration for the workspace
85
+ */
86
+ async function configureMCPs(rl) {
87
+ console.log('\n─────────────────────────────────────────────────────────────');
88
+ console.log(' Configuración de MCPs (Model Context Protocol)');
89
+ console.log('─────────────────────────────────────────────────────────────\n');
90
+
91
+ console.log('Este repo se crea en modo plugin-first para Claude Code.');
92
+ console.log('Se configurarán por defecto los MCPs oficiales de Microsoft:\n');
93
+ console.log(' • powerbi-remote (HTTP)');
94
+ console.log(' • fabric-mcp-server (npx @microsoft/fabric-mcp@latest)');
95
+ console.log(' • powerbi-modeling-mcp (launcher local para Windows)\n');
96
+ console.log('Nota: el Modeling MCP local sólo funciona en Windows.');
97
+ console.log('En macOS/Linux podrás seguir usando powerbi-remote y Fabric MCP.\n');
98
+
99
+ const answer = await prompt(rl, '¿Continuar con esta configuración recomendada? (S/n): ');
100
+ const accepted = !answer || answer.toLowerCase() === 's' || answer.toLowerCase() === 'y';
101
+
102
+ return {
103
+ pluginFirst: accepted,
104
+ servers: accepted ? ['powerbi-remote', 'fabric-mcp-server', 'powerbi-modeling-mcp'] : [],
105
+ };
106
+ }
107
+
108
+ /**
109
+ * Generate MCP configuration files for AI tools
110
+ */
111
+ function generateMcpConfigs(repoPath, _mcpConfig) {
112
+ if (_mcpConfig && _mcpConfig.pluginFirst === false) {
113
+ console.log(' • Omitido: archivos MCP (puedes ejecutar "bi-superpowers mcp-setup" más tarde)');
114
+ return;
115
+ }
116
+
117
+ const packageDir = path.resolve(__dirname, '..', '..');
118
+ const pluginMcp = createMcpConfigForFormat('plugin', {
119
+ packageDir,
120
+ });
121
+ fs.writeFileSync(path.join(repoPath, '.mcp.json'), JSON.stringify(pluginMcp, null, 2));
122
+ console.log(' ✓ Creado: .mcp.json (MCPs oficiales de Microsoft)');
123
+
124
+ // Create .cursor directory and mcp.json
125
+ const cursorDir = path.join(repoPath, '.cursor');
126
+ if (!fs.existsSync(cursorDir)) {
127
+ fs.mkdirSync(cursorDir, { recursive: true });
128
+ }
129
+
130
+ const cursorMcp = createMcpConfigForFormat('cursor', {
131
+ packageDir,
132
+ });
133
+ fs.writeFileSync(path.join(cursorDir, 'mcp.json'), JSON.stringify(cursorMcp, null, 2));
134
+ console.log(' ✓ Creado: .cursor/mcp.json (MCPs legacy)');
135
+
136
+ // Create .vscode directory and settings.json
137
+ const vscodeDir = path.join(repoPath, '.vscode');
138
+ if (!fs.existsSync(vscodeDir)) {
139
+ fs.mkdirSync(vscodeDir, { recursive: true });
140
+ }
141
+
142
+ const vscodeSettings = createMcpConfigForFormat('vscode', {
143
+ packageDir,
144
+ });
145
+ fs.writeFileSync(
146
+ path.join(vscodeDir, 'mcp-settings.json'),
147
+ JSON.stringify(vscodeSettings, null, 2)
148
+ );
149
+ console.log(' ✓ Creado: .vscode/mcp-settings.json (MCPs legacy)');
150
+ }
151
+
152
+ /**
153
+ * Show help message
154
+ */
155
+ function showHelp() {
156
+ console.log(`
157
+ super setup - Create your BI projects repository
158
+
159
+ Usage:
160
+ super setup Interactive wizard
161
+ super setup --path ~/bi-repo Specify location
162
+ super setup --skip-vscode Don't prompt to open VS Code
163
+
164
+ Options:
165
+ --path, -p <path> Path where to create the repo
166
+ --skip-vscode Skip VS Code setup prompt
167
+ --help, -h Show this help message
168
+
169
+ Examples:
170
+ super setup
171
+ super setup --path "C:/Users/Juan/bi-repo"
172
+ super setup --path ~/Documents/bi-repo --skip-vscode
173
+ `);
174
+ }
175
+
176
+ /**
177
+ * Get suggested repo locations
178
+ */
179
+ function getSuggestedLocations() {
180
+ const home = os.homedir();
181
+ const locations = [
182
+ path.join(home, DEFAULT_REPO_NAME),
183
+ path.join(home, 'Documents', DEFAULT_REPO_NAME),
184
+ ];
185
+
186
+ // Add Desktop on Windows
187
+ if (process.platform === 'win32') {
188
+ locations.push(path.join(home, 'Desktop', DEFAULT_REPO_NAME));
189
+ }
190
+
191
+ return locations;
192
+ }
193
+
194
+ /**
195
+ * Ask user to select repo location
196
+ */
197
+ async function selectRepoLocation(rl) {
198
+ const suggestions = getSuggestedLocations();
199
+
200
+ console.log('\n¿Dónde quieres crear tu carpeta de repositorio?\n');
201
+
202
+ suggestions.forEach((loc, i) => {
203
+ console.log(` ${i + 1}. ${loc}`);
204
+ });
205
+ console.log(` ${suggestions.length + 1}. Otra ubicación (especificar)\n`);
206
+
207
+ const choice = await prompt(rl, `Selecciona (1-${suggestions.length + 1}): `);
208
+ const choiceNum = parseInt(choice, 10);
209
+
210
+ if (choiceNum >= 1 && choiceNum <= suggestions.length) {
211
+ return suggestions[choiceNum - 1];
212
+ } else if (choiceNum === suggestions.length + 1) {
213
+ const customPath = await prompt(rl, '\nEscribe la ruta completa: ');
214
+ return customPath || suggestions[0];
215
+ } else {
216
+ console.log('\nOpción no válida. Usando ubicación recomendada.');
217
+ return suggestions[0];
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Create the repo directory structure
223
+ */
224
+ function createRepoStructure(repoPath, mcpConfig = {}) {
225
+ console.log('\nCreando estructura...\n');
226
+
227
+ // Create main directories
228
+ const dirs = [
229
+ repoPath,
230
+ path.join(repoPath, 'projects'),
231
+ path.join(repoPath, 'standards'),
232
+ path.join(repoPath, 'snippets'),
233
+ ];
234
+
235
+ for (const dir of dirs) {
236
+ if (!fs.existsSync(dir)) {
237
+ fs.mkdirSync(dir, { recursive: true });
238
+ console.log(` ✓ Creado: ${path.relative(repoPath, dir) || path.basename(repoPath)}/`);
239
+ }
240
+ }
241
+
242
+ // Create .gitignore
243
+ const gitignore = `# BI Agent Superpowers - Generated gitignore
244
+
245
+ # Power BI temporary files
246
+ *.pbix.tmp
247
+ *.pbix.lock
248
+
249
+ # Excel temporary files
250
+ ~$*.xlsx
251
+ ~$*.xlsm
252
+
253
+ # OS files
254
+ .DS_Store
255
+ Thumbs.db
256
+
257
+ # IDE
258
+ .vscode/settings.json
259
+ .idea/
260
+
261
+ # Local user config (not versioned)
262
+ .bi-superpowers.json
263
+ `;
264
+
265
+ fs.writeFileSync(path.join(repoPath, '.gitignore'), gitignore);
266
+ console.log(' ✓ Creado: .gitignore');
267
+
268
+ // Create bi-workspace.json (versioned workspace config)
269
+ let workspaceMcpServers = {};
270
+ if (mcpConfig.pluginFirst !== false) {
271
+ workspaceMcpServers = {
272
+ 'powerbi-modeling-mcp': {
273
+ enabled: true,
274
+ description: 'Microsoft Power BI Modeling MCP',
275
+ },
276
+ 'powerbi-remote': {
277
+ enabled: true,
278
+ description: 'Microsoft Power BI Remote MCP',
279
+ },
280
+ 'fabric-mcp-server': {
281
+ enabled: true,
282
+ mode: 'all',
283
+ description: 'Microsoft Fabric MCP Server',
284
+ },
285
+ };
286
+ }
287
+
288
+ const workspaceConfig = {
289
+ version: '3.1',
290
+ created: new Date().toISOString(),
291
+ projects: [],
292
+ mcpServers: workspaceMcpServers,
293
+ plugin: {
294
+ name: 'bi-superpowers',
295
+ pluginFirst: mcpConfig.pluginFirst !== false,
296
+ },
297
+ changelog: {
298
+ enabled: true,
299
+ autoGenerate: true,
300
+ includeInAgentContext: true,
301
+ recentChangesCount: 5,
302
+ },
303
+ };
304
+
305
+ fs.writeFileSync(
306
+ path.join(repoPath, 'bi-workspace.json'),
307
+ JSON.stringify(workspaceConfig, null, 2)
308
+ );
309
+ console.log(' ✓ Creado: bi-workspace.json');
310
+
311
+ // Create README.md
312
+ const readme = `# BI Projects Repository
313
+
314
+ Este repositorio contiene tus proyectos de Business Intelligence versionados con Git.
315
+
316
+ ## Estructura
317
+
318
+ \`\`\`
319
+ bi-repo/
320
+ ├── projects/ # Tus proyectos de BI
321
+ │ └── {proyecto}/
322
+ │ ├── project.json # Configuración y ruta al archivo original
323
+ │ ├── definition/ # TMDL (modelo semántico)
324
+ │ └── queries/ # Power Query (.pq)
325
+ ├── standards/ # Tus standards personalizados
326
+ └── snippets/ # Tus snippets personalizados
327
+ \`\`\`
328
+
329
+ ## Comandos Útiles
330
+
331
+ \`\`\`bash
332
+ # Añadir un proyecto
333
+ super add "ruta/al/archivo.pbix"
334
+
335
+ # Traer cambios del archivo original
336
+ super pull
337
+
338
+ # Ver historial de cambios
339
+ git log --oneline
340
+
341
+ # Revertir a una versión anterior
342
+ git checkout HEAD~1
343
+ super push
344
+ \`\`\`
345
+
346
+ ## Notas
347
+
348
+ - Los archivos originales (.pbix, .xlsx) permanecen en su ubicación original
349
+ - Solo los archivos de texto (TMDL, queries) se versionan aquí
350
+ - Haz commits frecuentes para tener puntos de restauración
351
+
352
+ ---
353
+ Creado con [BI Agent Superpowers](https://github.com/luquimbo/bi-superpowers)
354
+ `;
355
+
356
+ fs.writeFileSync(path.join(repoPath, 'README.md'), readme);
357
+ console.log(' ✓ Creado: README.md');
358
+
359
+ return true;
360
+ }
361
+
362
+ /**
363
+ * Initialize Git repository
364
+ */
365
+ function initializeGit(repoPath) {
366
+ if (!git.isGitInstalled()) {
367
+ console.log('\n⚠ Git no está instalado. Puedes instalarlo después.');
368
+ console.log(' Descarga: https://git-scm.com/downloads');
369
+ return false;
370
+ }
371
+
372
+ if (git.isGitRepo(repoPath)) {
373
+ console.log(' ✓ Git ya inicializado');
374
+ return true;
375
+ }
376
+
377
+ const success = git.initRepo(repoPath);
378
+ if (success) {
379
+ console.log(' ✓ Git inicializado');
380
+
381
+ // Create initial commit
382
+ git.stageFiles(repoPath, '.');
383
+ git.commit(repoPath, 'Initial commit - BI Agent Superpowers repo');
384
+ console.log(' ✓ Commit inicial creado');
385
+
386
+ return true;
387
+ } else {
388
+ console.log(' ⚠ No se pudo inicializar Git');
389
+ return false;
390
+ }
391
+ }
392
+
393
+ /**
394
+ * Prompt to open VS Code
395
+ */
396
+ async function promptVSCode(rl, repoPath, skipVscode) {
397
+ if (skipVscode) {
398
+ return;
399
+ }
400
+
401
+ console.log(`
402
+ Ahora vamos a configurar VS Code:
403
+
404
+ 1. Abre VS Code
405
+ 2. File → Add Folder to Workspace
406
+ 3. Selecciona: ${repoPath}
407
+ `);
408
+
409
+ const openNow = await prompt(rl, '¿Quieres que abra VS Code automáticamente? (s/n): ');
410
+
411
+ if (openNow.toLowerCase() === 's' || openNow.toLowerCase() === 'y') {
412
+ try {
413
+ const platform = process.platform;
414
+
415
+ if (platform === 'darwin') {
416
+ spawn('open', ['-a', 'Visual Studio Code', repoPath], { detached: true, stdio: 'ignore' });
417
+ } else if (platform === 'win32') {
418
+ spawn('code', [repoPath], { detached: true, stdio: 'ignore' });
419
+ } else {
420
+ spawn('code', [repoPath], { detached: true, stdio: 'ignore' });
421
+ }
422
+
423
+ console.log('\n ✓ VS Code abierto');
424
+ } catch (e) {
425
+ console.log('\n ⚠ No se pudo abrir VS Code automáticamente.');
426
+ console.log(' Abre VS Code manualmente y añade la carpeta.');
427
+ }
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Show completion message
433
+ */
434
+ function showCompletion(repoPath) {
435
+ console.log(`
436
+ ════════════════════════════════════════════════════════════════
437
+ ¡Tu repositorio está listo!
438
+ ════════════════════════════════════════════════════════════════
439
+
440
+ Ubicación: ${repoPath}
441
+
442
+ Próximos pasos:
443
+
444
+ 1. Añade tu primer proyecto:
445
+ super add "ruta/a/tu/archivo.pbix"
446
+
447
+ 2. Trabaja en tu proyecto normalmente
448
+
449
+ 3. Trae los cambios al repo:
450
+ super pull
451
+
452
+ 4. Git guarda el historial automáticamente
453
+
454
+ Comandos útiles:
455
+ super add <archivo> Añadir un proyecto
456
+ super pull Traer cambios del original
457
+ super powers Ver skills disponibles
458
+
459
+ ════════════════════════════════════════════════════════════════
460
+ `);
461
+ }
462
+
463
+ /**
464
+ * Main setup command handler
465
+ */
466
+ async function setupCommand(args, _config) {
467
+ const options = parseArgs(args);
468
+
469
+ if (options.help) {
470
+ showHelp();
471
+ return;
472
+ }
473
+
474
+ showWelcome();
475
+
476
+ // Check if repo already exists
477
+ const existingRepo = profiles.getRepoPath();
478
+ if (existingRepo && fs.existsSync(existingRepo)) {
479
+ console.log('Ya tienes un repositorio configurado en:');
480
+ console.log(` ${existingRepo}\n`);
481
+
482
+ const rl = createReadline();
483
+ const proceed = await prompt(rl, '¿Quieres crear uno nuevo? (s/n): ');
484
+
485
+ if (proceed.toLowerCase() !== 's' && proceed.toLowerCase() !== 'y') {
486
+ console.log('\nUsando repositorio existente.');
487
+ rl.close();
488
+ return;
489
+ }
490
+ rl.close();
491
+ }
492
+
493
+ const rl = createReadline();
494
+
495
+ try {
496
+ // Step 1: Select location
497
+ let repoPath;
498
+ if (options.path) {
499
+ repoPath = path.resolve(options.path);
500
+ console.log(`\nUsando ubicación: ${repoPath}`);
501
+ } else {
502
+ repoPath = await selectRepoLocation(rl);
503
+ }
504
+
505
+ // Check if path already exists
506
+ if (fs.existsSync(repoPath)) {
507
+ const contents = fs.readdirSync(repoPath);
508
+ if (contents.length > 0) {
509
+ console.log(`\n⚠ La carpeta ya existe y no está vacía: ${repoPath}`);
510
+ const overwrite = await prompt(rl, '¿Quieres continuar de todos modos? (s/n): ');
511
+
512
+ if (overwrite.toLowerCase() !== 's' && overwrite.toLowerCase() !== 'y') {
513
+ console.log('\nCancelado.');
514
+ return;
515
+ }
516
+ }
517
+ }
518
+
519
+ // Step 2: Configure MCPs for the workspace
520
+ const mcpConfig = await configureMCPs(rl);
521
+
522
+ // Step 3: Create structure with MCP config
523
+ createRepoStructure(repoPath, mcpConfig);
524
+
525
+ // Step 4: Generate MCP config files for AI tools
526
+ generateMcpConfigs(repoPath, mcpConfig);
527
+
528
+ // Step 5: Initialize Git
529
+ initializeGit(repoPath);
530
+
531
+ // Step 4: Save repo path to global config
532
+ profiles.setRepoPath(repoPath);
533
+ console.log(' ✓ Configuración guardada');
534
+
535
+ // Step 5: VS Code setup
536
+ await promptVSCode(rl, repoPath, options.skipVscode);
537
+
538
+ // Done!
539
+ showCompletion(repoPath);
540
+ } finally {
541
+ rl.close();
542
+ }
543
+ }
544
+
545
+ module.exports = setupCommand;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Tests for Setup Command
3
+ * @module commands/setup.test
4
+ */
5
+
6
+ const { test, describe, beforeEach, afterEach, mock } = require('node:test');
7
+ const assert = require('node:assert');
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const os = require('os');
11
+
12
+ // We'll test the parseArgs function and basic structure validation
13
+ // Full integration tests would require mocking readline and git
14
+
15
+ describe('Setup Command', () => {
16
+ test('module exports a function', () => {
17
+ const setupCommand = require('./setup');
18
+ assert.strictEqual(typeof setupCommand, 'function');
19
+ });
20
+
21
+ test('parseArgs handles --path option', () => {
22
+ // Import the module to access internal functions through the export
23
+ // Since parseArgs is not exported, we test through the main command
24
+ // This is a placeholder for when we refactor to export parseArgs
25
+ assert.ok(true, 'Placeholder test - parseArgs is internal');
26
+ });
27
+
28
+ test('parseArgs handles --skip-vscode flag', () => {
29
+ assert.ok(true, 'Placeholder test - parseArgs is internal');
30
+ });
31
+
32
+ test('parseArgs handles --help flag', () => {
33
+ assert.ok(true, 'Placeholder test - parseArgs is internal');
34
+ });
35
+ });
36
+
37
+ describe('Setup Command - Directory Structure', () => {
38
+ test('expected directories are defined', () => {
39
+ // Verify the expected structure would be created
40
+ const expectedDirs = ['projects', 'standards', 'snippets'];
41
+ const expectedFiles = ['.gitignore', '.bi-superpowers.json', 'README.md'];
42
+
43
+ assert.ok(expectedDirs.length === 3);
44
+ assert.ok(expectedFiles.length === 3);
45
+ });
46
+ });