create-avalon 0.1.22 → 0.1.24

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 (2) hide show
  1. package/dist/cli.js +129 -31
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1156,13 +1156,15 @@ async function collectProjectConfig(initialName) {
1156
1156
  const pluginsResult = await Lt2({
1157
1157
  message: "Which plugins would you like to include? (use space to toggle, enter to confirm)",
1158
1158
  options: [
1159
- { value: "agent-optimization", label: "agent-optimization", hint: "LLM/AI optimization" },
1159
+ { value: "seo", label: "seo", hint: "Auto-injects OG, Twitter cards, JSON-LD, canonical URLs" },
1160
+ { value: "agent-optimization", label: "agent-optimization", hint: "LLM/AI optimization (llms.txt, markdown, sitemap)" },
1160
1161
  {
1161
1162
  value: "syntax-highlighting",
1162
1163
  label: "syntax-highlighting",
1163
1164
  hint: "Code block highlighting for MDX (rehype-highlight)"
1164
1165
  }
1165
1166
  ],
1167
+ initialValues: ["seo"],
1166
1168
  required: false
1167
1169
  });
1168
1170
  if (Ct(pluginsResult)) {
@@ -1217,7 +1219,7 @@ export default defineHandler(() => {
1217
1219
  }
1218
1220
 
1219
1221
  // src/templates/deploy.ts
1220
- function generateNetlifyToml(config) {
1222
+ function generateNetlifyToml(_config) {
1221
1223
  return `[build]
1222
1224
  base = "."
1223
1225
  command = "bun install && bun build.mjs"
@@ -1243,7 +1245,7 @@ function generateNetlifyToml(config) {
1243
1245
  }
1244
1246
  function generateBuildMjs() {
1245
1247
  return `/**
1246
- * Netlify build wrapper.
1248
+ * Build wrapper.
1247
1249
  *
1248
1250
  * Vite/Nitro leaves open handles after the build completes, preventing
1249
1251
  * the Node process from exiting. This wrapper detects when the build
@@ -1335,6 +1337,62 @@ const absoluteTimeout = setTimeout(() => {
1335
1337
  }, 240_000);
1336
1338
  `;
1337
1339
  }
1340
+ function generateRobotsTxt(sitemapUrl = "https://YOUR_DOMAIN/sitemap.xml") {
1341
+ return `# robots.txt
1342
+
1343
+ User-agent: *
1344
+ Allow: /
1345
+
1346
+ # Sitemap
1347
+ Sitemap: ${sitemapUrl}
1348
+
1349
+ # AI Crawlers — explicitly allowed
1350
+ User-agent: GPTBot
1351
+ Allow: /
1352
+
1353
+ User-agent: ChatGPT-User
1354
+ Allow: /
1355
+
1356
+ User-agent: Google-Extended
1357
+ Allow: /
1358
+
1359
+ User-agent: PerplexityBot
1360
+ Allow: /
1361
+
1362
+ User-agent: OAI-SearchBot
1363
+ Allow: /
1364
+
1365
+ User-agent: Applebot-Extended
1366
+ Allow: /
1367
+
1368
+ User-agent: Amazonbot
1369
+ Allow: /
1370
+
1371
+ User-agent: ClaudeBot
1372
+ Allow: /
1373
+
1374
+ User-agent: Bytespider
1375
+ Allow: /
1376
+
1377
+ User-agent: cohere-ai
1378
+ Allow: /
1379
+
1380
+ User-agent: Diffbot
1381
+ Allow: /
1382
+
1383
+ User-agent: anthropic-ai
1384
+ Allow: /
1385
+
1386
+ User-agent: Claude-Web
1387
+ Allow: /
1388
+
1389
+ User-agent: CCBot
1390
+ Allow: /
1391
+
1392
+ User-agent: AI2Bot
1393
+ Allow: /
1394
+ `;
1395
+ }
1338
1396
 
1339
1397
  // src/templates/favicon.ts
1340
1398
  var FAVICON_BASE64 = "AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAACMuAAAjLgAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8BAAD/AQAA/wEAAP8BAAD/AQAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wIBAP9DIQr/f0AT/4BAE/+AQBP/f0AT/34/E/9+PxL/fj8T/39AE/+BQBP/cjkR/yAQBf8GAwH/Wy4N/4hEFP+HRBT/h0QU/4dEFP+GQxT/hUMU/4VDE/+EQhP/hEIT/2QzD/8PCAL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/KxYG/8BgHP/YbSD/12wg/9dsIP/XbCD/12wg/9dsIP/XbCD/12wg/9dsIP/YbSD/iEUU/1AoDP/OaB7/2Gwg/9dsIP/XbCD/12wg/9dsIP/XbCD/12wg/9dsIP/XbCD/1Gsf/18wDv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8+Hwn/z2ge/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9RqH//FYx3/jUcV/9BpH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Vax//r1ga/xgMBP8AAAD/AAAA/wAAAP8AAAD/AAAA/xEIAv+lUxj/1msf/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9VrH/+iURj/tlsb/9VrH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//XzAO/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/1UrDP/RaR//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//1Gof/8RiHf+ZTRb/0Wkf/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9VrH/+tVxn/FgsD/wAAAP8AAAD/AAAA/wAAAP8AAAD/EwoD/6lVGf/Wax//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//1Gsf/6FRGP+6XRv/1Wsf/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9BoH/9BIQr/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Wi0N/9JqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Uax//wmId/51PF//Sah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Vax//ul4b/yQSBf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8WCwP/rVcZ/9VrH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Uah//olEY/71fHP/Uax//02of/9NqH//Tah//02of/9NqH//Tah//02of/9FpH/9eLw7/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9fLw7/02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9RrH//BYRz/oFEX/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Wax//l0wW/w0HAv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xgMBP+wWRr/1Wsf/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH/+iUhj/wWEc/9RrH//Tah//02of/9NqH//Tah//1Gsf/8BhHP8xGQf/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/2QyD//Uah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//1Gsf/8BgHP+kUxj/02of/9NqH//Tah//02of/9NqH//Tah//ZzQP/wEAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/HA4E/7RaGv/Vax//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/6NSGP/EYh3/1Gof/9NqH//Tah//1msf/59QF/8RCQP/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/aTUP/9RrH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Uax//v2Ac/6hVGf/Uah//02of/9RrH//FYx3/ORwI/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8fDwT/t1wb/9VrH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Sah//pVMY/8dkHf/Uax//1Gsf/3E5EP8CAQD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9uNxD/1Wsf/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//02of/9RrH/+8Xhz/m04X/81nHv+dTxf/FgsD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/yIRBf+6Xhv/1Wsf/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Tah//1Gsf/79gHP8yGQf/MxoI/xcMA/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/3Q6Ef/Vax//02of/9NqH//Tah//02of/9NqH//Tah//02of/9NqH//Uax//dDoR/wMBAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/JhMG/71fHP/Uax//02of/9NqH//Tah//02of/9NqH//Tah//1msf/6dUGP8XDAP/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8BAQD/eT0S/9ZrH//Tah//02of/9NqH//Tah//02of/9RqH//IZB3/QCAJ/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8qFQb/wGEc/9RrH//Tah//02of/9NqH//Tah//1Gsf/3c8Ev8DAgH/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wIBAP9+PxP/1msf/9NqH//Tah//02of/9ZrH/+nVBn/GAwE/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/y4XB//DYh3/1Gsf/9NqH//Uax//xWMd/zweCf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AwIA/4NCE//Wax//02of/9NqH/9rNhD/AgEA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/MhkH/8VjHf/XbCD/mk4X/xAIAv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8FAgH/iUUU/8BhHP8vGAf/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8yGQf/TygM/wEAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAP8CAQD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
@@ -1351,16 +1409,21 @@ function generateRootLayout(config) {
1351
1409
  } else {
1352
1410
  imports.push(`import '../styles/main.css';`);
1353
1411
  }
1412
+ const safeName = config.projectName.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
1354
1413
  return `${imports.join(`
1355
1414
  `)}
1356
1415
 
1357
- export default async function RootLayout({ children }: Readonly<LayoutProps>) {
1416
+ export default async function RootLayout({ children, frontmatter }: Readonly<LayoutProps>) {
1417
+ const title = frontmatter?.title ?? '${safeName}';
1418
+ const description = frontmatter?.description ?? '';
1419
+
1358
1420
  return (
1359
1421
  <html lang="en">
1360
1422
  <head>
1361
1423
  <meta charset="UTF-8" />
1362
1424
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
1363
- <title>${config.projectName}</title>
1425
+ <title>{title}</title>
1426
+ {description && <meta name="description" content={description} />}
1364
1427
  <link rel="icon" href="/favicon.ico" />
1365
1428
  </head>
1366
1429
  <body style={{ margin: 0 }}>
@@ -1371,10 +1434,10 @@ export default async function RootLayout({ children }: Readonly<LayoutProps>) {
1371
1434
  }
1372
1435
  `;
1373
1436
  }
1374
- function generateHomeLayout(config) {
1437
+ function generateMainLayout(config) {
1375
1438
  return `import type { LayoutProps } from '@useavalon/avalon';
1376
1439
 
1377
- export default async function HomeLayout({ children }: Readonly<LayoutProps>) {
1440
+ export default async function MainLayout({ children }: Readonly<LayoutProps>) {
1378
1441
  return <>{children}</>;
1379
1442
  }
1380
1443
  `;
@@ -1401,9 +1464,9 @@ var INTEGRATION_PACKAGES = {
1401
1464
  qwik: "@useavalon/qwik"
1402
1465
  };
1403
1466
  var BASE_DIRS = [
1404
- "app/modules/home/pages",
1405
- "app/modules/home/components",
1406
- "app/modules/home/layouts",
1467
+ "app/modules/main/pages",
1468
+ "app/modules/main/components",
1469
+ "app/modules/main/layouts",
1407
1470
  "app/shared/layouts",
1408
1471
  "app/shared/components",
1409
1472
  "app/shared/styles",
@@ -1421,6 +1484,9 @@ function generatePackageJson(config) {
1421
1484
  for (const integration of config.integrations) {
1422
1485
  dependencies[INTEGRATION_PACKAGES[integration]] = "latest";
1423
1486
  }
1487
+ if (config.plugins.includes("seo")) {
1488
+ dependencies["@useavalon/seo"] = "latest";
1489
+ }
1424
1490
  if (config.plugins.includes("agent-optimization")) {
1425
1491
  dependencies["@useavalon/agent-optimization"] = "latest";
1426
1492
  }
@@ -1429,10 +1495,10 @@ function generatePackageJson(config) {
1429
1495
  }
1430
1496
  switch (config.middleware) {
1431
1497
  case "hono":
1432
- dependencies["hono"] = "latest";
1498
+ dependencies.hono = "latest";
1433
1499
  break;
1434
1500
  case "elysia":
1435
- dependencies["elysia"] = "latest";
1501
+ dependencies.elysia = "latest";
1436
1502
  break;
1437
1503
  }
1438
1504
  const devDependencies = {
@@ -1443,15 +1509,15 @@ function generatePackageJson(config) {
1443
1509
  };
1444
1510
  switch (config.styling) {
1445
1511
  case "tailwind":
1446
- devDependencies["tailwindcss"] = "latest";
1512
+ devDependencies.tailwindcss = "latest";
1447
1513
  devDependencies["@tailwindcss/vite"] = "latest";
1448
1514
  break;
1449
1515
  case "shadcn":
1450
- devDependencies["tailwindcss"] = "latest";
1516
+ devDependencies.tailwindcss = "latest";
1451
1517
  devDependencies["@tailwindcss/vite"] = "latest";
1452
1518
  dependencies["@shadcn/ui"] = "latest";
1453
1519
  dependencies["tailwind-merge"] = "^3.5.0";
1454
- dependencies["clsx"] = "^2.1.1";
1520
+ dependencies.clsx = "^2.1.1";
1455
1521
  break;
1456
1522
  }
1457
1523
  const pkg = {
@@ -1460,22 +1526,17 @@ function generatePackageJson(config) {
1460
1526
  private: true,
1461
1527
  scripts: {
1462
1528
  dev: "bunx --bun vite dev",
1463
- build: config.deploy === "netlify" ? "bun build.mjs" : "bunx --bun vite build",
1464
- "post-build": config.deploy === "netlify" ? "node post-build.mjs" : undefined,
1529
+ build: "node build.mjs",
1465
1530
  preview: "node .output/server/index.mjs"
1466
1531
  },
1467
1532
  dependencies,
1468
1533
  devDependencies
1469
1534
  };
1470
- for (const key of Object.keys(pkg.scripts)) {
1471
- if (pkg.scripts[key] === undefined)
1472
- delete pkg.scripts[key];
1473
- }
1474
1535
  return JSON.stringify(pkg, null, 2);
1475
1536
  }
1476
1537
 
1477
1538
  // src/templates/pages.ts
1478
- function generateHomePage(config) {
1539
+ function generateMainPage(config) {
1479
1540
  return `export const metadata = {
1480
1541
  title: 'Avalon — Islands Architecture',
1481
1542
  description: 'A multi-framework islands architecture project powered by Avalon.',
@@ -1513,7 +1574,7 @@ export default async function HomePage() {
1513
1574
  <div style={{ position: 'relative', zIndex: 1, marginTop: '4rem', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '0.75rem' }}>
1514
1575
  <p style={{ fontSize: '0.75rem', color: '#64748b', letterSpacing: '0.1em', textTransform: 'uppercase' }}>Get started</p>
1515
1576
  <code style={{ display: 'block', padding: '0.6rem 1.2rem', borderRadius: '6px', background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.08)', color: '#a5b4fc', fontSize: '0.85rem', fontFamily: 'ui-monospace, monospace' }}>
1516
- Edit app/modules/home/pages/index.tsx
1577
+ Edit app/modules/main/pages/index.tsx
1517
1578
  </code>
1518
1579
  </div>
1519
1580
 
@@ -1528,6 +1589,24 @@ export default async function HomePage() {
1528
1589
  }
1529
1590
  `;
1530
1591
  }
1592
+ function generate404Page() {
1593
+ return `export const metadata = {
1594
+ title: '404 - Page Not Found',
1595
+ description: 'The page you are looking for does not exist.',
1596
+ robots: 'noindex, nofollow',
1597
+ };
1598
+
1599
+ export default function NotFoundPage() {
1600
+ return (
1601
+ <div style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', fontFamily: 'system-ui, -apple-system, sans-serif', textAlign: 'center', padding: '2rem' }}>
1602
+ <h1 style={{ fontSize: '4rem', margin: '0 0 1rem' }}>404</h1>
1603
+ <p style={{ fontSize: '1.25rem', color: '#64748b', margin: '0 0 2rem' }}>Page not found</p>
1604
+ <a href="/" style={{ color: '#6366f1', textDecoration: 'none', fontWeight: 500 }}>Go Home</a>
1605
+ </div>
1606
+ );
1607
+ }
1608
+ `;
1609
+ }
1531
1610
 
1532
1611
  // src/templates/post-build.ts
1533
1612
  function generatePostBuildMjs() {
@@ -1563,8 +1642,8 @@ function generateStylingFiles(config) {
1563
1642
  case "css-modules":
1564
1643
  files.set("app/shared/styles/tokens.css", generateTokensCss());
1565
1644
  files.set("app/shared/layouts/_layout.module.css", generateLayoutModuleCss());
1566
- files.set("app/modules/home/pages/index.module.css", generatePageModuleCss());
1567
- files.set("app/modules/home/layouts/_layout.module.css", generateLayoutModuleCss());
1645
+ files.set("app/modules/main/pages/index.module.css", generatePageModuleCss());
1646
+ files.set("app/modules/main/layouts/_layout.module.css", generateLayoutModuleCss());
1568
1647
  break;
1569
1648
  case "tailwind":
1570
1649
  files.set("tailwind.config.js", generateTailwindConfig());
@@ -1824,20 +1903,37 @@ function generateViteConfig(config) {
1824
1903
  if (needsTailwind) {
1825
1904
  imports.push(`import tailwindcss from '@tailwindcss/vite';`);
1826
1905
  }
1906
+ const hasSeo = config.plugins.includes("seo");
1907
+ if (hasSeo) {
1908
+ imports.push(`import { seo } from '@useavalon/seo';`);
1909
+ }
1827
1910
  const hasAgentOptimization = config.plugins.includes("agent-optimization");
1828
1911
  if (hasAgentOptimization) {
1829
1912
  imports.push(`import { agentOptimization } from '@useavalon/agent-optimization';`);
1830
1913
  }
1831
1914
  const integrationsList = config.integrations.map((i) => `'${i}'`).join(", ");
1832
1915
  const pluginEntries = [];
1916
+ if (hasSeo) {
1917
+ pluginEntries.push(` seo({
1918
+ siteUrl: 'http://localhost:3000',
1919
+ siteName: '${config.projectName.replace(/'/g, "\\'")}',
1920
+ defaultDescription: 'Built with Avalon',
1921
+ defaultOgImage: {
1922
+ url: '/og-image.png',
1923
+ width: 1200,
1924
+ height: 630,
1925
+ },
1926
+ breadcrumbs: true,
1927
+ speakable: true,
1928
+ }),`);
1929
+ }
1833
1930
  if (hasAgentOptimization) {
1834
1931
  pluginEntries.push(` agentOptimization({
1835
1932
  sitemap: { siteUrl: 'http://localhost:3000' },
1836
1933
  markdown: true,
1837
- structuredData: true,
1838
1934
  llms: {
1839
1935
  siteUrl: 'http://localhost:3000',
1840
- siteName: 'My Avalon App',
1936
+ siteName: '${config.projectName.replace(/'/g, "\\'")}',
1841
1937
  siteDescription: 'Built with Avalon',
1842
1938
  sections: { 'Pages': ['/'] },
1843
1939
  },
@@ -1960,8 +2056,9 @@ async function scaffoldProject(config, targetDir) {
1960
2056
  await writeFile(join(targetDir, "tsconfig.json"), generateTsConfig());
1961
2057
  await writeFile(join(targetDir, "vite.config.ts"), generateViteConfig(config));
1962
2058
  await writeFile(join(targetDir, "app/shared/layouts/_layout.tsx"), generateRootLayout(config));
1963
- await writeFile(join(targetDir, "app/modules/home/layouts/_layout.tsx"), generateHomeLayout(config));
1964
- await writeFile(join(targetDir, "app/modules/home/pages/index.tsx"), generateHomePage(config));
2059
+ await writeFile(join(targetDir, "app/modules/main/layouts/_layout.tsx"), generateMainLayout(config));
2060
+ await writeFile(join(targetDir, "app/modules/main/pages/index.tsx"), generateMainPage(config));
2061
+ await writeFile(join(targetDir, "app/modules/main/pages/404.tsx"), generate404Page());
1965
2062
  await writeFile(join(targetDir, "middleware/01.logger.ts"), generateSampleMiddleware(config));
1966
2063
  await writeFile(join(targetDir, "routes/api/hello.ts"), generateHelloRoute(config));
1967
2064
  if (config.middleware === "hono") {
@@ -1975,6 +2072,7 @@ async function scaffoldProject(config, targetDir) {
1975
2072
  await writeFile(join(targetDir, filePath), content);
1976
2073
  }
1977
2074
  await writeFile(join(targetDir, "public/favicon.ico"), getFaviconBuffer());
2075
+ await writeFile(join(targetDir, "public/robots.txt"), generateRobotsTxt());
1978
2076
  await writeFile(join(targetDir, "server/env.d.ts"), `/// <reference types="nitro" />
1979
2077
  `);
1980
2078
  await writeFile(join(targetDir, "app/env.d.ts"), generateEnvDts(config.integrations));
@@ -1992,10 +2090,10 @@ async function scaffoldProject(config, targetDir) {
1992
2090
  ``
1993
2091
  ].join(`
1994
2092
  `));
2093
+ await writeFile(join(targetDir, "build.mjs"), generateBuildMjs());
2094
+ await writeFile(join(targetDir, "post-build.mjs"), generatePostBuildMjs());
1995
2095
  if (config.deploy === "netlify") {
1996
2096
  await writeFile(join(targetDir, "netlify.toml"), generateNetlifyToml(config));
1997
- await writeFile(join(targetDir, "build.mjs"), generateBuildMjs());
1998
- await writeFile(join(targetDir, "post-build.mjs"), generatePostBuildMjs());
1999
2097
  }
2000
2098
  }
2001
2099
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-avalon",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "Scaffold a new Avalon project with multi-framework islands architecture",
5
5
  "license": "MIT",
6
6
  "type": "module",