meno-core 1.0.40 → 1.0.42

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 (70) hide show
  1. package/bin/cli.ts +33 -0
  2. package/build-astro.ts +3 -27
  3. package/dist/bin/cli.js +31 -3
  4. package/dist/bin/cli.js.map +2 -2
  5. package/dist/build-static.js +8 -8
  6. package/dist/chunks/{chunk-A6KWUEA6.js → chunk-24KKYW25.js} +10 -2
  7. package/dist/chunks/chunk-24KKYW25.js.map +7 -0
  8. package/dist/chunks/{chunk-YSZ5IUFM.js → chunk-5Z5VQRTJ.js} +8 -4
  9. package/dist/chunks/chunk-5Z5VQRTJ.js.map +7 -0
  10. package/dist/chunks/{chunk-V4SVSX3X.js → chunk-6AYGKR6Y.js} +40 -25
  11. package/dist/chunks/chunk-6AYGKR6Y.js.map +7 -0
  12. package/dist/chunks/{chunk-3NOZVNM4.js → chunk-ACK7AURE.js} +5 -5
  13. package/dist/chunks/{chunk-Z7SAOCDG.js → chunk-DIYO4RBJ.js} +11 -2
  14. package/dist/chunks/{chunk-Z7SAOCDG.js.map → chunk-DIYO4RBJ.js.map} +2 -2
  15. package/dist/chunks/{chunk-OJ5SROQN.js → chunk-ITVPRBD6.js} +25 -9
  16. package/dist/chunks/chunk-ITVPRBD6.js.map +7 -0
  17. package/dist/chunks/{chunk-LOJLO2EY.js → chunk-S2HXJTAF.js} +1 -1
  18. package/dist/chunks/chunk-S2HXJTAF.js.map +7 -0
  19. package/dist/chunks/{chunk-GKICS7CF.js → chunk-UGHOL7IP.js} +2426 -249
  20. package/dist/chunks/chunk-UGHOL7IP.js.map +7 -0
  21. package/dist/chunks/{chunk-MOCRENNU.js → chunk-YM5BJZYJ.js} +8 -8
  22. package/dist/chunks/{chunk-MOCRENNU.js.map → chunk-YM5BJZYJ.js.map} +2 -2
  23. package/dist/chunks/{configService-TXBNUBBL.js → configService-KK5JEQOZ.js} +3 -3
  24. package/dist/chunks/{constants-L75FR445.js → constants-JOIPAAAA.js} +2 -2
  25. package/dist/entries/server-router.js +8 -8
  26. package/dist/lib/client/index.js +30 -16
  27. package/dist/lib/client/index.js.map +3 -3
  28. package/dist/lib/server/index.js +102 -53
  29. package/dist/lib/server/index.js.map +2 -2
  30. package/dist/lib/shared/index.js +16 -12
  31. package/dist/lib/shared/index.js.map +2 -2
  32. package/dist/lib/test-utils/index.js +1 -1
  33. package/lib/client/core/ComponentBuilder.ts +28 -15
  34. package/lib/client/routing/Router.tsx +6 -0
  35. package/lib/client/templateEngine.test.ts +178 -0
  36. package/lib/client/templateEngine.ts +45 -43
  37. package/lib/server/astro/cmsPageEmitter.ts +3 -0
  38. package/lib/server/astro/componentEmitter.ts +60 -12
  39. package/lib/server/astro/nodeToAstro.test.ts +1101 -0
  40. package/lib/server/astro/nodeToAstro.ts +58 -19
  41. package/lib/server/astro/pageEmitter.ts +4 -0
  42. package/lib/server/index.ts +3 -0
  43. package/lib/server/jsonLoader.ts +2 -2
  44. package/lib/server/routes/static.ts +1 -1
  45. package/lib/server/runtime/bundler.ts +9 -4
  46. package/lib/server/services/configService.ts +12 -0
  47. package/lib/server/ssr/htmlGenerator.ts +0 -5
  48. package/lib/server/ssr/imageMetadata.ts +3 -3
  49. package/lib/server/ssr/index.ts +4 -0
  50. package/lib/server/ssr/ssrRenderer.test.ts +16 -1
  51. package/lib/server/ssr/ssrRenderer.ts +71 -33
  52. package/lib/shared/constants.ts +5 -0
  53. package/lib/shared/nodeUtils.ts +24 -3
  54. package/lib/shared/registry/nodeTypes/ListNodeType.ts +2 -0
  55. package/lib/shared/styleNodeUtils.ts +36 -8
  56. package/lib/shared/tree/PathBuilder.ts +11 -15
  57. package/lib/shared/types/components.ts +8 -4
  58. package/lib/shared/validation/propValidator.ts +2 -1
  59. package/lib/shared/validation/schemas.ts +3 -1
  60. package/package.json +1 -1
  61. package/templates/index-router.html +0 -5
  62. package/dist/chunks/chunk-A6KWUEA6.js.map +0 -7
  63. package/dist/chunks/chunk-GKICS7CF.js.map +0 -7
  64. package/dist/chunks/chunk-LOJLO2EY.js.map +0 -7
  65. package/dist/chunks/chunk-OJ5SROQN.js.map +0 -7
  66. package/dist/chunks/chunk-V4SVSX3X.js.map +0 -7
  67. package/dist/chunks/chunk-YSZ5IUFM.js.map +0 -7
  68. /package/dist/chunks/{chunk-3NOZVNM4.js.map → chunk-ACK7AURE.js.map} +0 -0
  69. /package/dist/chunks/{configService-TXBNUBBL.js.map → configService-KK5JEQOZ.js.map} +0 -0
  70. /package/dist/chunks/{constants-L75FR445.js.map → constants-JOIPAAAA.js.map} +0 -0
package/bin/cli.ts CHANGED
@@ -296,6 +296,35 @@ async function runInit(projectName?: string) {
296
296
  JSON.stringify(packageJson, null, 2)
297
297
  );
298
298
 
299
+ // Create .claude/tools/ with screenshot tool
300
+ mkdirSync(join(projectPath, '.claude', 'tools'), { recursive: true });
301
+
302
+ const screenshotToolSrc = join(import.meta.dirname, '..', '..', '..', 'example', '.claude', 'tools', 'screenshot.mjs');
303
+ if (existsSync(screenshotToolSrc)) {
304
+ cpSync(screenshotToolSrc, join(projectPath, '.claude', 'tools', 'screenshot.mjs'));
305
+ }
306
+
307
+ // Create CLAUDE.md with project instructions
308
+ const claudeMd = `# ${projectName}
309
+
310
+ A Meno project - visual editor that generates websites from JSON files.
311
+
312
+ ## Dev Server
313
+
314
+ \`\`\`bash
315
+ bun run dev # Start dev server on port 3000
316
+ \`\`\`
317
+
318
+ ## Screenshot Tool
319
+
320
+ Take a screenshot of any element by its node ID:
321
+ \`\`\`bash
322
+ npx puppeteer browsers install chrome && node .claude/tools/screenshot.mjs <nodeId> --page /about
323
+ \`\`\`
324
+ Node IDs can be found in the page JSON files under the \`id\` field of each node.
325
+ `;
326
+ writeFileSync(join(projectPath, 'CLAUDE.md'), claudeMd);
327
+
299
328
  // Create .gitignore
