create-avalon 0.2.0 → 0.2.1

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 (3) hide show
  1. package/README.md +6 -5
  2. package/dist/cli.js +74 -21
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -21,7 +21,7 @@ The CLI walks you through:
21
21
  - Project name and directory
22
22
  - Rendering engine (Preact or React) and island integrations
23
23
  - Styling approach (CSS Modules, Tailwind, shadcn)
24
- - Plugins (SEO, agent optimization, syntax highlighting)
24
+ - Plugins (SEO, agent optimization). MDX syntax highlighting is always on.
25
25
  - Middleware (h3, Hono, Elysia)
26
26
  - Deploy target (**Cloudflare Pages**, Netlify, or none)
27
27
  - Scheduled jobs (cron)
@@ -44,10 +44,11 @@ A ready-to-run Avalon project with file-system routing, islands architecture, an
44
44
  my-project/
45
45
  ├── app/
46
46
  │ ├── modules/
47
- │ │ └── main/
48
- │ │ ├── pages/ # File-system routes
49
- │ │ ├── components/ # Interactive components
50
- │ │ └── layouts/ # Module layouts
47
+ │ │ ├── main/ # Site root (/)
48
+ │ │├── pages/ # File-system routes for this module
49
+ │ │├── components/
50
+ │ │└── layouts/
51
+ │ │ └── about/ # /about — a module name is a URL prefix
51
52
  │ └── shared/
52
53
  │ ├── layouts/ # Root layout
53
54
  │ ├── components/ # Shared components
package/dist/cli.js CHANGED
@@ -115,11 +115,7 @@ var STYLING_OPTIONS = [
115
115
  "tailwind",
116
116
  "shadcn"
117
117
  ];
