@atlashub/smartstack-cli 1.25.0 → 1.27.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/dist/index.js CHANGED
@@ -112862,29 +112862,28 @@ var installCommand = new Command("install").alias("i").description("Install Smar
112862
112862
  `Files installed: ${source_default.cyan(result.installed)}`,
112863
112863
  `Files skipped: ${source_default.yellow(result.skipped)} (use --force to overwrite)`,
112864
112864
  "",
112865
- "Available commands in Claude Code:",
112865
+ "Available skills in Claude Code:",
112866
112866
  "",
112867
112867
  source_default.bold("GitFlow:"),
112868
- ` ${source_default.cyan("/gitflow")} - Full GitFlow workflow`,
112869
- ` ${source_default.cyan("/gitflow:1-init")} - Initialize GitFlow`,
112870
- ` ${source_default.cyan("/gitflow:2-status")} - Show status`,
112871
- ` ${source_default.cyan("/gitflow:3-commit")} - Smart commit`,
112868
+ ` ${source_default.cyan("/gitflow")} - Full GitFlow workflow`,
112869
+ ` ${source_default.cyan("/gitflow start")} - Start feature/release/hotfix`,
112870
+ ` ${source_default.cyan("/gitflow commit")} - Smart commit`,
112871
+ ` ${source_default.cyan("/gitflow finish")} - Finish and merge`,
112872
112872
  "",
112873
112873
  source_default.bold("Development:"),
112874
- ` ${source_default.cyan("/apex")} - APEX methodology`,
112875
- ` ${source_default.cyan("/epct")} - Explore-Plan-Code-Test`,
112876
- ` ${source_default.cyan("/debug")} - Systematic debugging`,
112874
+ ` ${source_default.cyan("/apex")} - APEX methodology`,
112875
+ ` ${source_default.cyan("/debug")} - Systematic debugging`,
112876
+ ` ${source_default.cyan("/refactor")} - Code refactoring`,
112877
112877
  "",
112878
112878
  source_default.bold("Business Analysis:"),
112879
- ` ${source_default.cyan("/business-analyse")} - Full BA workflow`,
112879
+ ` ${source_default.cyan("/business-analyse")} - Full BA workflow`,
112880
112880
  "",
112881
112881
  source_default.bold("EF Core:"),
112882
- ` ${source_default.cyan("/efcore")} - EF Core orchestrator`,
112883
- ` ${source_default.cyan("/efcore:migration")} - Migration management`,
112882
+ ` ${source_default.cyan("/efcore")} - EF Core orchestrator`,
112883
+ ` ${source_default.cyan("/efcore migration")} - Migration management`,
112884
112884
  "",
112885
112885
  source_default.bold("Ralph Loop:"),
112886
- ` ${source_default.cyan("/ralph-loop")} - Start iterative loop`,
112887
- ` ${source_default.cyan("/cancel-ralph")} - Cancel active loop`,
112886
+ ` ${source_default.cyan("/ralph-loop")} - Start iterative loop`,
112888
112887
  ...pluginSummary
112889
112888
  ];
112890
112889
  logger.box(summary, "success");
@@ -115575,6 +115574,65 @@ function validateCSharpNamespace(name) {
115575
115574
  }
115576
115575
  return { valid: true };
115577
115576
  }