300
329
  const gitignore = `# Dependencies
301
330
  node_modules/
@@ -387,6 +416,9 @@ command = "bun install && bun run build"
387
416
 
388
417
  console.log('✅ Created project structure:');
389
418
  console.log(` ${projectName}/`);
419
+ console.log(' ├── .claude/');
420
+ console.log(' │ └── tools/');
421
+ console.log(' │ └── screenshot.mjs');
390
422
  console.log(' ├── pages/');
391
423
  console.log(' │ └── index.json');
392
424
  console.log(' ├── components/');
@@ -395,6 +427,7 @@ command = "bun install && bun run build"
395
427
  console.log(' ├── colors.json');
396
428
  console.log(' ├── project.config.json');
397
429
  console.log(' ├── package.json');
430
+ console.log(' ├── CLAUDE.md');
398
431
  console.log(' ├── netlify.toml');
399
432
  console.log(' ├── vercel.json');
400
433
  console.log(' ├── wrangler.toml');
package/build-astro.ts CHANGED
@@ -42,7 +42,7 @@ import { emitAstroPage } from "./lib/server/astro/pageEmitter";
42
42
  import { emitCMSPage } from './lib/server/astro/cmsPageEmitter';
43
43
  import { collectAllMappingClasses } from "./lib/server/astro/cssCollector";
44
44
  import { buildImageMetadataMap } from "./lib/server/ssr/imageMetadata";
45
- import { extractUtilityClassesFromHTML, generateUtilityCSS } from "./lib/shared/cssGeneration";
45
+
46
46
 
47
47
  // ---------------------------------------------------------------------------
48
48
  // Helpers
@@ -630,6 +630,7 @@ export async function buildAstroProject(
630
630
  i18nConfig,
631
631
  isMultiLocale: false, // Each file handles one locale
632
632
  slugMappings,
633
+ imageFormat: configService.getImageFormat(),
633
634
  });
634
635
 
635
636
  const astroFileFull = join(pagesOutDir, astroFilePath);
@@ -742,8 +743,6 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
742
743
  // ----------------------------------------------------------
743
744
  // 8. Generate .astro page files (component-structured)
744
745
  // ----------------------------------------------------------
745
- const allFallbackHtml: string[] = []; // Collect SSR fallback HTML for utility CSS generation
746
-
747
746
  for (const result of allResults) {
748
747
  const importPath = layoutImportPath(result.fileDepth);
749
748
 
@@ -772,9 +771,6 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
772
771
  try {
773
772
  // Use SSR fallback collector from the initial render (paths already match nodeToAstro convention)
774
773
  const ssrFallbacks = result.ssrFallbackCollector ?? new Map<string, string>();
775
- ssrFallbacks.forEach((html) => {
776
- allFallbackHtml.push(html);
777
- });
778
774
 
779
775
  // Compute slug map for locale list rendering
780
776
  const pageSlugMap: Record<string, string> | undefined =
@@ -801,6 +797,7 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
801
797
  i18nConfig: i18nConfig.locales.length > 1 ? i18nConfig : undefined,
802
798
  currentPageSlugMap: pageSlugMap,
803
799
  slugMappings: i18nConfig.locales.length > 1 ? slugMappings : undefined,
800
+ imageFormat: configService.getImageFormat(),
804
801
  });
805
802
  } catch (error: any) {
806
803
  // Fallback to SSR HTML if component emission fails
@@ -810,7 +807,6 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
810
807
  } else {
811
808
  // Pages without pageData: use SSR fallback
812
809
  astroContent = buildSSRFallbackPage(result, importPath, fontPreloads, libraryTags, defaultTheme, scriptPaths);
813
- allFallbackHtml.push(result.html);
814
810
  }
815
811
 
816
812
  const astroFileFull = join(pagesOutDir, result.astroFilePath);
@@ -824,26 +820,6 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
824
820
 
825
821
  console.log(`Generated ${allResults.length} .astro page file(s)`);
826
822
 
827
- // ----------------------------------------------------------
828
- // 8.5. Generate utility CSS for SSR fallback HTML
829
- // ----------------------------------------------------------
830
- if (allFallbackHtml.length > 0) {
831
- const allClasses = new Set<string>();
832
- for (const html of allFallbackHtml) {
833
- for (const cls of extractUtilityClassesFromHTML(html)) {
834
- allClasses.add(cls);
835
- }
836
- }
837
- if (allClasses.size > 0) {
838
- const utilityCSS = generateUtilityCSS(allClasses, breakpoints, responsiveScales);
839
- if (utilityCSS) {
840
- const existingCSS = await readFile(join(stylesDir, 'global.css'), 'utf-8');
841
- await writeFile(join(stylesDir, 'global.css'), existingCSS + '\n\n/* SSR fallback utility classes */\n' + utilityCSS, 'utf-8');
842
- console.log(`Added ${allClasses.size} utility classes for SSR fallback content`);
843
- }
844
- }
845
- }
846
-
847
823
  // ----------------------------------------------------------
848
824
  // 9. Generate CMS content collections (if templates exist)
849
825
  // ----------------------------------------------------------
package/dist/bin/cli.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  createRuntimeServer,
7
7
  setProjectRoot
8
- } from "../chunks/chunk-YSZ5IUFM.js";
8
+ } from "../chunks/chunk-5Z5VQRTJ.js";
9
9
  import {
10
10
  fileExists,
11
11
  serveFile
@@ -14,7 +14,7 @@ import "../chunks/chunk-KSBZ2L7C.js";
14
14
 
15
15
  // bin/cli.ts
16
16
  import { resolve, join } from "path";
17
- import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
17
+ import { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync } from "fs";
18
18
  var args = process.argv.slice(2);
19
19
  var command = args[0];
20
20
  function printHelp() {
@@ -82,7 +82,7 @@ function getMatchingHeaders(pathname, headersMap) {
82
82
  return result;
83
83
  }
84
84
  async function startStaticServer(distPath) {
85
- const { SERVE_PORT } = await import("../chunks/constants-L75FR445.js");
85
+ const { SERVE_PORT } = await import("../chunks/constants-JOIPAAAA.js");
86
86
  const headersMap = parseHeadersFile(distPath);
87
87
  const server = await createRuntimeServer({
88
88
  port: SERVE_PORT,
@@ -226,6 +226,30 @@ async function runInit(projectName) {
226
226
  join(projectPath, "package.json"),
227
227
  JSON.stringify(packageJson, null, 2)
228
228
  );
229
+ mkdirSync(join(projectPath, ".claude", "tools"), { recursive: true });
230
+ const screenshotToolSrc = join(import.meta.dirname, "..", "..", "..", "example", ".claude", "tools", "screenshot.mjs");
231
+ if (existsSync(screenshotToolSrc)) {
232
+ cpSync(screenshotToolSrc, join(projectPath, ".claude", "tools", "screenshot.mjs"));
233
+ }
234
+ const claudeMd = `# ${projectName}
235
+
236
+ A Meno project - visual editor that generates websites from JSON files.
237
+
238
+ ## Dev Server
239
+
240
+ \`\`\`bash
241
+ bun run dev # Start dev server on port 3000
242
+ \`\`\`
243
+
244
+ ## Screenshot Tool
245
+
246
+ Take a screenshot of any element by its node ID:
247
+ \`\`\`bash
248
+ npx puppeteer browsers install chrome && node .claude/tools/screenshot.mjs <nodeId> --page /about
249
+ \`\`\`
250
+ Node IDs can be found in the page JSON files under the \`id\` field of each node.
251
+ `;
252
+ writeFileSync(join(projectPath, "CLAUDE.md"), claudeMd);
229
253
  const gitignore = `# Dependencies
230
254
  node_modules/
231
255
 
@@ -307,6 +331,9 @@ command = "bun install && bun run build"
307
331
  );
308
332
  console.log("\u2705 Created project structure:");
309
333
  console.log(` ${projectName}/`);
334
+ console.log(" \u251C\u2500\u2500 .claude/");
335
+ console.log(" \u2502 \u2514\u2500\u2500 tools/");
336
+ console.log(" \u2502 \u2514\u2500\u2500 screenshot.mjs");
310
337
  console.log(" \u251C\u2500\u2500 pages/");
311
338
  console.log(" \u2502 \u2514\u2500\u2500 index.json");
312
339
  console.log(" \u251C\u2500\u2500 components/");
@@ -315,6 +342,7 @@ command = "bun install && bun run build"
315
342
  console.log(" \u251C\u2500\u2500 colors.json");
316
343
  console.log(" \u251C\u2500\u2500 project.config.json");
317
344
  console.log(" \u251C\u2500\u2500 package.json");
345
+ console.log(" \u251C\u2500\u2500 CLAUDE.md");
318
346
  console.log(" \u251C\u2500\u2500 netlify.toml");
319
347
  console.log(" \u251C\u2500\u2500 vercel.json");
320
348
  console.log(" \u251C\u2500\u2500 wrangler.toml");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../bin/cli.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n/**\n * meno CLI\n * Commands: dev, build, init\n */\n\nimport { resolve, join } from 'path';\nimport { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync } from 'fs';\nimport { setProjectRoot } from '../lib/server/projectContext';\nimport { generateBuildErrorPage, type BuildErrorsData } from '../lib/server/ssr/buildErrorOverlay';\nimport { createRuntimeServer, serveFile, fileExists as runtimeFileExists } from '../lib/server/runtime';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nfunction printHelp() {\n console.log(`\nmeno - Visual editor for JSON-based pages\n\nRequirements:\n - Bun or Node.js 18+\n\nUsage:\n meno <command> [options]\n\nCommands:\n dev Start development server with hot reload\n build Build static HTML files for production\n serve Serve built files from ./dist on port 8080\n init Initialize a new project\n\nOptions:\n build --dev Include draft pages in build (for local preview)\n\nExamples:\n meno dev Start dev server in current directory\n meno build Build static files to ./dist (excludes drafts)\n meno build --dev Build including draft pages\n meno serve Serve built files on port 8080\n meno init my-project Create new project in ./my-project\n`);\n}\n\n// Parse _headers file (Netlify/Cloudflare format)\nfunction parseHeadersFile(distPath: string): Map<string, Record<string, string>> {\n const headersPath = join(distPath, '_headers');\n const headers = new Map<string, Record<string, string>>();\n\n if (!existsSync(headersPath)) return headers;\n\n const content = readFileSync(headersPath, 'utf-8');\n let currentPath = '';\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n if (!line.startsWith(' ') && !line.startsWith('\\t')) {\n // Path line\n currentPath = trimmed;\n if (!headers.has(currentPath)) {\n headers.set(currentPath, {});\n }\n } else if (currentPath && trimmed.includes(':')) {\n // Header line\n const colonIndex = trimmed.indexOf(':');\n const name = trimmed.substring(0, colonIndex).trim();\n const value = trimmed.substring(colonIndex + 1).trim();\n headers.get(currentPath)![name] = value;\n }\n }\n\n return headers;\n}\n\n// Get headers matching a pathname\nfunction getMatchingHeaders(\n pathname: string,\n headersMap: Map<string, Record<string, string>>\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n headersMap.forEach((headers, pattern) => {\n if (pattern === pathname || pattern === '/*') {\n Object.assign(result, headers);\n } else if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n if (pathname.startsWith(prefix)) {\n Object.assign(result, headers);\n }\n }\n });\n\n return result;\n}\n\n// Start static file server on port 8080 (non-blocking)\nasync function startStaticServer(distPath: string) {\n const { SERVE_PORT } = await import('../lib/shared/constants');\n\n // Parse _headers file once on startup\n const headersMap = parseHeadersFile(distPath);\n\n const server = await createRuntimeServer({\n port: SERVE_PORT,\n hostname: 'localhost',\n async fetch(req: Request) {\n const url = new URL(req.url);\n let pathname = url.pathname;\n\n // Check for build errors and show overlay (except for _errors.json itself)\n if (pathname !== '/_errors.json') {\n const errorsPath = join(distPath, '_errors.json');\n if (existsSync(errorsPath)) {\n try {\n const errorsData: BuildErrorsData = JSON.parse(readFileSync(errorsPath, 'utf-8'));\n return new Response(generateBuildErrorPage(errorsData), {\n headers: { 'Content-Type': 'text/html; charset=utf-8' },\n });\n } catch {\n // If we can't parse errors file, continue normally\n }\n }\n }\n\n // Default to index.html for root\n if (pathname === '/') {\n pathname = '/index.html';\n }\n\n // Get custom headers for this path\n const customHeaders = getMatchingHeaders(pathname, headersMap);\n\n // Try to serve the file\n const filePath = join(distPath, pathname);\n\n // Check if file exists and serve it\n if (await runtimeFileExists(filePath)) {\n return await serveFile(filePath, customHeaders);\n }\n\n // Try with .html extension for clean URLs\n const htmlPath = filePath.endsWith('.html') ? filePath : `${filePath}.html`;\n if (await runtimeFileExists(htmlPath)) {\n return await serveFile(htmlPath, customHeaders);\n }\n\n // Try index.html in directory\n const indexPath = join(filePath, 'index.html');\n if (await runtimeFileExists(indexPath)) {\n return await serveFile(indexPath, customHeaders);\n }\n\n return new Response('Not Found', { status: 404 });\n },\n });\n\n return server;\n}\n\nasync function runDev() {\n const projectRoot = process.cwd();\n\n // Validate project structure\n if (!existsSync(join(projectRoot, 'pages'))) {\n console.error('\u274C No pages directory found. Are you in a valid project directory?');\n console.error(' Run \"meno init <project-name>\" to create a new project.');\n process.exit(1);\n }\n\n // Set project root for path resolution\n setProjectRoot(projectRoot);\n\n console.log(`\uD83D\uDCC1 Project root: ${projectRoot}`);\n\n // Start static server on 8080 if dist exists\n const distPath = join(projectRoot, 'dist');\n if (existsSync(distPath)) {\n const staticServer = await startStaticServer(distPath);\n console.log(`\uD83D\uDE80 Static server running at http://localhost:${staticServer.port}`);\n }\n\n // Import and run the dev server (it handles all initialization internally)\n await import('../entries/server-router');\n}\n\nasync function runBuild(isDev: boolean = false) {\n const projectRoot = process.cwd();\n\n // Validate project structure\n if (!existsSync(join(projectRoot, 'pages'))) {\n console.error('\u274C No pages directory found. Are you in a valid project directory?');\n process.exit(1);\n }\n\n // Set project root for path resolution\n setProjectRoot(projectRoot);\n\n // Set dev mode environment variable (drafts are built in dev mode)\n if (isDev) {\n process.env.MENO_DEV_BUILD = 'true';\n }\n\n console.log(`\uD83D\uDCC1 Building project: ${projectRoot}${isDev ? ' (dev mode - including drafts)' : ''}`);\n\n // Import and run build\n const { buildStaticPages } = await import('../build-static.ts');\n await buildStaticPages();\n}\n\nasync function runServe() {\n const projectRoot = process.cwd();\n const distPath = join(projectRoot, 'dist');\n\n // Validate dist directory exists\n if (!existsSync(distPath)) {\n console.error('\u274C No dist directory found. Run \"meno build\" first.');\n process.exit(1);\n }\n\n console.log(`\uD83D\uDCC1 Serving built files from: ${distPath}`);\n const server = await startStaticServer(distPath);\n console.log(`\uD83D\uDE80 Static server running at http://localhost:${server.port}`);\n\n // Keep the process alive\n await new Promise(() => {});\n}\n\nasync function runInit(projectName?: string) {\n if (!projectName) {\n console.error('\u274C Please provide a project name: meno init <project-name>');\n process.exit(1);\n }\n\n const projectPath = resolve(process.cwd(), projectName);\n\n if (existsSync(projectPath)) {\n console.error(`\u274C Directory \"${projectName}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n\uD83D\uDE80 Creating new meno project: ${projectName}\\n`);\n\n // Create project structure\n mkdirSync(projectPath, { recursive: true });\n mkdirSync(join(projectPath, 'pages'));\n mkdirSync(join(projectPath, 'components'));\n mkdirSync(join(projectPath, 'fonts'));\n mkdirSync(join(projectPath, 'images'));\n\n // Create default project.config.json\n const defaultConfig = {\n fonts: [],\n editor: {\n theme: 'dark'\n }\n };\n writeFileSync(\n join(projectPath, 'project.config.json'),\n JSON.stringify(defaultConfig, null, 2)\n );\n\n // Create default colors.json\n const defaultColors = {\n default: 'light',\n themes: {\n light: {\n label: 'Light',\n colors: {\n text: '#1f2937',\n bg: '#ffffff'\n }\n }\n }\n };\n writeFileSync(\n join(projectPath, 'colors.json'),\n JSON.stringify(defaultColors, null, 2)\n );\n\n // Create package.json for deployment\n const packageJson = {\n name: projectName,\n version: '1.0.0',\n private: true,\n scripts: {\n dev: 'meno dev',\n build: 'meno build',\n },\n dependencies: {\n 'meno-core': '^1.0.0'\n }\n };\n writeFileSync(\n join(projectPath, 'package.json'),\n JSON.stringify(packageJson, null, 2)\n );\n\n // Create .gitignore\n const gitignore = `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n\n# OS files\n.DS_Store\n`;\n writeFileSync(\n join(projectPath, '.gitignore'),\n gitignore\n );\n\n // Create netlify.toml\n const netlifyConfig = `[build]\n command = \"bun install && bun run build\"\n publish = \"dist\"\n\n[build.environment]\n BUN_VERSION = \"1\"\n`;\n writeFileSync(\n join(projectPath, 'netlify.toml'),\n netlifyConfig\n );\n\n // Create vercel.json\n const vercelConfig = {\n buildCommand: 'bun run build',\n outputDirectory: 'dist',\n installCommand: 'bun install'\n };\n writeFileSync(\n join(projectPath, 'vercel.json'),\n JSON.stringify(vercelConfig, null, 2)\n );\n\n // Create wrangler.toml for Cloudflare Pages\n const cloudflareConfig = `name = \"${projectName}\"\ncompatibility_date = \"2024-01-01\"\npages_build_output_dir = \"dist\"\n\n[build]\ncommand = \"bun install && bun run build\"\n`;\n writeFileSync(\n join(projectPath, 'wrangler.toml'),\n cloudflareConfig\n );\n\n // Create default index page\n const defaultPage = {\n meta: {\n title: 'Your Project Title',\n description: 'Your Project Description',\n keywords: '',\n ogTitle: 'Your Project Title',\n ogDescription: 'Your Project Description',\n ogType: 'website'\n },\n root: {\n type: 'node',\n tag: 'div',\n style: {\n base: {\n padding: '40px'\n },\n tablet: {},\n mobile: {}\n },\n children: [\n {\n type: 'node',\n tag: 'h1',\n style: {\n base: {}\n },\n children: 'Hello'\n }\n ]\n }\n };\n writeFileSync(\n join(projectPath, 'pages', 'index.json'),\n JSON.stringify(defaultPage, null, 2)\n );\n\n console.log('\u2705 Created project structure:');\n console.log(` ${projectName}/`);\n console.log(' \u251C\u2500\u2500 pages/');\n console.log(' \u2502 \u2514\u2500\u2500 index.json');\n console.log(' \u251C\u2500\u2500 components/');\n console.log(' \u251C\u2500\u2500 fonts/');\n console.log(' \u251C\u2500\u2500 images/');\n console.log(' \u251C\u2500\u2500 colors.json');\n console.log(' \u251C\u2500\u2500 project.config.json');\n console.log(' \u251C\u2500\u2500 package.json');\n console.log(' \u251C\u2500\u2500 netlify.toml');\n console.log(' \u251C\u2500\u2500 vercel.json');\n console.log(' \u251C\u2500\u2500 wrangler.toml');\n console.log(' \u2514\u2500\u2500 .gitignore');\n console.log('\\n\uD83C\uDF89 Project created successfully!\\n');\n console.log('Requirements:');\n console.log(' Bun - https://bun.sh');\n console.log('');\n console.log('Next steps:');\n console.log(` cd ${projectName}`);\n console.log(' bun install # Install dependencies');\n console.log(' bun run dev # Start dev server');\n console.log('');\n console.log('Deploy:');\n console.log(' Push to GitHub and connect to Netlify/Vercel/Cloudflare');\n console.log(' Config files included - auto-detected!');\n console.log('');\n}\n\n// Main\nswitch (command) {\n case 'dev':\n runDev();\n break;\n case 'build':\n runBuild(args.includes('--dev'));\n break;\n case 'serve':\n runServe();\n break;\n case 'init':\n runInit(args[1]);\n break;\n case '--help':\n case '-h':\n case undefined:\n printHelp();\n break;\n default:\n console.error(`Unknown command: ${command}`);\n printHelp();\n process.exit(1);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["#!/usr/bin/env node\n/**\n * meno CLI\n * Commands: dev, build, init\n */\n\nimport { resolve, join } from 'path';\nimport { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync } from 'fs';\nimport { setProjectRoot } from '../lib/server/projectContext';\nimport { generateBuildErrorPage, type BuildErrorsData } from '../lib/server/ssr/buildErrorOverlay';\nimport { createRuntimeServer, serveFile, fileExists as runtimeFileExists } from '../lib/server/runtime';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nfunction printHelp() {\n console.log(`\nmeno - Visual editor for JSON-based pages\n\nRequirements:\n - Bun or Node.js 18+\n\nUsage:\n meno <command> [options]\n\nCommands:\n dev Start development server with hot reload\n build Build static HTML files for production\n serve Serve built files from ./dist on port 8080\n init Initialize a new project\n\nOptions:\n build --dev Include draft pages in build (for local preview)\n\nExamples:\n meno dev Start dev server in current directory\n meno build Build static files to ./dist (excludes drafts)\n meno build --dev Build including draft pages\n meno serve Serve built files on port 8080\n meno init my-project Create new project in ./my-project\n`);\n}\n\n// Parse _headers file (Netlify/Cloudflare format)\nfunction parseHeadersFile(distPath: string): Map<string, Record<string, string>> {\n const headersPath = join(distPath, '_headers');\n const headers = new Map<string, Record<string, string>>();\n\n if (!existsSync(headersPath)) return headers;\n\n const content = readFileSync(headersPath, 'utf-8');\n let currentPath = '';\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n if (!line.startsWith(' ') && !line.startsWith('\\t')) {\n // Path line\n currentPath = trimmed;\n if (!headers.has(currentPath)) {\n headers.set(currentPath, {});\n }\n } else if (currentPath && trimmed.includes(':')) {\n // Header line\n const colonIndex = trimmed.indexOf(':');\n const name = trimmed.substring(0, colonIndex).trim();\n const value = trimmed.substring(colonIndex + 1).trim();\n headers.get(currentPath)![name] = value;\n }\n }\n\n return headers;\n}\n\n// Get headers matching a pathname\nfunction getMatchingHeaders(\n pathname: string,\n headersMap: Map<string, Record<string, string>>\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n headersMap.forEach((headers, pattern) => {\n if (pattern === pathname || pattern === '/*') {\n Object.assign(result, headers);\n } else if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n if (pathname.startsWith(prefix)) {\n Object.assign(result, headers);\n }\n }\n });\n\n return result;\n}\n\n// Start static file server on port 8080 (non-blocking)\nasync function startStaticServer(distPath: string) {\n const { SERVE_PORT } = await import('../lib/shared/constants');\n\n // Parse _headers file once on startup\n const headersMap = parseHeadersFile(distPath);\n\n const server = await createRuntimeServer({\n port: SERVE_PORT,\n hostname: 'localhost',\n async fetch(req: Request) {\n const url = new URL(req.url);\n let pathname = url.pathname;\n\n // Check for build errors and show overlay (except for _errors.json itself)\n if (pathname !== '/_errors.json') {\n const errorsPath = join(distPath, '_errors.json');\n if (existsSync(errorsPath)) {\n try {\n const errorsData: BuildErrorsData = JSON.parse(readFileSync(errorsPath, 'utf-8'));\n return new Response(generateBuildErrorPage(errorsData), {\n headers: { 'Content-Type': 'text/html; charset=utf-8' },\n });\n } catch {\n // If we can't parse errors file, continue normally\n }\n }\n }\n\n // Default to index.html for root\n if (pathname === '/') {\n pathname = '/index.html';\n }\n\n // Get custom headers for this path\n const customHeaders = getMatchingHeaders(pathname, headersMap);\n\n // Try to serve the file\n const filePath = join(distPath, pathname);\n\n // Check if file exists and serve it\n if (await runtimeFileExists(filePath)) {\n return await serveFile(filePath, customHeaders);\n }\n\n // Try with .html extension for clean URLs\n const htmlPath = filePath.endsWith('.html') ? filePath : `${filePath}.html`;\n if (await runtimeFileExists(htmlPath)) {\n return await serveFile(htmlPath, customHeaders);\n }\n\n // Try index.html in directory\n const indexPath = join(filePath, 'index.html');\n if (await runtimeFileExists(indexPath)) {\n return await serveFile(indexPath, customHeaders);\n }\n\n return new Response('Not Found', { status: 404 });\n },\n });\n\n return server;\n}\n\nasync function runDev() {\n const projectRoot = process.cwd();\n\n // Validate project structure\n if (!existsSync(join(projectRoot, 'pages'))) {\n console.error('\u274C No pages directory found. Are you in a valid project directory?');\n console.error(' Run \"meno init <project-name>\" to create a new project.');\n process.exit(1);\n }\n\n // Set project root for path resolution\n setProjectRoot(projectRoot);\n\n console.log(`\uD83D\uDCC1 Project root: ${projectRoot}`);\n\n // Start static server on 8080 if dist exists\n const distPath = join(projectRoot, 'dist');\n if (existsSync(distPath)) {\n const staticServer = await startStaticServer(distPath);\n console.log(`\uD83D\uDE80 Static server running at http://localhost:${staticServer.port}`);\n }\n\n // Import and run the dev server (it handles all initialization internally)\n await import('../entries/server-router');\n}\n\nasync function runBuild(isDev: boolean = false) {\n const projectRoot = process.cwd();\n\n // Validate project structure\n if (!existsSync(join(projectRoot, 'pages'))) {\n console.error('\u274C No pages directory found. Are you in a valid project directory?');\n process.exit(1);\n }\n\n // Set project root for path resolution\n setProjectRoot(projectRoot);\n\n // Set dev mode environment variable (drafts are built in dev mode)\n if (isDev) {\n process.env.MENO_DEV_BUILD = 'true';\n }\n\n console.log(`\uD83D\uDCC1 Building project: ${projectRoot}${isDev ? ' (dev mode - including drafts)' : ''}`);\n\n // Import and run build\n const { buildStaticPages } = await import('../build-static.ts');\n await buildStaticPages();\n}\n\nasync function runServe() {\n const projectRoot = process.cwd();\n const distPath = join(projectRoot, 'dist');\n\n // Validate dist directory exists\n if (!existsSync(distPath)) {\n console.error('\u274C No dist directory found. Run \"meno build\" first.');\n process.exit(1);\n }\n\n console.log(`\uD83D\uDCC1 Serving built files from: ${distPath}`);\n const server = await startStaticServer(distPath);\n console.log(`\uD83D\uDE80 Static server running at http://localhost:${server.port}`);\n\n // Keep the process alive\n await new Promise(() => {});\n}\n\nasync function runInit(projectName?: string) {\n if (!projectName) {\n console.error('\u274C Please provide a project name: meno init <project-name>');\n process.exit(1);\n }\n\n const projectPath = resolve(process.cwd(), projectName);\n\n if (existsSync(projectPath)) {\n console.error(`\u274C Directory \"${projectName}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n\uD83D\uDE80 Creating new meno project: ${projectName}\\n`);\n\n // Create project structure\n mkdirSync(projectPath, { recursive: true });\n mkdirSync(join(projectPath, 'pages'));\n mkdirSync(join(projectPath, 'components'));\n mkdirSync(join(projectPath, 'fonts'));\n mkdirSync(join(projectPath, 'images'));\n\n // Create default project.config.json\n const defaultConfig = {\n fonts: [],\n editor: {\n theme: 'dark'\n }\n };\n writeFileSync(\n join(projectPath, 'project.config.json'),\n JSON.stringify(defaultConfig, null, 2)\n );\n\n // Create default colors.json\n const defaultColors = {\n default: 'light',\n themes: {\n light: {\n label: 'Light',\n colors: {\n text: '#1f2937',\n bg: '#ffffff'\n }\n }\n }\n };\n writeFileSync(\n join(projectPath, 'colors.json'),\n JSON.stringify(defaultColors, null, 2)\n );\n\n // Create package.json for deployment\n const packageJson = {\n name: projectName,\n version: '1.0.0',\n private: true,\n scripts: {\n dev: 'meno dev',\n build: 'meno build',\n },\n dependencies: {\n 'meno-core': '^1.0.0'\n }\n };\n writeFileSync(\n join(projectPath, 'package.json'),\n JSON.stringify(packageJson, null, 2)\n );\n\n // Create .claude/tools/ with screenshot tool\n mkdirSync(join(projectPath, '.claude', 'tools'), { recursive: true });\n\n const screenshotToolSrc = join(import.meta.dirname, '..', '..', '..', 'example', '.claude', 'tools', 'screenshot.mjs');\n if (existsSync(screenshotToolSrc)) {\n cpSync(screenshotToolSrc, join(projectPath, '.claude', 'tools', 'screenshot.mjs'));\n }\n\n // Create CLAUDE.md with project instructions\n const claudeMd = `# ${projectName}\n\nA Meno project - visual editor that generates websites from JSON files.\n\n## Dev Server\n\n\\`\\`\\`bash\nbun run dev # Start dev server on port 3000\n\\`\\`\\`\n\n## Screenshot Tool\n\nTake a screenshot of any element by its node ID:\n\\`\\`\\`bash\nnpx puppeteer browsers install chrome && node .claude/tools/screenshot.mjs <nodeId> --page /about\n\\`\\`\\`\nNode IDs can be found in the page JSON files under the \\`id\\` field of each node.\n`;\n writeFileSync(join(projectPath, 'CLAUDE.md'), claudeMd);\n\n // Create .gitignore\n const gitignore = `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n\n# OS files\n.DS_Store\n`;\n writeFileSync(\n join(projectPath, '.gitignore'),\n gitignore\n );\n\n // Create netlify.toml\n const netlifyConfig = `[build]\n command = \"bun install && bun run build\"\n publish = \"dist\"\n\n[build.environment]\n BUN_VERSION = \"1\"\n`;\n writeFileSync(\n join(projectPath, 'netlify.toml'),\n netlifyConfig\n );\n\n // Create vercel.json\n const vercelConfig = {\n buildCommand: 'bun run build',\n outputDirectory: 'dist',\n installCommand: 'bun install'\n };\n writeFileSync(\n join(projectPath, 'vercel.json'),\n JSON.stringify(vercelConfig, null, 2)\n );\n\n // Create wrangler.toml for Cloudflare Pages\n const cloudflareConfig = `name = \"${projectName}\"\ncompatibility_date = \"2024-01-01\"\npages_build_output_dir = \"dist\"\n\n[build]\ncommand = \"bun install && bun run build\"\n`;\n writeFileSync(\n join(projectPath, 'wrangler.toml'),\n cloudflareConfig\n );\n\n // Create default index page\n const defaultPage = {\n meta: {\n title: 'Your Project Title',\n description: 'Your Project Description',\n keywords: '',\n ogTitle: 'Your Project Title',\n ogDescription: 'Your Project Description',\n ogType: 'website'\n },\n root: {\n type: 'node',\n tag: 'div',\n style: {\n base: {\n padding: '40px'\n },\n tablet: {},\n mobile: {}\n },\n children: [\n {\n type: 'node',\n tag: 'h1',\n style: {\n base: {}\n },\n children: 'Hello'\n }\n ]\n }\n };\n writeFileSync(\n join(projectPath, 'pages', 'index.json'),\n JSON.stringify(defaultPage, null, 2)\n );\n\n console.log('\u2705 Created project structure:');\n console.log(` ${projectName}/`);\n console.log(' \u251C\u2500\u2500 .claude/');\n console.log(' \u2502 \u2514\u2500\u2500 tools/');\n console.log(' \u2502 \u2514\u2500\u2500 screenshot.mjs');\n console.log(' \u251C\u2500\u2500 pages/');\n console.log(' \u2502 \u2514\u2500\u2500 index.json');\n console.log(' \u251C\u2500\u2500 components/');\n console.log(' \u251C\u2500\u2500 fonts/');\n console.log(' \u251C\u2500\u2500 images/');\n console.log(' \u251C\u2500\u2500 colors.json');\n console.log(' \u251C\u2500\u2500 project.config.json');\n console.log(' \u251C\u2500\u2500 package.json');\n console.log(' \u251C\u2500\u2500 CLAUDE.md');\n console.log(' \u251C\u2500\u2500 netlify.toml');\n console.log(' \u251C\u2500\u2500 vercel.json');\n console.log(' \u251C\u2500\u2500 wrangler.toml');\n console.log(' \u2514\u2500\u2500 .gitignore');\n console.log('\\n\uD83C\uDF89 Project created successfully!\\n');\n console.log('Requirements:');\n console.log(' Bun - https://bun.sh');\n console.log('');\n console.log('Next steps:');\n console.log(` cd ${projectName}`);\n console.log(' bun install # Install dependencies');\n console.log(' bun run dev # Start dev server');\n console.log('');\n console.log('Deploy:');\n console.log(' Push to GitHub and connect to Netlify/Vercel/Cloudflare');\n console.log(' Config files included - auto-detected!');\n console.log('');\n}\n\n// Main\nswitch (command) {\n case 'dev':\n runDev();\n break;\n case 'build':\n runBuild(args.includes('--dev'));\n break;\n case 'serve':\n runServe();\n break;\n case 'init':\n runInit(args[1]);\n break;\n case '--help':\n case '-h':\n case undefined:\n printHelp();\n break;\n default:\n console.error(`Unknown command: ${command}`);\n printHelp();\n process.exit(1);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -9,17 +9,17 @@ import {