118
- var PLUGINS = [
119
- "seo",
120
- "agent-optimization",
121
- "syntax-highlighting"
122
- ];
118
+ var PLUGINS = ["seo", "agent-optimization"];
123
119
  var MIDDLEWARE_OPTIONS = [
124
120
  "h3",
125
121
  "hono",
@@ -143,6 +139,9 @@ var BASE_DIRS = [
143
139
  "app/modules/main/pages",
144
140
  "app/modules/main/components",
145
141
  "app/modules/main/layouts",
142
+ "app/modules/about/pages",
143
+ "app/modules/about/components",
144
+ "app/modules/about/layouts",
146
145
  "app/shared/layouts",
147
146
  "app/shared/components",
148
147
  "app/shared/styles",
@@ -1246,11 +1245,6 @@ async function collectProjectConfig(initialName) {
1246
1245
  value: "agent-optimization",
1247
1246
  label: "agent-optimization",
1248
1247
  hint: "LLM/AI optimization (llms.txt, markdown, sitemap)"
1249
- },
1250
- {
1251
- value: "syntax-highlighting",
1252
- label: "syntax-highlighting",
1253
- hint: "Code block highlighting for MDX (rehype-highlight)"
1254
1248
  }
1255
1249
  ],
1256
1250
  initialValues: ["seo"],
@@ -1731,8 +1725,8 @@ function generateRootLayout(config) {
1731
1725
  `)}
1732
1726
 
1733
1727
  export default async function RootLayout({ children, frontmatter }: Readonly<LayoutProps>) {
1734
- const title = frontmatter?.title ?? '${safeName}';
1735
- const description = frontmatter?.description ?? '';
1728
+ const title = typeof frontmatter?.title === 'string' ? frontmatter.title : '${safeName}';
1729
+ const description = typeof frontmatter?.description === 'string' ? frontmatter.description : '';
1736
1730
 
1737
1731
  return (
1738
1732
  <html lang="en">
@@ -1740,8 +1734,9 @@ export default async function RootLayout({ children, frontmatter }: Readonly<Lay
1740
1734
  <meta charset="UTF-8" />
1741
1735
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
1742
1736
  <title>{title}</title>
1743
- {description && <meta name="description" content={description} />}
1737
+ {description ? <meta name="description" content={description} /> : null}
1744
1738
  <link rel="icon" href="/favicon.ico" />
1739
+ <link rel="stylesheet" href="/syntax-highlighting.css" />
1745
1740
  </head>
1746
1741
  <body style={{ margin: 0 }}>
1747
1742
  {children}
@@ -1759,6 +1754,14 @@ export default async function MainLayout({ children }: Readonly<LayoutProps>) {
1759
1754
  }
1760
1755
  `;
1761
1756
  }
1757
+ function generateAboutLayout(_config) {
1758
+ return `import type { LayoutProps } from '@useavalon/avalon';
1759
+
1760
+ export default async function AboutLayout({ children }: Readonly<LayoutProps>) {
1761
+ return <>{children}</>;
1762
+ }
1763
+ `;
1764
+ }
1762
1765
 
1763
1766
  // src/templates/middleware.ts
1764
1767
  function generateSampleMiddleware(_config) {
@@ -1891,6 +1894,10 @@ export default async function HomePage() {
1891
1894
  <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' }}>
1892
1895
  Edit app/modules/main/pages/index.tsx
1893
1896
  </code>
1897
+ <p style={{ fontSize: '0.85rem', color: '#94a3b8', margin: '0.5rem 0 0' }}>
1898
+ <a href="/about" style={{ color: '#818cf8', textDecoration: 'none' }}>About</a>
1899
+ {' '}is the about module — app/modules/about/pages/index.tsx → /about
1900
+ </p>
1894
1901
  </div>
1895
1902
 
1896
1903
  <footer style={{ position: 'relative', zIndex: 1, marginTop: '4rem', paddingTop: '2rem', borderTop: '1px solid rgba(255,255,255,0.06)', width: '100%', maxWidth: '640px' }}>
@@ -1904,6 +1911,28 @@ export default async function HomePage() {
1904
1911
  }
1905
1912
  `;
1906
1913
  }
1914
+ function generateAboutPage() {
1915
+ return `export const metadata = {
1916
+ title: 'About',
1917
+ description: 'The about module maps to the /about route.',
1918
+ };
1919
+
1920
+ export default function AboutPage() {
1921
+ return (
1922
+ <div style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', background: 'linear-gradient(145deg, #0a0a12 0%, #0d1117 40%, #111827 100%)', color: '#e2e8f0', fontFamily: 'system-ui, -apple-system, sans-serif', padding: '2rem', textAlign: 'center' }}>
1923
+ <p style={{ fontSize: '0.8rem', letterSpacing: '0.15em', textTransform: 'uppercase', color: '#818cf8', marginBottom: '1.5rem', fontWeight: 500 }}>Module route</p>
1924
+ <h1 style={{ fontSize: 'clamp(2rem, 5vw, 3rem)', fontWeight: 700, lineHeight: 1.1, margin: '0 0 1.5rem' }}>About</h1>
1925
+ <p style={{ fontSize: '1.05rem', lineHeight: 1.7, color: '#94a3b8', marginBottom: '2rem', maxWidth: '480px' }}>
1926
+ This page is <code style={{ color: '#a5b4fc' }}>app/modules/about/pages/index.tsx</code>.
1927
+ A module name is a URL prefix, so the about module is <code style={{ color: '#a5b4fc' }}>/about</code>.
1928
+ The main module is the site root.
1929
+ </p>
1930
+ <a href="/" style={{ color: '#818cf8', textDecoration: 'none', fontWeight: 500 }}>Home</a>
1931
+ </div>
1932
+ );
1933
+ }
1934
+ `;
1935
+ }
1907
1936
  function generate404Page() {
1908
1937
  return `export const metadata = {
1909
1938
  title: '404 - Page Not Found',
@@ -1951,6 +1980,7 @@ function generatePostBuildMjs() {
1951
1980
  function generateStylingFiles(config) {
1952
1981
  const files = new Map;
1953
1982
  files.set("app/shared/styles/main.css", generateMainCss(config));
1983
+ files.set("public/syntax-highlighting.css", generateSyntaxHighlightingCss());
1954
1984
  if (config.styling === "css-modules") {
1955
1985
  files.set("app/shared/styles/reset.css", generateResetCss());
1956
1986
  }
@@ -2144,6 +2174,30 @@ function generateShadcnComponentsJson(config) {
2144
2174
  return JSON.stringify(componentsConfig, null, 2) + `
2145
2175
  `;
2146
2176
  }
2177
+ function generateSyntaxHighlightingCss() {
2178
+ return `code.hljs { padding: 3px 5px; }
2179
+ pre code.hljs { display: block; overflow-x: auto; padding: 1em; }
2180
+ .hljs { color: #c9d1d9; background: transparent; }
2181
+ .hljs-doctag, .hljs-keyword, .hljs-meta .hljs-keyword, .hljs-template-tag,
2182
+ .hljs-template-variable, .hljs-type, .hljs-variable.language_ { color: #ff7b72; }
2183
+ .hljs-title, .hljs-title.class_, .hljs-title.class_.inherited__,
2184
+ .hljs-title.function_ { color: #d2a8ff; }
2185
+ .hljs-attr, .hljs-attribute, .hljs-literal, .hljs-meta, .hljs-number,
2186
+ .hljs-operator, .hljs-variable, .hljs-selector-attr, .hljs-selector-class,
2187
+ .hljs-selector-id { color: #79c0ff; }
2188
+ .hljs-regexp, .hljs-string, .hljs-meta .hljs-string { color: #a5d6ff; }
2189
+ .hljs-built_in, .hljs-symbol { color: #ffa657; }
2190
+ .hljs-comment, .hljs-code, .hljs-formula { color: #8b949e; }
2191
+ .hljs-name, .hljs-quote, .hljs-selector-tag, .hljs-selector-pseudo { color: #7ee787; }
2192
+ .hljs-subst { color: #c9d1d9; }
2193
+ .hljs-section { color: #1f6feb; font-weight: bold; }
2194
+ .hljs-bullet { color: #f2cc60; }
2195
+ .hljs-emphasis { color: #c9d1d9; font-style: italic; }
2196
+ .hljs-strong { color: #c9d1d9; font-weight: bold; }
2197
+ .hljs-addition { color: #aff5b4; background-color: #033a16; }
2198
+ .hljs-deletion { color: #ffdcd7; background-color: #67060c; }
2199
+ `;
2200
+ }
2147
2201
 
2148
2202
  // src/templates/tsconfig.ts
2149
2203
  function generateTsConfig(core = "preact") {
@@ -2286,7 +2340,7 @@ function generateViteConfig(config) {
2286
2340
  ` clientEntry: 'app/entry-client',`,
2287
2341
  ` globalCSS: ['app/shared/styles/main.css'],`,
2288
2342
  ` prerender: {`,
2289
- ` routes: ['/'],`,
2343
+ ` routes: ['/', '/about'],`,
2290
2344
  ` crawlLinks: true,`,
2291
2345
  ` ignore: [],`,
2292
2346
  ` },`,
@@ -2387,6 +2441,8 @@ async function scaffoldProject(config, targetDir) {
2387
2441
  await writeFile(join(targetDir, "app/modules/main/layouts/_layout.tsx"), generateMainLayout(config));
2388
2442
  await writeFile(join(targetDir, "app/modules/main/pages/index.tsx"), generateMainPage(config));
2389
2443
  await writeFile(join(targetDir, "app/modules/main/pages/404.tsx"), generate404Page());
2444
+ await writeFile(join(targetDir, "app/modules/about/layouts/_layout.tsx"), generateAboutLayout(config));
2445
+ await writeFile(join(targetDir, "app/modules/about/pages/index.tsx"), generateAboutPage());
2390
2446
  await writeFile(join(targetDir, "middleware/01.logger.ts"), generateSampleMiddleware(config));
2391
2447
  await writeFile(join(targetDir, "routes/api/hello.ts"), generateHelloRoute(config));
2392
2448
  if (config.cron) {
@@ -2413,13 +2469,10 @@ async function scaffoldProject(config, targetDir) {
2413
2469
  `);
2414
2470
  await writeFile(join(targetDir, "server/renderer.ts"), [
2415
2471
  `/**`,
2416
- ` * SSR Renderer provided by Avalon's virtual module system.`,
2417
- ` *`,
2418
- ` * Avalon auto-discovers layouts, injects client assets, and handles`,
2419
- ` * layout wrapping. Import from the virtual modules directly to customize:`,
2472
+ ` * Nitro SSR catch-all. Keep this re-export for the default renderer.`,
2420
2473
  ` *`,
2421
- ` * import { wrapWithLayouts } from 'virtual:avalon/layouts';`,
2422
- ` * import { injectAssets } from 'virtual:avalon/assets';`,
2474
+ ` * Customize only when you need a custom hydration directive or to wrap`,
2475
+ ` * the handler. See https://useavalon.dev/docs/ssr-renderer`,
2423
2476
  ` */`,
2424
2477
  `export { default } from 'virtual:avalon/renderer';`,
2425
2478
  ``
@@ -2516,7 +2569,7 @@ async function main() {
2516
2569
  " --core Rendering engine: preact (default) | react",
2517
2570
  " --integrations Comma list: preact,react,vue,svelte,solid,lit,qwik",
2518
2571
  " --styling css-modules (default) | tailwind | shadcn",
2519
- " --plugins Comma list: seo (default),agent-optimization,syntax-highlighting",
2572
+ " --plugins Comma list: seo (default),agent-optimization",
2520
2573
  " --middleware h3 (default) | hono | elysia",
2521
2574
  " --deploy cloudflare | netlify | none (default)",
2522
2575
  " --cron Scaffold an example cron task + config",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-avalon",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Scaffold a new Avalon project with multi-framework islands architecture",
5
5
  "license": "MIT",
6
6
  "type": "module",