115577
+ async function detectProjectContext(name, here) {
115578
+ const cwd = process.cwd();
115579
+ if (name && !here) {
115580
+ const projectDir = (0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(cwd, name);
115581
+ const projectName = (0, import_path4.basename)(name);
115582
+ return { projectName, projectDir, inPlace: false };
115583
+ }
115584
+ const parentDir = (0, import_path4.dirname)(cwd);
115585
+ const currentFolderName = (0, import_path4.basename)(cwd);
115586
+ let detectedName;
115587
+ const gitflowConfigPath = (0, import_path4.join)(cwd, ".claude", "gitflow", "config.json");
115588
+ if (await import_fs_extra3.default.pathExists(gitflowConfigPath)) {
115589
+ try {
115590
+ const config = await import_fs_extra3.default.readJson(gitflowConfigPath);
115591
+ if (config.repository?.name) {
115592
+ detectedName = config.repository.name;
115593
+ }
115594
+ } catch {
115595
+ }
115596
+ }
115597
+ if (!detectedName) {
115598
+ const bareDir = (0, import_path4.join)(parentDir, ".bare");
115599
+ if (await import_fs_extra3.default.pathExists(bareDir)) {
115600
+ detectedName = (0, import_path4.basename)(parentDir);
115601
+ }
115602
+ }
115603
+ if (!detectedName) {
115604
+ const worktreePatterns = /^(\d+-)?(?:main|master|develop|development)$/i;
115605
+ if (worktreePatterns.test(currentFolderName)) {
115606
+ detectedName = (0, import_path4.basename)(parentDir);
115607
+ } else {
115608
+ detectedName = currentFolderName;
115609
+ }
115610
+ }
115611
+ return {
115612
+ projectName: detectedName,
115613
+ projectDir: cwd,
115614
+ inPlace: true
115615
+ };
115616
+ }
115617
+ async function validateInPlaceDirectory(projectDir) {
115618
+ if (await import_fs_extra3.default.pathExists((0, import_path4.join)(projectDir, ".smartstack", "config.json"))) {
115619
+ return 'SmartStack is already initialized in this directory. Use "ss update" to update.';
115620
+ }
115621
+ const files = await import_fs_extra3.default.readdir(projectDir);
115622
+ const hasSln = files.some((f) => f.endsWith(".sln"));
115623
+ if (hasSln) {
115624
+ return "A .NET solution already exists in this directory. Cannot initialize SmartStack here.";
115625
+ }
115626
+ const srcDir = (0, import_path4.join)(projectDir, "src");
115627
+ if (await import_fs_extra3.default.pathExists(srcDir)) {
115628
+ const srcFiles = await import_fs_extra3.default.readdir(srcDir);
115629
+ const hasCsproj = srcFiles.some((f) => f.endsWith(".csproj") || import_fs_extra3.default.statSync((0, import_path4.join)(srcDir, f)).isDirectory());
115630
+ if (hasCsproj) {
115631
+ return "A src/ directory with projects already exists. Cannot initialize SmartStack here.";
115632
+ }
115633
+ }
115634
+ return void 0;
115635
+ }
115578
115636
  async function checkMcpServers() {
115579
115637
  const result = {
115580
115638
  smartstack: { installed: false },
@@ -115713,7 +115771,7 @@ async function createDualDbContextStructure(projectDir, projectName, dryRun) {
115713
115771
  }
115714
115772
  async function createBackendStructure(config, dryRun) {
115715
115773
  const { name } = config;
115716
- const projectDir = (0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(process.cwd(), name);
115774
+ const projectDir = config.projectDir ?? ((0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(process.cwd(), name));
115717
115775
  const projectName = (0, import_path4.basename)(name);
115718
115776
  const srcDir = (0, import_path4.join)(projectDir, "src");
115719
115777
  const slnPath = (0, import_path4.join)(projectDir, `${projectName}.sln`);
@@ -115837,9 +115895,10 @@ EndGlobal
115837
115895
  ]
115838
115896
  }
115839
115897
  ];
115898
+ const prereleaseFlag = config.preview ? " --prerelease" : "";
115840
115899
  for (const { project, packages } of nugetPackages) {
115841
115900
  for (const pkg2 of packages) {
115842
- execCommand(`dotnet add "${(0, import_path4.join)(srcDir, project)}" package ${pkg2}`, void 0, dryRun);
115901
+ execCommand(`dotnet add "${(0, import_path4.join)(srcDir, project)}" package ${pkg2}${prereleaseFlag}`, void 0, dryRun);
115843
115902
  }
115844
115903
  }
115845
115904
  if (!dryRun) {
@@ -115904,7 +115963,7 @@ app.Run();
115904
115963
  }
115905
115964
  async function createConfigFiles(config, dryRun) {
115906
115965
  const { name } = config;
115907
- const projectDir = (0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(process.cwd(), name);
115966
+ const projectDir = config.projectDir ?? ((0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(process.cwd(), name));
115908
115967
  const projectName = (0, import_path4.basename)(name);
115909
115968
  if (dryRun) {
115910
115969
  logger.info("[DRY RUN] Would create configuration files");
@@ -116303,7 +116362,7 @@ Generated with [SmartStack CLI](https://atlashub.io/products/smartstack-cli)
116303
116362
  }
116304
116363
  async function createFrontendStructure(config, dryRun) {
116305
116364
  const { name } = config;
116306
- const projectDir = (0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(process.cwd(), name);
116365
+ const projectDir = config.projectDir ?? ((0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(process.cwd(), name));
116307
116366
  const projectName = (0, import_path4.basename)(name);
116308
116367
  const webDir = (0, import_path4.join)(projectDir, "web", `${projectName.toLowerCase()}-web`);
116309
116368
  logger.info("Creating React frontend structure...");
@@ -116320,6 +116379,7 @@ async function createFrontendStructure(config, dryRun) {
116320
116379
  await import_fs_extra3.default.ensureDir((0, import_path4.join)(webDir, "src", "types"));
116321
116380
  await import_fs_extra3.default.ensureDir((0, import_path4.join)(webDir, "src", "i18n"));
116322
116381
  await import_fs_extra3.default.ensureDir((0, import_path4.join)(webDir, "public"));
116382
+ const smartstackNpmTag = config.preview ? "next" : "latest";
116323
116383
  const packageJson = {
116324
116384
  name: `${projectName.toLowerCase()}-web`,
116325
116385
  private: true,
@@ -116334,7 +116394,7 @@ async function createFrontendStructure(config, dryRun) {
116334
116394
  preview: "vite preview"
116335
116395
  },
116336
116396
  dependencies: {
116337
- "@atlashub/smartstack": "latest",
116397
+ "@atlashub/smartstack": smartstackNpmTag,
116338
116398
  "@microsoft/signalr": "latest",
116339
116399
  "@tailwindcss/vite": "latest",
116340
116400
  axios: "latest",
@@ -116647,13 +116707,21 @@ Thumbs.db
116647
116707
  }
116648
116708
  async function initializeGit(config, dryRun) {
116649
116709
  const { name } = config;
116650
- const projectDir = (0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(process.cwd(), name);
116651
- logger.info("Initializing Git repository...");
116652
- execCommand("git init", projectDir, dryRun);
116653
- execCommand("git add .", projectDir, dryRun);
116654
- execCommand('git commit -m "chore: initial SmartStack project setup"', projectDir, dryRun);
116710
+ const projectDir = config.projectDir ?? ((0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(process.cwd(), name));
116711
+ const gitDir = (0, import_path4.join)(projectDir, ".git");
116712
+ const isGitInitialized = await import_fs_extra3.default.pathExists(gitDir);
116713
+ if (isGitInitialized) {
116714
+ logger.info("Git repository already initialized, adding SmartStack files...");
116715
+ execCommand("git add .", projectDir, dryRun);
116716
+ execCommand('git commit -m "feat: initialize SmartStack project structure"', projectDir, dryRun);
116717
+ } else {
116718
+ logger.info("Initializing Git repository...");
116719
+ execCommand("git init", projectDir, dryRun);
116720
+ execCommand("git add .", projectDir, dryRun);
116721
+ execCommand('git commit -m "chore: initial SmartStack project setup"', projectDir, dryRun);
116722
+ }
116655
116723
  }
116656
- var initCommand = new Command("init").description("Initialize a new SmartStack project").argument("<name>", "Project name").option("--dry-run", "Show what would be created without actually creating").option("-y, --yes", "Skip prompts and use defaults").option("--skip-mcp-check", "Skip MCP servers verification").option("--multi-tenant", "Enable multi-tenant mode").option("--b2c", "Enable B2C (user tenant management)").action(async (name, options) => {
116724
+ var initCommand = new Command("init").description("Initialize a new SmartStack project").argument("[name]", "Project name (optional, uses current folder if not provided)").option("--dry-run", "Show what would be created without actually creating").option("-y, --yes", "Skip prompts and use defaults").option("--skip-mcp-check", "Skip MCP servers verification").option("--multi-tenant", "Enable multi-tenant mode").option("--b2c", "Enable B2C (user tenant management)").option("--preview", "Use preview/prerelease versions (NuGet --prerelease + npm @next)").option("--here", "Initialize in current directory (use folder name as project name)").action(async (name, options) => {
116657
116725
  logger.header("SmartStack Project Initialization");
116658
116726
  if (!options.skipMcpCheck) {
116659
116727
  logger.info("Checking MCP servers...");
@@ -116712,8 +116780,37 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
116712
116780
  logger.error(".NET SDK not found. Please install .NET 10.0 or later.");
116713
116781
  process.exit(1);
116714
116782
  }
116715
- const projectDir = (0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(process.cwd(), name);
116716
- const projectName = (0, import_path4.basename)(name);
116783
+ const context = await detectProjectContext(name, options.here ?? false);
116784
+ const { projectName, projectDir, inPlace } = context;
116785
+ if (inPlace) {
116786
+ logger.info(`Detected project: ${source_default.cyan(projectName)}`);
116787
+ logger.info(`Directory: ${source_default.cyan(projectDir)}`);
116788
+ const inPlaceError = await validateInPlaceDirectory(projectDir);
116789
+ if (inPlaceError) {
116790
+ logger.error(inPlaceError);
116791
+ process.exit(1);
116792
+ }
116793
+ if (!options.yes) {
116794
+ const { confirm } = await lib_default.prompt([
116795
+ {
116796
+ type: "confirm",
116797
+ name: "confirm",
116798
+ message: `Initialize SmartStack project "${projectName}" in current directory?`,
116799
+ default: true
116800
+ }
116801
+ ]);
116802
+ if (!confirm) {
116803
+ logger.info("Cancelled by user.");
116804
+ process.exit(0);
116805
+ }
116806
+ }
116807
+ } else {
116808
+ if (await import_fs_extra3.default.pathExists(projectDir)) {
116809
+ logger.error(`Directory '${projectDir}' already exists.`);
116810
+ logger.info(`Tip: Use ${source_default.cyan("--here")} to initialize in the current directory instead.`);
116811
+ process.exit(1);
116812
+ }
116813
+ }
116717
116814
  const validation = validateCSharpNamespace(projectName);
116718
116815
  if (!validation.valid) {
116719
116816
  logger.error(`Invalid project name: ${validation.error}`);
@@ -116722,16 +116819,14 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
116722
116819
  }
116723
116820
  process.exit(1);
116724
116821
  }
116725
- if (await import_fs_extra3.default.pathExists(projectDir)) {
116726
- logger.error(`Directory '${projectDir}' already exists.`);
116727
- process.exit(1);
116728
- }
116729
116822
  let config;
116730
116823
  if (options.yes) {
116731
116824
  config = {
116732
- name,
116733
- nameLower: name.toLowerCase(),
116825
+ name: projectName,
116826
+ nameLower: projectName.toLowerCase(),
116734
116827
  database: "sqlserver",
116828
+ preview: options.preview ?? false,
116829
+ projectDir: inPlace ? projectDir : void 0,
116735
116830
  multiTenant: {
116736
116831
  enabled: options.multiTenant ?? true,
116737
116832
  enableB2C: options.b2c ?? true,
@@ -116771,9 +116866,11 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
116771
116866
  }
116772
116867
  ]);
116773
116868
  config = {
116774
- name,
116775
- nameLower: name.toLowerCase(),
116869
+ name: projectName,
116870
+ nameLower: projectName.toLowerCase(),
116776
116871
  database: "sqlserver",
116872
+ preview: options.preview ?? false,
116873
+ projectDir: inPlace ? projectDir : void 0,
116777
116874
  multiTenant: {
116778
116875
  enabled: answers.multiTenantEnabled ?? true,
116779
116876
  enableB2C: answers.enableB2C ?? true,
@@ -116790,6 +116887,7 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
116790
116887
  console.log();
116791
116888
  logger.info(`Project: ${source_default.cyan(config.name)}`);
116792
116889
  logger.info(`Database: ${source_default.cyan("SQL Server")}`);
116890
+ logger.info(`Preview mode: ${config.preview ? source_default.yellow("Enabled (prerelease)") : source_default.gray("Disabled (stable)")}`);
116793
116891
  logger.info(`Multi-Tenant: ${config.multiTenant.enabled ? source_default.green("Enabled") : source_default.gray("Disabled")}`);
116794
116892
  if (config.multiTenant.enabled) {
116795
116893
  logger.info(` B2C (User Tenants): ${config.multiTenant.enableB2C ? source_default.green("Enabled") : source_default.gray("Disabled")}`);
@@ -116797,7 +116895,7 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
116797
116895
  }
116798
116896
  console.log();
116799
116897
  try {
116800
- if (!dryRun) {
116898
+ if (!dryRun && !inPlace) {
116801
116899
  await import_fs_extra3.default.ensureDir(projectDir);
116802
116900
  }
116803
116901
  await createBackendStructure(config, dryRun);