@atlashub/smartstack-cli 3.20.0 → 3.22.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 (41) hide show
  1. package/dist/index.js +70 -6
  2. package/dist/index.js.map +1 -1
  3. package/dist/mcp-entry.mjs +69 -3
  4. package/dist/mcp-entry.mjs.map +1 -1
  5. package/package.json +1 -1
  6. package/templates/project/api.ts.template +8 -29
  7. package/templates/project/appsettings.json.template +1 -0
  8. package/templates/skills/application/references/application-roles-template.md +2 -2
  9. package/templates/skills/application/steps/step-05-frontend.md +40 -35
  10. package/templates/skills/application/templates-frontend.md +64 -36
  11. package/templates/skills/business-analyse/html/ba-interactive.html +642 -156
  12. package/templates/skills/business-analyse/html/src/scripts/01-data-init.js +11 -6
  13. package/templates/skills/business-analyse/html/src/scripts/02-navigation.js +209 -4
  14. package/templates/skills/business-analyse/html/src/scripts/04-render-modules.js +2 -8
  15. package/templates/skills/business-analyse/html/src/scripts/05-render-specs.js +95 -8
  16. package/templates/skills/business-analyse/html/src/scripts/07-render-handoff.js +3 -1
  17. package/templates/skills/business-analyse/html/src/scripts/08-editing.js +112 -22
  18. package/templates/skills/business-analyse/html/src/scripts/11-review-panel.js +7 -0
  19. package/templates/skills/business-analyse/html/src/styles/02-layout.css +1 -1
  20. package/templates/skills/business-analyse/html/src/styles/03-navigation.css +89 -31
  21. package/templates/skills/business-analyse/html/src/styles/05-modules.css +64 -0
  22. package/templates/skills/business-analyse/html/src/styles/06-wireframes.css +42 -0
  23. package/templates/skills/business-analyse/html/src/template.html +8 -76
  24. package/templates/skills/business-analyse/references/acceptance-criteria.md +169 -0
  25. package/templates/skills/business-analyse/references/deploy-data-build.md +13 -9
  26. package/templates/skills/business-analyse/references/handoff-file-templates.md +2 -1
  27. package/templates/skills/business-analyse/references/html-data-mapping.md +20 -28
  28. package/templates/skills/business-analyse/references/naming-conventions.md +245 -0
  29. package/templates/skills/business-analyse/references/validate-incremental-html.md +28 -5
  30. package/templates/skills/business-analyse/references/validation-checklist.md +31 -11
  31. package/templates/skills/business-analyse/references/wireframe-svg-style-guide.md +335 -0
  32. package/templates/skills/business-analyse/steps/step-03b-ui.md +59 -0
  33. package/templates/skills/business-analyse/steps/step-03c-compile.md +169 -2
  34. package/templates/skills/business-analyse/steps/step-03d-validate.md +217 -28
  35. package/templates/skills/business-analyse/steps/step-05a-handoff.md +189 -3
  36. package/templates/skills/business-analyse/steps/step-05b-deploy.md +55 -0
  37. package/templates/skills/ralph-loop/references/category-rules.md +5 -2
  38. package/templates/skills/ralph-loop/references/compact-loop.md +52 -1
  39. package/templates/skills/ralph-loop/references/core-seed-data.md +232 -21
  40. package/templates/skills/ralph-loop/steps/step-01-task.md +36 -4
  41. package/templates/skills/ralph-loop/steps/step-02-execute.md +81 -0
