@atlashub/smartstack-cli 2.1.0 → 2.3.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 (38) hide show
  1. package/.documentation/business-analyse.html +1503 -1058
  2. package/dist/index.js +92 -55
  3. package/dist/index.js.map +1 -1
  4. package/package.json +10 -7
  5. package/templates/agents/ba-reader.md +250 -0
  6. package/templates/agents/ba-writer.md +210 -0
  7. package/templates/agents/docs-context-reader.md +51 -33
  8. package/templates/skills/_shared.md +2 -0
  9. package/templates/skills/business-analyse/SKILL.md +120 -108
  10. package/templates/skills/business-analyse/_shared.md +136 -146
  11. package/templates/skills/business-analyse/patterns/suggestion-catalog.md +478 -0
  12. package/templates/skills/business-analyse/questionnaire/01-context.md +3 -15
  13. package/templates/skills/business-analyse/questionnaire/03-scope.md +7 -7
  14. package/templates/skills/business-analyse/questionnaire/08-performance.md +7 -21
  15. package/templates/skills/business-analyse/questionnaire/09-constraints.md +0 -13
  16. package/templates/skills/business-analyse/questionnaire/10-documentation.md +0 -13
  17. package/templates/skills/business-analyse/questionnaire/12-migration.md +1 -1
  18. package/templates/skills/business-analyse/questionnaire.md +72 -76
  19. package/templates/skills/business-analyse/react/components.md +317 -154
  20. package/templates/skills/business-analyse/react/i18n-template.md +167 -106
  21. package/templates/skills/business-analyse/react/schema.md +474 -107
  22. package/templates/skills/business-analyse/schemas/feature-schema.json +860 -0
  23. package/templates/skills/business-analyse/steps/step-00-init.md +395 -285
  24. package/templates/skills/business-analyse/steps/step-01-analyse.md +523 -0
  25. package/templates/skills/business-analyse/steps/step-02-specify.md +899 -0
  26. package/templates/skills/business-analyse/steps/step-03-validate.md +1009 -0
  27. package/templates/skills/business-analyse/steps/step-04-handoff.md +1802 -0
  28. package/templates/skills/business-analyse/templates/tpl-handoff.md +49 -64
  29. package/templates/skills/business-analyse/steps/step-01-discover.md +0 -737
  30. package/templates/skills/business-analyse/steps/step-02-analyse.md +0 -299
  31. package/templates/skills/business-analyse/steps/step-03-specify.md +0 -472
  32. package/templates/skills/business-analyse/steps/step-04-validate.md +0 -335
  33. package/templates/skills/business-analyse/steps/step-05-handoff.md +0 -741
  34. package/templates/skills/business-analyse/steps/step-06-doc-html.md +0 -320
  35. package/templates/skills/business-analyse/templates/00-context.md +0 -105
  36. package/templates/skills/business-analyse/templates/tpl-brd.md +0 -97
  37. package/templates/skills/business-analyse/templates/tpl-discovery.md +0 -78
  38. package/templates/skills/business-analyse/tracking/change-template.md +0 -30
package/dist/index.js CHANGED
@@ -112215,6 +112215,10 @@ function getPackageVersion() {
112215
112215
  return "0.0.0";
112216
112216
  }
112217
112217
  }
112218
+ function processTemplateVariables(content, version2) {
112219
+ const sanitized = version2.replace(/[^0-9a-zA-Z.\-+]/g, "");
112220
+ return content.replace(/\{\{SMARTSTACK_VERSION\}\}/g, sanitized);
112221
+ }
112218
112222
  var DEFAULT_PLUGINS = [];
