@atlashub/smartstack-cli 3.21.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.
- package/dist/index.js +17 -5
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +68 -3
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -1
- package/templates/skills/application/references/application-roles-template.md +2 -2
- package/templates/skills/application/steps/step-05-frontend.md +40 -35
- package/templates/skills/application/templates-frontend.md +64 -36
- package/templates/skills/business-analyse/html/ba-interactive.html +80 -6
- package/templates/skills/business-analyse/html/src/scripts/05-render-specs.js +38 -6
- package/templates/skills/business-analyse/html/src/styles/06-wireframes.css +42 -0
- package/templates/skills/business-analyse/references/acceptance-criteria.md +169 -0
- package/templates/skills/business-analyse/references/deploy-data-build.md +5 -3
- package/templates/skills/business-analyse/references/handoff-file-templates.md +2 -1
- package/templates/skills/business-analyse/references/naming-conventions.md +245 -0
- package/templates/skills/business-analyse/references/validate-incremental-html.md +26 -4
- package/templates/skills/business-analyse/references/validation-checklist.md +31 -11
- package/templates/skills/business-analyse/references/wireframe-svg-style-guide.md +335 -0
- package/templates/skills/business-analyse/steps/step-03b-ui.md +59 -0
- package/templates/skills/business-analyse/steps/step-03c-compile.md +114 -0
- package/templates/skills/business-analyse/steps/step-03d-validate.md +144 -22
- package/templates/skills/business-analyse/steps/step-05a-handoff.md +114 -2
- package/templates/skills/business-analyse/steps/step-05b-deploy.md +28 -0
- package/templates/skills/ralph-loop/references/category-rules.md +5 -2
- package/templates/skills/ralph-loop/references/compact-loop.md +52 -1
- package/templates/skills/ralph-loop/references/core-seed-data.md +232 -21
- package/templates/skills/ralph-loop/steps/step-01-task.md +36 -4
- package/templates/skills/ralph-loop/steps/step-02-execute.md +81 -0
package/dist/mcp-entry.mjs
CHANGED
|
@@ -57047,13 +57047,40 @@ async function scaffoldRoutes(input, config2) {
|
|
|
57047
57047
|
result.instructions.push("");
|
|
57048
57048
|
result.instructions.push("## App.tsx Wiring Instructions");
|
|
57049
57049
|
result.instructions.push("");
|
|
57050
|
-
result.instructions.push("
|
|
57051
|
-
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:");
|
|
57052
57051
|
result.instructions.push("");
|
|
57053
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("");
|
|
57054
57081
|
for (const [context, applications] of Object.entries(routeTree)) {
|
|
57055
57082
|
const layoutName = getLayoutName(context);
|
|
57056
|
-
result.instructions.push(
|
|
57083
|
+
result.instructions.push(`#### ${capitalize(context)} context (inside \`<Route path="/${context}" element={<${layoutName} />}>\`):`);
|
|
57057
57084
|
result.instructions.push("");
|
|
57058
57085
|
result.instructions.push("```tsx");
|
|
57059
57086
|
for (const [, modules] of Object.entries(applications)) {
|
|
@@ -57547,6 +57574,7 @@ function generateClientRoutesConfig(routes, pageFiles, includeGuards) {
|
|
|
57547
57574
|
" */",
|
|
57548
57575
|
"",
|
|
57549
57576
|
"import type { RouteObject } from 'react-router-dom';",
|
|
57577
|
+
"import type { ContextRouteExtensions } from '@atlashub/smartstack';",
|
|
57550
57578
|
"import { Navigate } from 'react-router-dom';"
|
|
57551
57579
|
];
|
|
57552
57580
|
if (includeGuards) {
|
|
@@ -57648,6 +57676,24 @@ function generateClientRoutesConfig(routes, pageFiles, includeGuards) {
|
|
|
57648
57676
|
}
|
|
57649
57677
|
lines.push("};");
|
|
57650
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("");
|
|
57651
57697
|
return lines.join("\n");
|
|
57652
57698
|
}
|
|
57653
57699
|
function getLayoutName(context) {
|
|
@@ -58028,6 +58074,25 @@ async function validateAppWiring(webPath, backendRoutes, result) {
|
|
|
58028
58074
|
result.appWiring.issues.push("App.tsx does not import any route configuration");
|
|
58029
58075
|
return;
|
|
58030
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
|
+
}
|
|
58031
58096
|
for (const route of backendRoutes) {
|
|
58032
58097
|
const modulePath = route.navRoute.split(".").slice(1).join("/");
|
|
58033
58098
|
const lastSegment = route.navRoute.split(".").pop() || "";
|