@@ -25773,6 +25773,7 @@ var init_types3 = __esm({
25773
25773
  projectType: external_exports.enum(["client", "platform"]).default("platform"),
25774
25774
  dbContext: external_exports.enum(["core", "extensions"]).default("core"),
25775
25775
  baseNamespace: external_exports.string().optional(),
25776
+ tablePrefix: external_exports.string().optional().describe('Application-level table prefix (e.g., "rh_", "fi_", "crm_")'),
25776
25777
  smartStackVersion: external_exports.string().optional(),
25777
25778
  initialized: external_exports.string().optional(),
25778
25779
  paths: external_exports.object({
@@ -57046,13 +57047,40 @@ async function scaffoldRoutes(input, config2) {
57046
57047
  result.instructions.push("");
57047
57048
  result.instructions.push("## App.tsx Wiring Instructions");
57048
57049
  result.instructions.push("");
57049
- result.instructions.push("Import page components and add routes INSIDE the appropriate Layout wrapper in App.tsx.");
57050
- result.instructions.push("Routes must be added in BOTH the standard block and the tenant-prefixed block (/t/:slug/...).");
57050
+ result.instructions.push("**Detect App.tsx pattern first**, then follow the matching instructions:");
57051
57051
  result.instructions.push("");
57052
57052
  const routeTree = buildRouteTree(navRoutes);
57053
+ result.instructions.push("### Pattern A: mergeRoutes (if App.tsx uses `contextRoutes: ContextRouteExtensions`)");
57054
+ result.instructions.push("");
57055
+ result.instructions.push("Add routes to `contextRoutes.{context}[]` with **RELATIVE** paths (no leading `/`):");
57056
+ result.instructions.push("");
57057
+ result.instructions.push("```tsx");
57058
+ result.instructions.push("const contextRoutes: ContextRouteExtensions = {");
57059
+ for (const [context, applications] of Object.entries(routeTree)) {
57060
+ result.instructions.push(` ${context}: [`);
57061
+ for (const [, modules] of Object.entries(applications)) {
57062
+ for (const route of modules) {
57063
+ const modulePath = route.navRoute.split(".").slice(1).join("/");
57064
+ const pageEntry = pageFiles.get(route.navRoute);
57065
+ const component = pageEntry?.[0]?.componentName || `${route.navRoute.split(".").map(capitalize).join("")}Page`;
57066
+ result.instructions.push(` { path: '${modulePath}', element: <${component} /> },`);
57067
+ }
57068
+ }
57069
+ result.instructions.push(" ],");
57070
+ }
57071
+ result.instructions.push("};");
57072
+ result.instructions.push("```");
57073
+ result.instructions.push("");
57074
+ result.instructions.push("Routes are automatically injected into BOTH standard and tenant-prefixed trees by `mergeRoutes()`.");
57075
+ result.instructions.push("**DO NOT** add business/platform/personal routes to `clientRoutes[]` \u2014 that array is only for routes outside SmartStack contexts.");
57076
+ result.instructions.push("");
57077
+ result.instructions.push('### Pattern B: JSX Routes (if App.tsx uses `<Route path="/{context}" element={<{Layout} />}>`)');
57078
+ result.instructions.push("");
57079
+ result.instructions.push("Insert `<Route>` children INSIDE the appropriate Layout wrapper:");
57080
+ result.instructions.push("");
57053
57081
  for (const [context, applications] of Object.entries(routeTree)) {
57054
57082
  const layoutName = getLayoutName(context);
57055
- result.instructions.push(`### ${capitalize(context)} context (inside <Route path="/${context}" element={<${layoutName} />}>):`);
57083
+ result.instructions.push(`#### ${capitalize(context)} context (inside \`<Route path="/${context}" element={<${layoutName} />}>\`):`);
57056
57084
  result.instructions.push("");
57057
57085
  result.instructions.push("```tsx");
57058
57086
  for (const [, modules] of Object.entries(applications)) {
@@ -57546,6 +57574,7 @@ function generateClientRoutesConfig(routes, pageFiles, includeGuards) {
57546
57574
  " */",
57547
57575
  "",
57548
57576
  "import type { RouteObject } from 'react-router-dom';",
57577
+ "import type { ContextRouteExtensions } from '@atlashub/smartstack';",
57549
57578
  "import { Navigate } from 'react-router-dom';"
57550
57579
  ];
57551
57580
  if (includeGuards) {
@@ -57647,6 +57676,24 @@ function generateClientRoutesConfig(routes, pageFiles, includeGuards) {
57647
57676
  }
57648
57677
  lines.push("};");
57649
57678
  lines.push("");
57679
+ lines.push("/**");
57680
+ lines.push(" * Context route extensions for mergeRoutes() pattern.");
57681
+ lines.push(" * Import and spread into your App.tsx contextRoutes:");
57682
+ lines.push(" *");
57683
+ lines.push(" * ```tsx");
57684
+ lines.push(" * import { contextRouteExtensions } from './routes/clientRoutes.generated';");
57685
+ lines.push(" * const contextRoutes: ContextRouteExtensions = {");
57686
+ lines.push(" * ...contextRouteExtensions,");
57687
+ lines.push(" * // your additional routes...");
57688
+ lines.push(" * };");
57689
+ lines.push(" * ```");
57690
+ lines.push(" */");
57691
+ lines.push("export const contextRouteExtensions: ContextRouteExtensions = {");
57692
+ for (const context of contexts) {
57693
+ lines.push(` ${context}: ${context}Routes,`);
57694
+ }
57695
+ lines.push("};");
57696
+ lines.push("");
57650
57697
  return lines.join("\n");
57651
57698
  }
57652
57699
  function getLayoutName(context) {
@@ -58027,6 +58074,25 @@ async function validateAppWiring(webPath, backendRoutes, result) {
58027
58074
  result.appWiring.issues.push("App.tsx does not import any route configuration");
58028
58075
  return;
58029
58076
  }
58077
+ const caseMismatches = [];
58078
+ for (const route of backendRoutes) {
58079
+ const modulePath = route.webPath.replace(/^\//, "");
58080
+ if (modulePath !== modulePath.toLowerCase()) {
58081
+ const kebabPath = modulePath.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
58082
+ caseMismatches.push(
58083
+ `Route "${route.navRoute}" uses PascalCase in URL. Found: ${modulePath} \u2192 Expected: ${kebabPath}`
58084
+ );
58085
+ }
58086
+ }
58087
+ if (caseMismatches.length > 0) {
58088
+ result.appWiring.issues.push(
58089
+ `Case mismatch detected (${caseMismatches.length} routes with uppercase):`
58090
+ );
58091
+ result.appWiring.issues.push(...caseMismatches);
58092
+ result.appWiring.issues.push(
58093
+ "Fix: Use ToKebabCase() in NavigationSeedData route generation (see core-seed-data.md)"
58094
+ );
58095
+ }
58030
58096
  for (const route of backendRoutes) {
58031
58097
  const modulePath = route.navRoute.split(".").slice(1).join("/");
58032
58098
  const lastSegment = route.navRoute.split(".").pop() || "";