112219
112223
  function getClaudeDir(global3) {
112220
112224
  if (global3) {
@@ -112250,6 +112254,7 @@ async function installCommands(options = {}) {
112250
112254
  };
112251
112255
  logger.info(`Installing to: ${claudeDir}`);
112252
112256
  const dirsToInstall = installAll ? INSTALL_DIRS : INSTALL_DIRS.filter((d) => components.includes(d));
112257
+ const version2 = getPackageVersion();
112253
112258
  for (const dir of dirsToInstall) {
112254
112259
  const sourceDir = (0, import_path.join)(TEMPLATES_DIR, dir);
112255
112260
  const targetDir = (0, import_path.join)(claudeDir, dir);
@@ -112270,7 +112275,13 @@ async function installCommands(options = {}) {
112270
112275
  continue;
112271
112276
  }
112272
112277
  await import_fs_extra.default.ensureDir((0, import_path.dirname)(dest));
112273
- await import_fs_extra.default.copy(src, dest, { overwrite: options.force });
112278
+ if (file.endsWith(".md")) {
112279
+ const content = await import_fs_extra.default.readFile(src, "utf-8");
112280
+ const processed = processTemplateVariables(content, version2);
112281
+ await import_fs_extra.default.writeFile(dest, processed, "utf-8");
112282
+ } else {
112283
+ await import_fs_extra.default.copy(src, dest, { overwrite: options.force });
112284
+ }
112274
112285
  result.installed++;
112275
112286
  result.installedFiles.push(relativePath);
112276
112287
  if (file.endsWith(".md") && !file.includes("/")) {
@@ -125340,6 +125351,13 @@ var import_bcryptjs = __toESM(require_bcryptjs());
125340
125351
  var import_fs4 = require("fs");
125341
125352
  var import_path9 = require("path");
125342
125353
  var import_child_process8 = require("child_process");
125354
+ function tryLoadNativeDriver() {
125355
+ try {
125356
+ return require("mssql/msnodesqlv8");
125357
+ } catch {
125358
+ return null;
125359
+ }
125360
+ }
125343
125361
  var DEFAULT_CONFIG = {
125344
125362
  schema: "core",
125345
125363
  usersTable: "auth_Users",
@@ -125428,15 +125446,12 @@ async function promptSqlCredentials() {
125428
125446
  }
125429
125447
  function detectSmartStackApp() {
125430
125448
  const cwd = process.cwd();
125431
- const configPath = (0, import_path9.join)(cwd, ".smartstack", "config.json");
125432
- if ((0, import_fs4.existsSync)(configPath)) {
125433
- const srcDir = (0, import_path9.join)(cwd, "src");
125434
- if ((0, import_fs4.existsSync)(srcDir)) {
125435
- const folders = (0, import_fs4.readdirSync)(srcDir);
125436
- const apiFolder = folders.find((f) => f.endsWith(".Api"));
125437
- if (apiFolder) {
125438
- return (0, import_path9.join)(srcDir, apiFolder);
125439
- }
125449
+ const srcDir = (0, import_path9.join)(cwd, "src");
125450
+ if ((0, import_fs4.existsSync)(srcDir)) {
125451
+ const folders = (0, import_fs4.readdirSync)(srcDir);
125452
+ const apiFolder = folders.find((f) => f.endsWith(".Api"));
125453
+ if (apiFolder) {
125454
+ return (0, import_path9.join)(srcDir, apiFolder);
125440
125455
  }
125441
125456
  }
125442
125457
  const possiblePaths = [
@@ -125550,53 +125565,77 @@ adminCommand.command("reset").description("Reset the localAdmin account password
125550
125565
  console.log(source_default.green("\u2550".repeat(60)));
125551
125566
  console.log();
125552
125567
  };
125568
+ const resetViaMssql = async (sqlModule) => {
125569
+ spinner.text = "Connected. Checking account...";
125570
+ const checkResult = await sqlModule.query`
125571
+ SELECT COUNT(*) as count
125572
+ FROM [core].[auth_Users]
125573
+ WHERE Email = ${adminEmail}
125574
+ `;
125575
+ const exists = checkResult.recordset[0].count > 0;
125576
+ if (!exists) {
125577
+ spinner.fail(`Account ${source_default.yellow(adminEmail)} does not exist.`);
125578
+ logger.error("Cannot reset password for non-existent account.");
125579
+ logger.info("Use the application seeding or AdminTool to create the account first.");
125580
+ await sqlModule.close();
125581
+ process.exit(1);
125582
+ }
125583
+ spinner.text = "Generating new password...";
125584
+ const newPassword = generatePassword();
125585
+ const passwordHash = await import_bcryptjs.default.hash(newPassword, 10);
125586
+ spinner.text = "Updating password...";
125587
+ await sqlModule.query`
125588
+ UPDATE [core].[auth_Users]
125589
+ SET PasswordHash = ${passwordHash},
125590
+ UpdatedAt = ${/* @__PURE__ */ new Date()}
125591
+ WHERE Email = ${adminEmail}
125592
+ `;
125593
+ await sqlModule.close();
125594
+ spinner.succeed("Password reset successfully!");
125595
+ displayPasswordResult(adminEmail, newPassword);
125596
+ };
125597
+ const tryWithSqlCmd = async () => {
125598
+ try {
125599
+ await resetViaSqlCmd();
125600
+ } catch (winAuthError) {
125601
+ if (isLoginFailure(winAuthError)) {
125602
+ spinner.fail("Windows Authentication failed");
125603
+ console.log();
125604
+ const sqlCreds = await promptSqlCredentials();
125605
+ if (!sqlCreds) {
125606
+ process.exit(1);
125607
+ }
125608
+ spinner.start("Retrying with SQL Server credentials...");
125609
+ await resetViaSqlCmd(sqlCreds);
125610
+ } else {
125611
+ throw winAuthError;
125612
+ }
125613
+ }
125614
+ };
125553
125615
  try {
125554
125616
  if (connInfo.useWindowsAuth) {
125555
- try {
125556
- await resetViaSqlCmd();
125557
- } catch (winAuthError) {
125558
- if (isLoginFailure(winAuthError)) {
125559
- spinner.fail("Windows Authentication failed");
125560
- console.log();
125561
- const sqlCreds = await promptSqlCredentials();
125562
- if (!sqlCreds) {
125563
- process.exit(1);
125617
+ const nativeDriver = tryLoadNativeDriver();
125618
+ let nativeConnected = false;
125619
+ if (nativeDriver) {
125620
+ try {
125621
+ spinner.text = "Connecting with Windows Authentication...";
125622
+ await nativeDriver.connect(connectionString);
125623
+ nativeConnected = true;
125624
+ await resetViaMssql(nativeDriver);
125625
+ } catch (nativeError) {
125626
+ if (nativeConnected) throw nativeError;
125627
+ try {
125628
+ await nativeDriver.close();
125629
+ } catch {
125564
125630
  }
125565
- spinner.start("Retrying with SQL Server credentials...");
125566
- await resetViaSqlCmd(sqlCreds);
125567
- } else {
125568
- throw winAuthError;
125569
125631
  }
125570
125632
  }
125633
+ if (!nativeConnected) {
125634
+ await tryWithSqlCmd();
125635
+ }
125571
125636
  } else {
125572
125637
  await import_mssql.default.connect(connectionString);
125573
- spinner.text = "Connected. Checking account...";
125574
- const checkResult = await import_mssql.default.query`
125575
- SELECT COUNT(*) as count
125576
- FROM [core].[auth_Users]
125577
- WHERE Email = ${adminEmail}
125578
- `;
125579
- const exists = checkResult.recordset[0].count > 0;
125580
- if (!exists) {
125581
- spinner.fail(`Account ${source_default.yellow(adminEmail)} does not exist.`);
125582
- logger.error("Cannot reset password for non-existent account.");
125583
- logger.info("Use the application seeding or AdminTool to create the account first.");
125584
- await import_mssql.default.close();
125585
- process.exit(1);
125586
- }
125587
- spinner.text = "Generating new password...";
125588
- const newPassword = generatePassword();
125589
- const passwordHash = await import_bcryptjs.default.hash(newPassword, 10);
125590
- spinner.text = "Updating password...";
125591
- await import_mssql.default.query`
125592
- UPDATE [core].[auth_Users]
125593
- SET PasswordHash = ${passwordHash},
125594
- UpdatedAt = ${/* @__PURE__ */ new Date()}
125595
- WHERE Email = ${adminEmail}
125596
- `;
125597
- await import_mssql.default.close();
125598
- spinner.succeed("Password reset successfully!");
125599
- displayPasswordResult(adminEmail, newPassword);
125638
+ await resetViaMssql(import_mssql.default);
125600
125639
  }
125601
125640
  } catch (error) {
125602
125641
  spinner.fail("Failed to reset password");
@@ -125614,11 +125653,9 @@ adminCommand.command("reset").description("Reset the localAdmin account password
125614
125653
  logger.info(` 3. Or use: ${source_default.cyan('ss admin reset --connection "Server=...;Database=...;User Id=sa;Password=..."')}`);
125615
125654
  }
125616
125655
  }
125617
- if (!connInfo.useWindowsAuth) {
125618
- try {
125619
- await import_mssql.default.close();
125620
- } catch {
125621
- }
125656
+ try {
125657
+ await import_mssql.default.close();
125658
+ } catch {
125622
125659
  }
125623
125660
  process.exit(1);
125624
125661
  }