@atlashub/smartstack-cli 1.26.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`);
@@ -115905,7 +115963,7 @@ app.Run();
115905
115963
  }
115906
115964
  async function createConfigFiles(config, dryRun) {
115907
115965
  const { name } = config;
115908
- 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));
115909
115967
  const projectName = (0, import_path4.basename)(name);
115910
115968
  if (dryRun) {
115911
115969
  logger.info("[DRY RUN] Would create configuration files");
@@ -116304,7 +116362,7 @@ Generated with [SmartStack CLI](https://atlashub.io/products/smartstack-cli)
116304
116362
  }
116305
116363
  async function createFrontendStructure(config, dryRun) {
116306
116364
  const { name } = config;
116307
- 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));
116308
116366
  const projectName = (0, import_path4.basename)(name);
116309
116367
  const webDir = (0, import_path4.join)(projectDir, "web", `${projectName.toLowerCase()}-web`);
116310
116368
  logger.info("Creating React frontend structure...");
@@ -116649,13 +116707,21 @@ Thumbs.db
116649
116707
  }
116650
116708
  async function initializeGit(config, dryRun) {
116651
116709
  const { name } = config;
116652
- const projectDir = (0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(process.cwd(), name);
116653
- logger.info("Initializing Git repository...");
116654
- execCommand("git init", projectDir, dryRun);
116655
- execCommand("git add .", projectDir, dryRun);
116656
- 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
+ }
116657
116723
  }
116658
- 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)").option("--preview", "Use preview/prerelease versions (NuGet --prerelease + npm @next)").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) => {
116659
116725
  logger.header("SmartStack Project Initialization");
116660
116726
  if (!options.skipMcpCheck) {
116661
116727
  logger.info("Checking MCP servers...");
@@ -116714,8 +116780,37 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
116714
116780
  logger.error(".NET SDK not found. Please install .NET 10.0 or later.");
116715
116781
  process.exit(1);
116716
116782
  }
116717
- const projectDir = (0, import_path4.isAbsolute)(name) ? name : (0, import_path4.join)(process.cwd(), name);
116718
- 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
+ }
116719
116814
  const validation = validateCSharpNamespace(projectName);
116720
116815
  if (!validation.valid) {
116721
116816
  logger.error(`Invalid project name: ${validation.error}`);
@@ -116724,17 +116819,14 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
116724
116819
  }
116725
116820
  process.exit(1);
116726
116821
  }
116727
- if (await import_fs_extra3.default.pathExists(projectDir)) {
116728
- logger.error(`Directory '${projectDir}' already exists.`);
116729
- process.exit(1);
116730
- }
116731
116822
  let config;
116732
116823
  if (options.yes) {
116733
116824
  config = {
116734
- name,
116735
- nameLower: name.toLowerCase(),
116825
+ name: projectName,
116826
+ nameLower: projectName.toLowerCase(),
116736
116827
  database: "sqlserver",
116737
116828
  preview: options.preview ?? false,
116829
+ projectDir: inPlace ? projectDir : void 0,
116738
116830
  multiTenant: {
116739
116831
  enabled: options.multiTenant ?? true,
116740
116832
  enableB2C: options.b2c ?? true,
@@ -116774,10 +116866,11 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
116774
116866
  }
116775
116867
  ]);
116776
116868
  config = {
116777
- name,
116778
- nameLower: name.toLowerCase(),
116869
+ name: projectName,
116870
+ nameLower: projectName.toLowerCase(),
116779
116871
  database: "sqlserver",
116780
116872
  preview: options.preview ?? false,
116873
+ projectDir: inPlace ? projectDir : void 0,
116781
116874
  multiTenant: {
116782
116875
  enabled: answers.multiTenantEnabled ?? true,
116783
116876
  enableB2C: answers.enableB2C ?? true,
@@ -116802,7 +116895,7 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
116802
116895
  }
116803
116896
  console.log();
116804
116897
  try {
116805
- if (!dryRun) {
116898
+ if (!dryRun && !inPlace) {
116806
116899
  await import_fs_extra3.default.ensureDir(projectDir);
116807
116900
  }
116808
116901
  await createBackendStructure(config, dryRun);