@atlashub/smartstack-cli 4.55.1 → 4.57.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 (23) hide show
  1. package/dist/index.js +28 -10
  2. package/dist/index.js.map +1 -1
  3. package/package.json +1 -1
  4. package/templates/project/Dockerfile.frontend.template +3 -3
  5. package/templates/skills/business-analyse/_shared.md +69 -21
  6. package/templates/skills/business-analyse/references/canonical-json-formats.md +1 -1
  7. package/templates/skills/business-analyse/references/naming-conventions.md +12 -2
  8. package/templates/skills/business-analyse/steps/step-00-init.md +54 -21
  9. package/templates/skills/business-analyse/steps/step-01-cadrage.md +6 -2
  10. package/templates/skills/business-analyse/steps/step-02-structure.md +13 -3
  11. package/templates/skills/business-analyse/steps/step-03-specify.md +14 -1
  12. package/templates/skills/business-analyse/steps/step-04-consolidate.md +3 -1
  13. package/templates/skills/business-analyse-design/steps/step-01-screens.md +12 -1
  14. package/templates/skills/business-analyse-design/steps/step-03-navigation.md +4 -3
  15. package/templates/skills/business-analyse-handoff/steps/step-01-transform.md +2 -2
  16. package/templates/skills/business-analyse-handoff/steps/step-02-export.md +15 -13
  17. package/templates/skills/business-analyse-html/SKILL.md +14 -0
  18. package/templates/skills/business-analyse-html/steps/step-01-collect.md +12 -6
  19. package/templates/skills/business-analyse-html/steps/step-03-render.md +7 -4
  20. package/templates/skills/business-analyse-html/steps/step-04-verify.md +3 -3
  21. package/templates/skills/business-analyse-review/steps/step-00-init.md +7 -2
  22. package/templates/skills/business-analyse-review/steps/step-01-apply.md +6 -7
  23. package/templates/skills/business-analyse-status/SKILL.md +19 -8
package/dist/index.js CHANGED
@@ -116339,6 +116339,12 @@ async function setupMailPitContainer() {
116339
116339
  logger.info(`SMTP server: ${source_default.cyan("localhost:1025")}`);
116340
116340
  logger.info(`Web interface: ${source_default.cyan("http://localhost:8025")}`);
116341
116341
  }
116342
+ function toPascalCase(name) {
116343
+ return name.split(/[-_.\s]+/).filter(Boolean).map((part) => {
116344
+ if (/^\d+$/.test(part)) return part;
116345
+ return part.charAt(0).toUpperCase() + part.slice(1);
116346
+ }).join("");
116347
+ }
116342
116348
  function validateCSharpNamespace(name) {
116343
116349
  if (!name || name.trim().length === 0) {
116344
116350
  return { valid: false, error: "Project name cannot be empty" };
@@ -116349,13 +116355,13 @@ function validateCSharpNamespace(name) {
116349
116355
  return {
116350
116356
  valid: false,
116351
116357
  error: `Project name cannot start with a digit: '${firstChar}'`,
116352
- suggestion: `_${name.replace(/[^a-zA-Z0-9_]/g, "_")}`
116358
+ suggestion: toPascalCase("_" + name)
116353
116359
  };
116354
116360
  }
116355
116361
  return {
116356
116362
  valid: false,
116357
116363
  error: `Project name cannot start with '${firstChar}'`,
116358
- suggestion: name.replace(/[^a-zA-Z0-9_]/g, "_").replace(/^[^a-zA-Z_]+/, "")
116364
+ suggestion: toPascalCase(name)
116359
116365
  };
116360
116366
  }
116361
116367
  const invalidChars = name.match(/[^a-zA-Z0-9_]/g);
@@ -116364,7 +116370,7 @@ function validateCSharpNamespace(name) {
116364
116370
  return {
116365
116371
  valid: false,
116366
116372
  error: `Project name contains invalid characters for C# namespace: ${uniqueInvalid.map((c) => `'${c}'`).join(", ")}`,
116367
- suggestion: name.replace(/[^a-zA-Z0-9_]/g, "_")
116373
+ suggestion: toPascalCase(name)
116368
116374
  };
116369
116375
  }
116370
116376
  const csharpKeywords = [
@@ -116453,6 +116459,14 @@ function validateCSharpNamespace(name) {
116453
116459
  suggestion: `${name}_Project`
116454
116460
  };
116455
116461
  }
116462
+ const pascalVersion = toPascalCase(name);
116463
+ if (pascalVersion !== name) {
116464
+ return {
116465
+ valid: false,
116466
+ error: `Project name "${name}" is not PascalCase`,
116467
+ suggestion: pascalVersion
116468
+ };
116469
+ }
116456
116470
  return { valid: true };
116457
116471
  }