9
9
  hashContent,
10
10
  injectTrackingScript,
11
11
  isCMSPage
12
- } from "./chunks/chunk-3NOZVNM4.js";
13
- import "./chunks/chunk-GKICS7CF.js";
14
- import "./chunks/chunk-A6KWUEA6.js";
15
- import "./chunks/chunk-YSZ5IUFM.js";
12
+ } from "./chunks/chunk-ACK7AURE.js";
13
+ import "./chunks/chunk-UGHOL7IP.js";
14
+ import "./chunks/chunk-24KKYW25.js";
15
+ import "./chunks/chunk-5Z5VQRTJ.js";
16
16
  import "./chunks/chunk-WQFG7PAH.js";
17
- import "./chunks/chunk-LOJLO2EY.js";
18
- import "./chunks/chunk-V4SVSX3X.js";
19
- import "./chunks/chunk-OJ5SROQN.js";
17
+ import "./chunks/chunk-S2HXJTAF.js";
18
+ import "./chunks/chunk-6AYGKR6Y.js";
19
+ import "./chunks/chunk-ITVPRBD6.js";
20
20
  import "./chunks/chunk-PGH3ATYI.js";
21
21
  import "./chunks/chunk-UB44F4Z2.js";
22
- import "./chunks/chunk-Z7SAOCDG.js";
22
+ import "./chunks/chunk-DIYO4RBJ.js";
23
23
  import "./chunks/chunk-KSBZ2L7C.js";
