@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/.documentation/commands.html +8 -8
- package/.documentation/efcore.html +13 -13
- package/.documentation/index.html +7 -7
- package/.documentation/installation.html +62 -121
- package/README.md +27 -49
- package/dist/index.js +126 -33
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/scripts/health-check.sh +167 -0
- package/scripts/postinstall.js +18 -0
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
|
|
112865
|
+
"Available skills in Claude Code:",
|
|
112866
112866
|
"",
|
|
112867
112867
|
source_default.bold("GitFlow:"),
|
|
112868
|
-
` ${source_default.cyan("/gitflow")}
|
|
112869
|
-
` ${source_default.cyan("/gitflow
|
|
112870
|
-
` ${source_default.cyan("/gitflow
|
|
112871
|
-
` ${source_default.cyan("/gitflow
|
|
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")}
|
|
112875
|
-
` ${source_default.cyan("/
|
|
112876
|
-
` ${source_default.cyan("/
|
|
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")}
|
|
112879
|
+
` ${source_default.cyan("/business-analyse")} - Full BA workflow`,
|
|
112880
112880
|
"",
|
|
112881
112881
|
source_default.bold("EF Core:"),
|
|
112882
|
-
` ${source_default.cyan("/efcore")}
|
|
112883
|
-
` ${source_default.cyan("/efcore
|
|
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")}
|
|
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
|
-
|
|
116654
|
-
|
|
116655
|
-
|
|
116656
|
-
|
|
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("
|
|
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
|
|
116718
|
-
const projectName =
|
|
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:
|
|
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:
|
|
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);
|