116458
116472
  async function detectProjectContext(name, here) {
@@ -117184,6 +117198,7 @@ ${projectName}/
117184
117198
  \u2502 \u2514\u2500\u2500 ${projectName}.Api/ # Web API controllers and configuration
117185
117199
  \u251C\u2500\u2500 web/
117186
117200
  \u2502 \u2514\u2500\u2500 ${projectName.toLowerCase()}-web/ # React frontend (Vite + TypeScript + Tailwind)
117201
+ \u251C\u2500\u2500 docker-image/ # Dockerfiles (backend + frontend)
117187
117202
  \u2514\u2500\u2500 tests/ # Unit and integration tests
117188
117203
  \`\`\`
117189
117204
 
@@ -117643,11 +117658,14 @@ Thumbs.db
117643
117658
  logger.success("React frontend created at: " + webDir);
117644
117659
  }
117645
117660
  async function createDockerFiles(config, state, dryRun) {
117646
- const projectDir = config.name;
117647
- const projectName = config.name;
117648
- const projectNameLower = projectName.toLowerCase();
117661
+ const { name } = config;
117662
+ const projectDir = config.projectDir ?? ((0, import_path7.isAbsolute)(name) ? name : (0, import_path7.join)(process.cwd(), name));
117663
+ const projectName = (0, import_path7.basename)(name);
117664
+ if (!dryRun) {
117665
+ await import_fs_extra6.default.ensureDir((0, import_path7.join)(projectDir, "docker-image"));
117666
+ }
117649
117667
  const backendDockerfile = await loadTemplate("Dockerfile.backend.template", projectName);
117650
- const backendRelPath = `src/${projectName}.Api/Dockerfile`;
117668
+ const backendRelPath = "docker-image/Dockerfile.backend";
117651
117669
  if (dryRun) {
117652
117670
  logger.info(`Would create ${backendRelPath}`);
117653
117671
  } else {
@@ -117660,7 +117678,7 @@ async function createDockerFiles(config, state, dryRun) {
117660
117678
  recordFile(state, "docker", backendRelPath, backendResult.hash);
117661
117679
  }
117662
117680
  const frontendDockerfile = await loadTemplate("Dockerfile.frontend.template", projectName);
117663
- const frontendRelPath = `web/${projectNameLower}-web/Dockerfile`;
117681
+ const frontendRelPath = "docker-image/Dockerfile.frontend";
117664
117682
  if (dryRun) {
117665
117683
  logger.info(`Would create ${frontendRelPath}`);
117666
117684
  } else {
@@ -118119,8 +118137,8 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
118119
118137
  ` 3. Start dev server: ${source_default.cyan("npm run dev")}`,
118120
118138
  "",
118121
118139
  source_default.yellow("Docker:"),
118122
- ` Build backend: ${source_default.cyan(`docker build -t smartstack-${projectNameLower}-backend:latest -f src/${finalProjectName}.Api/Dockerfile .`)}`,
118123
- ` Build frontend: ${source_default.cyan(`docker build -t smartstack-${projectNameLower}-frontend:latest web/${projectNameLower}-web/`)}`,
118140
+ ` Build backend: ${source_default.cyan(`docker build -t smartstack-${projectNameLower}-backend:latest -f docker-image/Dockerfile.backend .`)}`,
118141
+ ` Build frontend: ${source_default.cyan(`docker build -t smartstack-${projectNameLower}-frontend:latest -f docker-image/Dockerfile.frontend .`)}`,
118124
118142
  "",
118125
118143
  source_default.yellow("Ralph (AI Automation):"),
118126
118144
  ` 1. Check MCP servers: ${source_default.cyan("smartstack check-mcp")}`,