24
24
  export {
25
25
  buildCMSItemPath,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  projectPaths
3
- } from "./chunk-YSZ5IUFM.js";
3
+ } from "./chunk-5Z5VQRTJ.js";
4
4
  import {
5
5
  fileExists,
6
6
  readTextFile
@@ -181,6 +181,14 @@ var ConfigService = class {
181
181
  }
182
182
  return this.config.baseComponent;
183
183
  }
184
+ /**
185
+ * Get image format setting
186
+ * Returns 'webp' (default) or 'avif'
187
+ */
188
+ getImageFormat() {
189
+ if (this.config?.imageFormat === "avif") return "avif";
190
+ return "webp";
191
+ }
184
192
  /**
185
193
  * Get raw config value by key (for extension)
186
194
  */
@@ -197,4 +205,4 @@ export {
197
205
  ConfigService,
198
206
  configService
199
207
  };
200
- //# sourceMappingURL=chunk-A6KWUEA6.js.map
208
+ //# sourceMappingURL=chunk-24KKYW25.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../lib/server/services/configService.ts"],
4
+ "sourcesContent": ["/**\n * Config Service\n * Centralized configuration loading and access\n *\n * Consolidates multiple config loaders into a single service that loads\n * the project.config.json file once and exposes typed sections.\n */\n\nimport type { BreakpointConfig, BreakpointConfigInput, BreakpointEntry } from '../../shared/breakpoints';\nimport { DEFAULT_BREAKPOINTS, normalizeBreakpointConfig } from '../../shared/breakpoints';\nimport type { ResponsiveScales, BreakpointScales } from '../../shared/responsiveScaling';\nimport { DEFAULT_RESPONSIVE_SCALES } from '../../shared/responsiveScaling';\nimport type { I18nConfig } from '../../shared/types/components';\nimport type { LibrariesConfig, JSLibraryConfig, CSSLibraryConfig } from '../../shared/types/libraries';\nimport type { CSPConfig } from '../../shared/types/config';\nimport { DEFAULT_I18N_CONFIG, migrateI18nConfig } from '../../shared/i18n';\nimport { projectPaths } from '../projectContext';\nimport { readTextFile, fileExists } from '../runtime';\n\n/**\n * Icons configuration\n */\nexport interface IconsConfig {\n favicon?: string;\n appleTouchIcon?: string;\n}\n\n/**\n * Raw project config structure from project.config.json\n */\nexport type ImageFormat = 'webp' | 'avif';\n\ninterface RawProjectConfig {\n breakpoints?: BreakpointConfigInput;\n responsiveScales?: Partial<ResponsiveScales>;\n i18n?: unknown;\n icons?: IconsConfig;\n libraries?: LibrariesConfig;\n csp?: CSPConfig;\n baseComponent?: string;\n imageFormat?: ImageFormat;\n}\n\n/**\n * ConfigService\n * Loads project configuration once and provides typed access to sections\n */\nexport class ConfigService {\n private config: RawProjectConfig | null = null;\n private loaded = false;\n\n /**\n * Load configuration from project.config.json\n * Safe to call multiple times - only loads once\n */\n async load(): Promise<void> {\n if (this.loaded) {\n return;\n }\n\n try {\n if (await fileExists(projectPaths.config())) {\n const content = await readTextFile(projectPaths.config());\n this.config = JSON.parse(content);\n }\n } catch {\n // Fall through to defaults\n this.config = null;\n }\n\n this.loaded = true;\n }\n\n /**\n * Check if configuration has been loaded\n */\n isLoaded(): boolean {\n return this.loaded;\n }\n\n /**\n * Reset the service (for testing)\n */\n reset(): void {\n this.config = null;\n this.loaded = false;\n }\n\n /**\n * Get breakpoint configuration\n * Returns validated and normalized breakpoints (always object format)\n * Supports both legacy format { tablet: 1024 } and new format { tablet: { breakpoint: 1024, previewPoint: 768 } }\n */\n getBreakpoints(): BreakpointConfig {\n if (!this.config?.breakpoints || typeof this.config.breakpoints !== 'object') {\n return { ...DEFAULT_BREAKPOINTS };\n }\n\n // Validate breakpoint values before normalization\n const validInput: BreakpointConfigInput = {};\n for (const [key, value] of Object.entries(this.config.breakpoints)) {\n if (typeof value === 'number' && value > 0) {\n // Legacy format: number\n validInput[key] = value;\n } else if (typeof value === 'object' && value !== null) {\n // New format: object with breakpoint and optional previewPoint\n const entry = value as BreakpointEntry;\n if (typeof entry.breakpoint === 'number' && entry.breakpoint > 0) {\n validInput[key] = {\n breakpoint: entry.breakpoint,\n previewPoint: typeof entry.previewPoint === 'number' && entry.previewPoint > 0\n ? entry.previewPoint\n : entry.breakpoint,\n };\n }\n }\n }\n\n // Return normalized breakpoints or defaults if none valid\n if (Object.keys(validInput).length === 0) {\n return { ...DEFAULT_BREAKPOINTS };\n }\n\n return normalizeBreakpointConfig(validInput);\n }\n\n /**\n * Get i18n configuration\n * Automatically migrates old string[] format to LocaleConfig[] format\n */\n getI18n(): I18nConfig {\n if (!this.config?.i18n) {\n return { ...DEFAULT_I18N_CONFIG };\n }\n\n return migrateI18nConfig(this.config.i18n);\n }\n\n /**\n * Deep merge scale categories, preserving user-defined breakpoints\n * while filling in missing values from defaults\n */\n private mergeScaleCategory(\n userScales: BreakpointScales | undefined,\n defaultScales: BreakpointScales | undefined\n ): BreakpointScales | undefined {\n if (!userScales && !defaultScales) return undefined;\n if (!userScales) return defaultScales ? { ...defaultScales } : undefined;\n if (!defaultScales) return { ...userScales };\n\n // User scales take precedence, but include defaults for breakpoints not specified\n return {\n ...defaultScales,\n ...userScales,\n };\n }\n\n /**\n * Get responsive scales configuration\n * Supports dynamic breakpoints - scales are keyed by breakpoint name\n * Deep merges scale categories to preserve user breakpoint definitions\n */\n getResponsiveScales(): ResponsiveScales {\n if (!this.config?.responsiveScales || typeof this.config.responsiveScales !== 'object') {\n return { ...DEFAULT_RESPONSIVE_SCALES };\n }\n\n const userScales = this.config.responsiveScales;\n\n return {\n enabled: userScales.enabled ?? DEFAULT_RESPONSIVE_SCALES.enabled,\n baseReference: userScales.baseReference ?? DEFAULT_RESPONSIVE_SCALES.baseReference,\n fontSize: this.mergeScaleCategory(\n userScales.fontSize as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.fontSize\n ),\n padding: this.mergeScaleCategory(\n userScales.padding as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.padding\n ),\n margin: this.mergeScaleCategory(\n userScales.margin as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.margin\n ),\n gap: this.mergeScaleCategory(\n userScales.gap as BreakpointScales | undefined,\n DEFAULT_RESPONSIVE_SCALES.gap\n ),\n };\n }\n\n /**\n * Get icons configuration\n * Returns empty object if not configured\n */\n getIcons(): IconsConfig {\n if (!this.config?.icons || typeof this.config.icons !== 'object') {\n return {};\n }\n\n return this.config.icons;\n }\n\n /**\n * Get libraries configuration\n * Returns empty arrays if not configured\n * Normalizes string URLs to object format for backwards compatibility\n */\n getLibraries(): LibrariesConfig {\n if (!this.config?.libraries || typeof this.config.libraries !== 'object') {\n return { js: [], css: [] };\n }\n\n const libs = this.config.libraries;\n\n // Normalize JS libraries: support both string URLs and object format\n const normalizedJs = Array.isArray(libs.js)\n ? libs.js.map((lib) =>\n typeof lib === 'string' ? { url: lib } : lib\n ) as JSLibraryConfig[]\n : [];\n\n // Normalize CSS libraries: support both string URLs and object format\n const normalizedCss = Array.isArray(libs.css)\n ? libs.css.map((lib) =>\n typeof lib === 'string' ? { url: lib } : lib\n ) as CSSLibraryConfig[]\n : [];\n\n return {\n js: normalizedJs,\n css: normalizedCss,\n };\n }\n\n /**\n * Get CSP configuration\n * Returns empty object if not configured\n */\n getCSP(): CSPConfig {\n if (!this.config?.csp || typeof this.config.csp !== 'object') {\n return {};\n }\n\n return this.config.csp;\n }\n\n /**\n * Get base component name for new pages\n * Returns undefined if not configured\n */\n getBaseComponent(): string | undefined {\n if (!this.config?.baseComponent || typeof this.config.baseComponent !== 'string') {\n return undefined;\n }\n return this.config.baseComponent;\n }\n\n /**\n * Get image format setting\n * Returns 'webp' (default) or 'avif'\n */\n getImageFormat(): ImageFormat {\n if (this.config?.imageFormat === 'avif') return 'avif';\n return 'webp';\n }\n\n /**\n * Get raw config value by key (for extension)\n */\n getRaw<T>(key: string): T | undefined {\n if (!this.config) {\n return undefined;\n }\n return (this.config as Record<string, unknown>)[key] as T | undefined;\n }\n}\n\n/**\n * Singleton instance for global access\n * Use this for convenience, or create your own instance for testing\n */\nexport const configService = new ConfigService();\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -17,10 +17,14 @@ async function minifyJS(code) {
17
17
  return minifyWithEsbuild(code);
18
18
  }
19
19
  async function validateJS(code) {
20
- if (isBun) {
21
- return validateWithBun(code);
20
+ try {
21
+ if (isBun) {
22
+ return await validateWithBun(code);
23
+ }
24
+ return await validateWithEsbuild(code);
25
+ } catch {
26
+ return null;
22
27
  }
23
- return validateWithEsbuild(code);
24
28
  }
25
29
  async function bundleWithBun(entrypoint, opts) {
26
30
  try {
@@ -460,4 +464,4 @@ export {
460
464
  resolveProjectPath,
461
465
  resolvePackagePath
462
466
  };
463
- //# sourceMappingURL=chunk-YSZ5IUFM.js.map
467
+ //# sourceMappingURL=chunk-5Z5VQRTJ.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../lib/server/runtime/bundler.ts", "../../lib/server/runtime/httpServer.ts", "../../lib/server/runtime/index.ts", "../../lib/server/projectContext.ts"],
4
+ "sourcesContent": ["/**\n * Runtime-agnostic bundler abstraction.\n * Uses Bun.build when available, falls back to esbuild for Node.js.\n */\n\nconst isBun = typeof (globalThis as any).Bun !== 'undefined';\n\nexport interface BundleResult {\n code: string;\n success: boolean;\n errors: string[];\n}\n\nexport interface BundleOptions {\n target?: 'browser' | 'node';\n format?: 'esm' | 'cjs';\n minify?: boolean;\n sourcemap?: 'inline' | 'external' | boolean;\n /** When true, throw on build errors instead of returning them */\n throw?: boolean;\n}\n\n/**\n * Bundle a file entry point.\n * Returns the bundled code as a string.\n */\nexport async function bundleFile(\n entrypoint: string,\n opts: BundleOptions = {},\n): Promise<BundleResult> {\n if (isBun) {\n return bundleWithBun(entrypoint, opts);\n }\n return bundleWithEsbuild(entrypoint, opts);\n}\n\n/**\n * Minify JavaScript code.\n */\nexport async function minifyJS(code: string): Promise<BundleResult> {\n if (isBun) {\n return minifyWithBun(code);\n }\n return minifyWithEsbuild(code);\n}\n\n/**\n * Validate JavaScript syntax (check for errors without producing output).\n */\nexport async function validateJS(code: string): Promise<string | null> {\n try {\n if (isBun) {\n return await validateWithBun(code);\n }\n return await validateWithEsbuild(code);\n } catch {\n // Validation not available (e.g., Cloudflare Workers) \u2014 skip and trust the JS\n return null;\n }\n}\n\n// \u2500\u2500 Bun implementations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function bundleWithBun(\n entrypoint: string,\n opts: BundleOptions,\n): Promise<BundleResult> {\n try {\n const result = await Bun.build({\n entrypoints: [entrypoint],\n target: opts.target || 'browser',\n format: opts.format || 'esm',\n minify: opts.minify ?? false,\n sourcemap: opts.sourcemap === true ? 'inline' : (opts.sourcemap || 'none'),\n throw: opts.throw ?? false,\n });\n\n if (result.success && result.outputs[0]) {\n const code = await result.outputs[0].text();\n return { code, success: true, errors: [] };\n }\n\n const errors = (result.logs || []).map((log: any) => {\n const parts: string[] = [];\n if (log.position?.file) parts.push(`File: ${log.position.file}`);\n if (log.position?.line) parts.push(`Line ${log.position.line}:${log.position.column || 0}`);\n if (log.position?.lineText) parts.push(log.position.lineText);\n if (log.message) parts.push(log.message);\n return parts.length > 0 ? parts.join('\\n') : String(log);\n });\n\n return { code: '', success: false, errors };\n } catch (err: any) {\n if (opts.throw) throw err;\n\n const errors: string[] = [];\n if (err.logs && Array.isArray(err.logs)) {\n for (const log of err.logs) {\n const parts: string[] = [];\n if (log.position?.line) parts.push(`Line ${log.position.line}:${log.position.column || 0}`);\n if (log.position?.lineText) parts.push(log.position.lineText);\n if (log.message) parts.push(log.message);\n errors.push(parts.length > 0 ? parts.join('\\n') : String(log));\n }\n } else {\n errors.push(err.message || String(err));\n }\n\n return { code: '', success: false, errors };\n }\n}\n\nasync function minifyWithBun(code: string): Promise<BundleResult> {\n const { writeFile, rm } = await import('fs/promises');\n const { join } = await import('path');\n const tempFile = join('/tmp', `meno-minify-${Date.now()}.js`);\n\n try {\n await writeFile(tempFile, code, 'utf-8');\n\n const result = await Bun.build({\n entrypoints: [tempFile],\n minify: true,\n throw: true,\n });\n\n if (result.outputs.length > 0) {\n const minified = await result.outputs[0].text();\n return { code: minified, success: true, errors: [] };\n }\n\n return { code: '', success: false, errors: ['Minification produced no output'] };\n } catch (err: any) {\n const { inspect } = await import('./fs');\n let details = '';\n if (err.logs && Array.isArray(err.logs)) {\n details = err.logs.map((log: any) => {\n const parts: string[] = [];\n if (log.position?.line) parts.push(`Line ${log.position.line}:${log.position.column || 0}`);\n if (log.position?.lineText) parts.push(log.position.lineText);\n if (log.message) parts.push(log.message);\n return parts.length > 0 ? parts.join('\\n') : String(log);\n }).join('\\n\\n');\n }\n if (!details) {\n try { details = inspect(err); } catch { details = err.stack || err.message || String(err); }\n }\n return { code: '', success: false, errors: [details] };\n } finally {\n try { const { rm } = await import('fs/promises'); await rm(tempFile, { force: true }); } catch {}\n }\n}\n\nasync function validateWithBun(code: string): Promise<string | null> {\n const { writeFile, rm } = await import('fs/promises');\n const { join } = await import('path');\n const tempFile = join('/tmp', `meno-validate-${Date.now()}-${Math.random().toString(36).slice(2)}.js`);\n\n try {\n await writeFile(tempFile, code, 'utf-8');\n await Bun.build({\n entrypoints: [tempFile],\n minify: true,\n throw: true,\n });\n return null; // Valid\n } catch (err: any) {\n const { inspect } = await import('./fs');\n let details = '';\n if (err.logs && Array.isArray(err.logs)) {\n details = err.logs.map((log: any) => {\n const parts: string[] = [];\n if (log.position?.line) parts.push(`Line ${log.position.line}:${log.position.column || 0}`);\n if (log.position?.lineText) parts.push(log.position.lineText);\n if (log.message) parts.push(log.message);\n return parts.length > 0 ? parts.join('\\n') : String(log);\n }).join('\\n\\n');\n }\n if (!details) {\n try { details = inspect(err); } catch { details = err.stack || err.message || String(err); }\n }\n return details || 'Unknown JavaScript error';\n } finally {\n try { await rm(tempFile, { force: true }); } catch {}\n }\n}\n\n// \u2500\u2500 esbuild implementations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function getEsbuild() {\n return await import('esbuild');\n}\n\nasync function bundleWithEsbuild(\n entrypoint: string,\n opts: BundleOptions,\n): Promise<BundleResult> {\n const esbuild = await getEsbuild();\n\n try {\n const result = await esbuild.build({\n entryPoints: [entrypoint],\n bundle: true,\n write: false,\n platform: opts.target === 'node' ? 'node' : 'browser',\n format: opts.format || 'esm',\n minify: opts.minify ?? false,\n sourcemap: opts.sourcemap === true ? 'inline' : (opts.sourcemap === 'inline' ? 'inline' : opts.sourcemap === 'external' ? true : false),\n jsx: 'automatic',\n jsxImportSource: 'react',\n logLevel: 'silent',\n });\n\n if (result.outputFiles && result.outputFiles.length > 0) {\n return { code: result.outputFiles[0].text, success: true, errors: [] };\n }\n\n return { code: '', success: false, errors: ['Build produced no output'] };\n } catch (err: any) {\n if (opts.throw) throw err;\n\n const errors: string[] = [];\n if (err.errors && Array.isArray(err.errors)) {\n for (const e of err.errors) {\n const parts: string[] = [];\n if (e.location?.file) parts.push(`File: ${e.location.file}`);\n if (e.location?.line) parts.push(`Line ${e.location.line}:${e.location.column || 0}`);\n if (e.location?.lineText) parts.push(e.location.lineText);\n if (e.text) parts.push(e.text);\n errors.push(parts.length > 0 ? parts.join('\\n') : String(e));\n }\n } else {\n errors.push(err.message || String(err));\n }\n\n return { code: '', success: false, errors };\n }\n}\n\nasync function minifyWithEsbuild(code: string): Promise<BundleResult> {\n const esbuild = await getEsbuild();\n\n try {\n const result = await esbuild.transform(code, {\n minify: true,\n loader: 'js',\n });\n\n return { code: result.code, success: true, errors: [] };\n } catch (err: any) {\n const errors: string[] = [];\n if (err.errors && Array.isArray(err.errors)) {\n for (const e of err.errors) {\n const parts: string[] = [];\n if (e.location?.line) parts.push(`Line ${e.location.line}:${e.location.column || 0}`);\n if (e.location?.lineText) parts.push(e.location.lineText);\n if (e.text) parts.push(e.text);\n errors.push(parts.length > 0 ? parts.join('\\n') : String(e));\n }\n } else {\n errors.push(err.message || String(err));\n }\n\n return { code: '', success: false, errors };\n }\n}\n\nasync function validateWithEsbuild(code: string): Promise<string | null> {\n const esbuild = await getEsbuild();\n\n try {\n await esbuild.transform(code, { loader: 'js' });\n return null; // Valid\n } catch (err: any) {\n const errors: string[] = [];\n if (err.errors && Array.isArray(err.errors)) {\n for (const e of err.errors) {\n const parts: string[] = [];\n if (e.location?.line) parts.push(`Line ${e.location.line}:${e.location.column || 0}`);\n if (e.location?.lineText) parts.push(e.location.lineText);\n if (e.text) parts.push(e.text);\n errors.push(parts.length > 0 ? parts.join('\\n') : String(e));\n }\n } else {\n errors.push(err.message || String(err));\n }\n\n return errors.join('\\n\\n') || 'Unknown JavaScript error';\n }\n}\n", "/**\n * Runtime-agnostic HTTP server abstraction.\n * Uses Bun.serve when available, falls back to Node.js http + ws.\n */\n\nconst isBun = typeof globalThis.Bun !== 'undefined';\n\nexport interface RuntimeServer {\n port: number;\n stop(): void;\n}\n\nexport interface RuntimeWSClient {\n send(data: string | ArrayBuffer | Uint8Array): void;\n readyState: number;\n close(code?: number, reason?: string): void;\n}\n\nexport interface ServerOptions {\n port: number;\n hostname?: string;\n fetch: (req: Request, upgradeWebSocket: (req: Request) => boolean) => Promise<Response | undefined>;\n websocket?: {\n open(ws: RuntimeWSClient): void;\n message(ws: RuntimeWSClient, data: string): void;\n close(ws: RuntimeWSClient): void;\n };\n /** Path to upgrade to WebSocket (e.g., \"/__hmr\") */\n wsPath?: string;\n}\n\nexport async function createRuntimeServer(\n options: ServerOptions,\n): Promise<RuntimeServer> {\n if (isBun) {\n return createBunServer(options);\n }\n return createNodeServer(options);\n}\n\n// \u2500\u2500 Bun implementation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction createBunServer(options: ServerOptions): RuntimeServer {\n const { port, hostname, fetch, websocket, wsPath } = options;\n\n const bunConfig: any = {\n port,\n hostname: hostname || 'localhost',\n\n async fetch(req: Request, server: any) {\n // Create upgrade function that delegates to Bun's server.upgrade\n const upgradeWebSocket = (upgradeReq: Request): boolean => {\n return server.upgrade(upgradeReq);\n };\n\n const response = await fetch(req, upgradeWebSocket);\n return response || new Response('Not Found', { status: 404 });\n },\n };\n\n if (websocket) {\n bunConfig.websocket = {\n open(ws: RuntimeWSClient) {\n websocket.open(ws);\n },\n message(ws: RuntimeWSClient, message: unknown) {\n websocket.message(ws, String(message));\n },\n close(ws: RuntimeWSClient) {\n websocket.close(ws);\n },\n };\n }\n\n const server = Bun.serve(bunConfig);\n\n return {\n port: server.port ?? port,\n stop() {\n server.stop();\n },\n };\n}\n\n// \u2500\u2500 Node.js implementation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function createNodeServer(options: ServerOptions): Promise<RuntimeServer> {\n const { port, hostname, fetch, websocket, wsPath } = options;\n const http = await import('http');\n\n const server = http.createServer(async (nodeReq, nodeRes) => {\n try {\n // Convert Node.js IncomingMessage \u2192 Web Request\n const url = `http://${hostname || 'localhost'}:${port}${nodeReq.url || '/'}`;\n const headers = new Headers();\n for (const [key, value] of Object.entries(nodeReq.headers)) {\n if (value) {\n if (Array.isArray(value)) {\n for (const v of value) headers.append(key, v);\n } else {\n headers.set(key, value);\n }\n }\n }\n\n let body: ReadableStream | null = null;\n if (nodeReq.method !== 'GET' && nodeReq.method !== 'HEAD') {\n const { Readable } = await import('stream');\n body = Readable.toWeb(nodeReq) as unknown as ReadableStream;\n }\n\n const request = new Request(url, {\n method: nodeReq.method || 'GET',\n headers,\n body,\n // @ts-ignore - duplex is needed for streaming request bodies in Node\n duplex: body ? 'half' : undefined,\n });\n\n // No-op upgrade function for non-upgrade requests\n const upgradeWebSocket = (): boolean => false;\n\n const response = await fetch(request, upgradeWebSocket);\n if (!response) {\n nodeRes.writeHead(404);\n nodeRes.end('Not Found');\n return;\n }\n\n // Convert Web Response \u2192 Node.js ServerResponse\n nodeRes.writeHead(response.status, Object.fromEntries(response.headers.entries()));\n\n if (response.body) {\n const reader = response.body.getReader();\n const pump = async () => {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n nodeRes.end();\n break;\n }\n const canContinue = nodeRes.write(value);\n if (!canContinue) {\n await new Promise<void>((resolve) => nodeRes.once('drain', resolve));\n }\n }\n };\n await pump();\n } else {\n const text = await response.text();\n nodeRes.end(text);\n }\n } catch (err) {\n console.error('Server error:', err);\n if (!nodeRes.headersSent) {\n nodeRes.writeHead(500);\n nodeRes.end('Internal Server Error');\n }\n }\n });\n\n // WebSocket support via 'ws' package\n if (websocket && wsPath) {\n try {\n const { WebSocketServer } = await import('ws');\n const wss = new WebSocketServer({ noServer: true });\n\n server.on('upgrade', (request, socket, head) => {\n const pathname = new URL(\n request.url || '/',\n `http://${hostname || 'localhost'}:${port}`,\n ).pathname;\n\n if (pathname === wsPath) {\n wss.handleUpgrade(request, socket, head, (ws) => {\n wss.emit('connection', ws, request);\n });\n } else {\n socket.destroy();\n }\n });\n\n wss.on('connection', (ws) => {\n const client: RuntimeWSClient = {\n send(data) {\n if (ws.readyState === 1) { // OPEN\n ws.send(data);\n }\n },\n get readyState() {\n return ws.readyState;\n },\n close(code, reason) {\n ws.close(code, reason);\n },\n };\n\n websocket.open(client);\n\n ws.on('message', (data) => {\n websocket.message(client, data.toString());\n });\n\n ws.on('close', () => {\n websocket.close(client);\n });\n });\n } catch {\n console.warn('WebSocket support requires the \"ws\" package. Install it with: npm install ws');\n }\n }\n\n // Start listening\n return new Promise((resolve, reject) => {\n server.on('error', reject);\n server.listen(port, hostname || 'localhost', () => {\n const addr = server.address();\n const actualPort = typeof addr === 'object' && addr ? addr.port : port;\n\n resolve({\n port: actualPort,\n stop() {\n server.close();\n },\n });\n });\n });\n}\n", "/**\n * Runtime Abstraction\n * Detects Bun vs Node.js and re-exports runtime-agnostic utilities.\n */\n\nexport const isBun = typeof globalThis.Bun !== 'undefined';\n\nexport {\n readTextFile,\n readJsonFile,\n fileExists,\n writeFile,\n serveFile,\n hashContent,\n inspect,\n ensureDir,\n getModuleDir,\n spawnProcess,\n getFileSize,\n getMimeType,\n} from './fs';\n\nexport {\n bundleFile,\n minifyJS,\n validateJS,\n type BundleResult,\n type BundleOptions,\n} from './bundler';\n\nexport {\n createRuntimeServer,\n type RuntimeServer,\n type RuntimeWSClient,\n type ServerOptions,\n} from './httpServer';\n", "import { join, dirname } from 'path';\nimport { getModuleDir } from './runtime';\n\nlet projectRoot: string = process.cwd();\n\n// Package root is where the editor files are installed (2 levels up from this file)\n// In packaged Electron builds, MENO_CORE_ROOT overrides import.meta.url resolution\nconst packageRoot = process.env.MENO_CORE_ROOT\n || join(dirname(getModuleDir(import.meta.url)), '..');\n\nexport function setProjectRoot(root: string): void {\n projectRoot = root;\n}\n\nexport function getProjectRoot(): string {\n return projectRoot;\n}\n\nexport function getPackageRoot(): string {\n return packageRoot;\n}\n\n// Path getters for project files (user's project)\nexport const projectPaths = {\n pages: () => join(projectRoot, 'pages'),\n templates: () => join(projectRoot, 'templates'),\n components: () => join(projectRoot, 'components'),\n fonts: () => join(projectRoot, 'fonts'),\n images: () => join(projectRoot, 'images'),\n videos: () => join(projectRoot, 'videos'),\n assets: () => join(projectRoot, 'assets'),\n icons: () => join(projectRoot, 'icons'),\n cms: () => join(projectRoot, 'cms'),\n libraries: () => join(projectRoot, 'libraries'),\n functions: () => join(projectRoot, 'functions'),\n config: () => join(projectRoot, 'project.config.json'),\n componentsConfig: () => join(projectRoot, 'components.config.json'),\n colors: () => join(projectRoot, 'colors.json'),\n variables: () => join(projectRoot, 'variables.json'),\n enums: () => join(projectRoot, 'enums.json'),\n dist: () => join(projectRoot, 'dist'),\n env: () => join(projectRoot, '.env'),\n get project() { return projectRoot; }, // Direct access to project root\n};\n\n// Path getters for package files (core assets)\n// Note: Editor-specific paths (editorHtml) are now in @meno/studio\nexport const packagePaths = {\n indexHtml: () => join(packageRoot, 'templates', 'index-router.html'),\n clientRouter: () => join(packageRoot, 'entries', 'client-router.tsx'),\n};\n\nexport function resolveProjectPath(...segments: string[]): string {\n return join(projectRoot, ...segments);\n}\n\nexport function resolvePackagePath(...segments: string[]): string {\n return join(packageRoot, ...segments);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["writeFile", "join", "inspect", "rm", "isBun", "server", "isBun"]
7
+ }