@onexapis/cli 1.1.66 → 1.1.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -3,15 +3,15 @@
3
3
 
4
4
  var chalk4 = require('chalk');
5
5
  var ora = require('ora');
6
- var path11 = require('path');
6
+ var fs3 = require('fs');
7
+ var path13 = require('path');
7
8
  var glob = require('glob');
8
- var fs = require('fs-extra');
9
+ var fs8 = require('fs-extra');
9
10
  var crypto = require('crypto');
11
+ var fs11 = require('fs/promises');
10
12
  var esbuild = require('esbuild');
11
- var fs9 = require('fs/promises');
12
13
  var module$1 = require('module');
13
14
  var http = require('http');
14
- var fs3 = require('fs');
15
15
  var ws = require('ws');
16
16
  var os = require('os');
17
17
  var dotenv = require('dotenv');
@@ -49,13 +49,13 @@ function _interopNamespace(e) {
49
49
 
50
50
  var chalk4__default = /*#__PURE__*/_interopDefault(chalk4);
51
51
  var ora__default = /*#__PURE__*/_interopDefault(ora);
52
- var path11__default = /*#__PURE__*/_interopDefault(path11);
53
- var fs__default = /*#__PURE__*/_interopDefault(fs);
52
+ var fs3__default = /*#__PURE__*/_interopDefault(fs3);
53
+ var path13__default = /*#__PURE__*/_interopDefault(path13);
54
+ var fs8__default = /*#__PURE__*/_interopDefault(fs8);
54
55
  var crypto__default = /*#__PURE__*/_interopDefault(crypto);
56
+ var fs11__default = /*#__PURE__*/_interopDefault(fs11);
55
57
  var esbuild__namespace = /*#__PURE__*/_interopNamespace(esbuild);
56
- var fs9__default = /*#__PURE__*/_interopDefault(fs9);
57
58
  var http__default = /*#__PURE__*/_interopDefault(http);
58
- var fs3__default = /*#__PURE__*/_interopDefault(fs3);
59
59
  var os__default = /*#__PURE__*/_interopDefault(os);
60
60
  var dotenv__default = /*#__PURE__*/_interopDefault(dotenv);
61
61
  var ejs__default = /*#__PURE__*/_interopDefault(ejs);
@@ -132,6 +132,13 @@ var init_logger = __esm({
132
132
  logger = new Logger();
133
133
  }
134
134
  });
135
+ function isNextjsProject(dir) {
136
+ return fs3__default.default.existsSync(path13__default.default.join(dir, "next.config.ts")) || fs3__default.default.existsSync(path13__default.default.join(dir, "next.config.js")) || fs3__default.default.existsSync(path13__default.default.join(dir, "next.config.mjs"));
137
+ }
138
+ var init_detect_nextjs = __esm({
139
+ "src/utils/detect-nextjs.ts"() {
140
+ }
141
+ });
135
142
  function sortedCopy(value) {
136
143
  if (Array.isArray(value)) {
137
144
  return value.map((v) => sortedCopy(v));
@@ -214,7 +221,7 @@ async function extractSchemas(themePath) {
214
221
  const sections = {};
215
222
  for (const file of schemaFiles) {
216
223
  try {
217
- const mod = await jiti.import(path11__default.default.join(themePath, file));
224
+ const mod = await jiti.import(path13__default.default.join(themePath, file));
218
225
  const exports$1 = mod;
219
226
  for (const value of Object.values(exports$1)) {
220
227
  if (value && typeof value === "object" && typeof value.type === "string" && Array.isArray(value.settings)) {
@@ -246,24 +253,24 @@ function isVideoAsset(filePath) {
246
253
  return VIDEO_EXTENSIONS.some((ext) => lower.endsWith(ext));
247
254
  }
248
255
  function mimeFor(filename) {
249
- const ext = path11__default.default.extname(filename).toLowerCase();
256
+ const ext = path13__default.default.extname(filename).toLowerCase();
250
257
  return MIME_MAP[ext] || "application/octet-stream";
251
258
  }
252
259
  async function sha256Prefix(absPath, len) {
253
- const buf = await fs__default.default.readFile(absPath);
260
+ const buf = await fs8__default.default.readFile(absPath);
254
261
  return crypto__default.default.createHash("sha256").update(buf).digest("hex").slice(0, len);
255
262
  }
256
263
  function insertHashIntoName(relPath, hash) {
257
- const dir = path11__default.default.posix.dirname(relPath);
258
- const base = path11__default.default.posix.basename(relPath);
259
- const ext = path11__default.default.posix.extname(base);
264
+ const dir = path13__default.default.posix.dirname(relPath);
265
+ const base = path13__default.default.posix.basename(relPath);
266
+ const ext = path13__default.default.posix.extname(base);
260
267
  const stem = ext ? base.slice(0, -ext.length) : base;
261
268
  const hashed = `${stem}-${hash}${ext}`;
262
269
  return dir === "." ? hashed : `${dir}/${hashed}`;
263
270
  }
264
271
  async function scanThemeAssets(distDir) {
265
- const assetsDir = path11__default.default.join(distDir, "theme-assets");
266
- if (!await fs__default.default.pathExists(assetsDir)) return [];
272
+ const assetsDir = path13__default.default.join(distDir, "theme-assets");
273
+ if (!await fs8__default.default.pathExists(assetsDir)) return [];
267
274
  const files = await glob.glob("**/*", {
268
275
  cwd: assetsDir,
269
276
  nodir: true,
@@ -271,10 +278,10 @@ async function scanThemeAssets(distDir) {
271
278
  });
272
279
  const results = [];
273
280
  for (const rel of files) {
274
- const absPath = path11__default.default.join(assetsDir, rel);
275
- const stat = await fs__default.default.stat(absPath);
281
+ const absPath = path13__default.default.join(assetsDir, rel);
282
+ const stat = await fs8__default.default.stat(absPath);
276
283
  if (!stat.isFile()) continue;
277
- const originalPath = rel.split(path11__default.default.sep).join("/");
284
+ const originalPath = rel.split(path13__default.default.sep).join("/");
278
285
  const hash = await sha256Prefix(absPath, HASH_LEN);
279
286
  const hashedPath = insertHashIntoName(originalPath, hash);
280
287
  const contentType = mimeFor(rel);
@@ -332,6 +339,101 @@ var init_scan_theme_assets = __esm({
332
339
  ];
333
340
  }
334
341
  });
342
+ async function scanAppDirectory(themePath) {
343
+ const appDir = path13__default.default.join(themePath, "app");
344
+ let pageFiles;
345
+ try {
346
+ pageFiles = await glob.glob("**/page.{tsx,ts,jsx,js}", { cwd: appDir });
347
+ } catch {
348
+ return [];
349
+ }
350
+ if (pageFiles.length === 0) return [];
351
+ const pages = [];
352
+ for (const pageFile of pageFiles) {
353
+ const routePath = deriveRoutePath(pageFile);
354
+ const absPageFile = path13__default.default.join(appDir, pageFile);
355
+ let source;
356
+ try {
357
+ source = await fs11__default.default.readFile(absPageFile, "utf-8");
358
+ } catch {
359
+ continue;
360
+ }
361
+ const sections = await extractSectionsFromPage(source, themePath);
362
+ pages.push({
363
+ routePath,
364
+ sourceFile: path13__default.default.join("app", pageFile),
365
+ sections
366
+ });
367
+ }
368
+ return pages;
369
+ }
370
+ function deriveRoutePath(pageFile) {
371
+ const dir = path13__default.default.dirname(pageFile);
372
+ if (dir === ".") return "/";
373
+ return "/" + dir;
374
+ }
375
+ async function extractSectionsFromPage(source, themePath) {
376
+ const importRegex = /import\s+\w+\s+from\s+["'](@\/|\.\.?\/)(components\/[^"']+)["']/g;
377
+ const sections = [];
378
+ const seen = /* @__PURE__ */ new Set();
379
+ for (const match of source.matchAll(importRegex)) {
380
+ const rawImportPath = match[2];
381
+ const componentDir = path13__default.default.dirname(rawImportPath);
382
+ const absComponentDir = path13__default.default.join(themePath, componentDir);
383
+ if (seen.has(componentDir)) continue;
384
+ seen.add(componentDir);
385
+ const sectionJsonPath = path13__default.default.join(absComponentDir, "section.json");
386
+ let sectionJson;
387
+ try {
388
+ const raw = await fs11__default.default.readFile(sectionJsonPath, "utf-8");
389
+ sectionJson = JSON.parse(raw);
390
+ } catch {
391
+ continue;
392
+ }
393
+ if (sectionJson.type !== "opaque-react") continue;
394
+ if (!sectionJson.entry) continue;
395
+ sections.push({
396
+ type: "opaque-react",
397
+ name: sectionJson.name ?? path13__default.default.basename(componentDir),
398
+ entry: path13__default.default.join(componentDir, sectionJson.entry),
399
+ componentDir
400
+ });
401
+ }
402
+ return sections;
403
+ }
404
+ function buildNextjsPagesMap(pages, themeId) {
405
+ const result = {};
406
+ for (const page of pages) {
407
+ const id = page.routePath === "/" ? "home" : page.routePath.replace(/\//g, "-").replace(/^-/, "");
408
+ const makeSectionType = (name) => `${themeId}-${name.toLowerCase().replace(/\s+/g, "-")}`;
409
+ result[id] = {
410
+ id,
411
+ name: id.charAt(0).toUpperCase() + id.slice(1),
412
+ path: page.routePath,
413
+ config: {
414
+ id,
415
+ path: page.routePath,
416
+ sections: page.sections.map((s, i) => ({
417
+ id: `${id}-section-${i}`,
418
+ type: makeSectionType(s.name),
419
+ sectionType: "opaque-react",
420
+ settings: {}
421
+ }))
422
+ },
423
+ sections: page.sections.map((s, i) => ({
424
+ id: `${id}-section-${i}`,
425
+ type: makeSectionType(s.name),
426
+ sectionType: "opaque-react",
427
+ settings: {}
428
+ }))
429
+ };
430
+ }
431
+ return result;
432
+ }
433
+ var init_nextjs_page_scanner = __esm({
434
+ "src/utils/nextjs-page-scanner.ts"() {
435
+ }
436
+ });
335
437
 
336
438
  // src/utils/compile-theme.ts
337
439
  var compile_theme_exports = {};
@@ -347,8 +449,8 @@ async function generateThemeCSS(themePath, outDir) {
347
449
  const tailwindcss = (await import('tailwindcss')).default;
348
450
  const tailwindConfig = {
349
451
  content: [
350
- path11__default.default.join(themePath, "sections/**/*.{ts,tsx}"),
351
- path11__default.default.join(themePath, "components/**/*.{ts,tsx}")
452
+ path13__default.default.join(themePath, "sections/**/*.{ts,tsx}"),
453
+ path13__default.default.join(themePath, "components/**/*.{ts,tsx}")
352
454
  ],
353
455
  theme: { extend: {} },
354
456
  plugins: []
@@ -358,7 +460,7 @@ async function generateThemeCSS(themePath, outDir) {
358
460
  inputCSS,
359
461
  { from: void 0 }
360
462
  );
361
- await fs9__default.default.writeFile(path11__default.default.join(outDir, "bundle.css"), result.css);
463
+ await fs11__default.default.writeFile(path13__default.default.join(outDir, "bundle.css"), result.css);
362
464
  logger.info("Generated bundle.css");
363
465
  } catch (err) {
364
466
  logger.warning(
@@ -369,12 +471,12 @@ async function generateThemeCSS(themePath, outDir) {
369
471
  async function resolveNodeModulesFile(startDir, relativePath) {
370
472
  let dir = startDir;
371
473
  while (true) {
372
- const candidate = path11__default.default.join(dir, "node_modules", relativePath);
474
+ const candidate = path13__default.default.join(dir, "node_modules", relativePath);
373
475
  try {
374
- await fs9__default.default.access(candidate);
476
+ await fs11__default.default.access(candidate);
375
477
  return candidate;
376
478
  } catch {
377
- const parent = path11__default.default.dirname(dir);
479
+ const parent = path13__default.default.dirname(dir);
378
480
  if (parent === dir) break;
379
481
  dir = parent;
380
482
  }
@@ -398,7 +500,7 @@ async function scanImportsFromPackage(sourceDir, packageName) {
398
500
  });
399
501
  for (const file of sourceFiles) {
400
502
  try {
401
- const content = await fs9__default.default.readFile(path11__default.default.join(sourceDir, file), "utf-8");
503
+ const content = await fs11__default.default.readFile(path13__default.default.join(sourceDir, file), "utf-8");
402
504
  for (const match of content.matchAll(namespaceImportRegex)) {
403
505
  const subpath = match[1] ? match[1].slice(1) : "";
404
506
  if (!result[subpath]) result[subpath] = /* @__PURE__ */ new Set();
@@ -452,17 +554,17 @@ function createCoreGlobalPlugin(themePath) {
452
554
  const distFileName = subpath ? `${subpath}.mjs` : "index.mjs";
453
555
  let distPath = await resolveNodeModulesFile(
454
556
  themePath,
455
- path11__default.default.join("@onexapis", "core", "dist", distFileName)
557
+ path13__default.default.join("@onexapis", "core", "dist", distFileName)
456
558
  );
457
559
  if (!distPath) {
458
560
  distPath = await resolveNodeModulesFile(
459
561
  __dirname,
460
- path11__default.default.join("@onexapis", "core", "dist", distFileName)
562
+ path13__default.default.join("@onexapis", "core", "dist", distFileName)
461
563
  );
462
564
  }
463
565
  try {
464
566
  if (!distPath) throw new Error("not found");
465
- const distContent = await fs9__default.default.readFile(distPath, "utf-8");
567
+ const distContent = await fs11__default.default.readFile(distPath, "utf-8");
466
568
  const exportMatches = distContent.matchAll(/export\s*\{([^}]+)\}/g);
467
569
  for (const m of exportMatches) {
468
570
  const names = m[1].split(",").map((n) => {
@@ -509,180 +611,6 @@ ${namedExportLines}
509
611
  }
510
612
  };
511
613
  }
512
- function createThemeDepsStubPlugin(themePath) {
513
- return {
514
- name: "theme-deps-stub",
515
- setup(build2) {
516
- const tryResolveOrStub = (filter, namespace) => {
517
- build2.onResolve({ filter }, async (args) => {
518
- if (args.pluginData?.skipStub) return void 0;
519
- try {
520
- const result = await build2.resolve(args.path, {
521
- kind: args.kind,
522
- resolveDir: args.resolveDir || themePath,
523
- importer: args.importer,
524
- namespace: "file",
525
- pluginData: { skipStub: true }
526
- });
527
- if (!result.errors.length) return result;
528
- } catch {
529
- }
530
- try {
531
- const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)) || __filename);
532
- const resolved = req.resolve(args.path);
533
- if (resolved) return { path: resolved, namespace: "file" };
534
- } catch {
535
- }
536
- return { path: args.path, namespace };
537
- });
538
- };
539
- tryResolveOrStub(/^next\//, "next-stub");
540
- build2.onLoad({ filter: /.*/, namespace: "next-stub" }, (args) => {
541
- const stubs = {
542
- "next/image": `
543
- import React from 'react';
544
- const Image = React.forwardRef((props, ref) => {
545
- const { src, alt, width, height, fill, priority, sizes, quality, placeholder, blurDataURL, onLoad, onError, style, className, ...rest } = props;
546
- const imgSrc = typeof src === 'object' ? src.src : src;
547
- const fillStyle = fill ? { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: style?.objectFit || 'cover', display: 'block' } : {};
548
- const mergedStyle = { ...fillStyle, ...style };
549
- return React.createElement('img', {
550
- ref, src: imgSrc, alt,
551
- width: fill ? undefined : width, height: fill ? undefined : height,
552
- loading: priority ? 'eager' : 'lazy',
553
- style: Object.keys(mergedStyle).length > 0 ? mergedStyle : undefined,
554
- className, onLoad, onError, ...rest,
555
- });
556
- });
557
- export default Image;
558
- `,
559
- "next/link": `
560
- import React from 'react';
561
- const Link = ({ href, children, ...rest }) => React.createElement('a', { href, ...rest }, children);
562
- export default Link;
563
- `,
564
- "next/navigation": `
565
- export function useRouter() { return { push(u){window.location.href=u}, replace(u){window.location.href=u}, back(){window.history.back()}, forward(){window.history.forward()}, refresh(){window.location.reload()}, prefetch(){} }; }
566
- export function usePathname() { return window.location.pathname; }
567
- export function useSearchParams() { return new URLSearchParams(window.location.search); }
568
- export function useParams() { return {}; }
569
- export function redirect(url) { window.location.href = url; }
570
- export function notFound() { throw new Error('Not Found'); }
571
- `,
572
- "next/headers": `
573
- export function cookies() { return { get(){}, getAll(){ return []; }, set(){}, delete(){}, has(){ return false; } }; }
574
- export function headers() { return new Headers(); }
575
- `
576
- };
577
- return {
578
- contents: stubs[args.path] || "export default {};",
579
- loader: "jsx",
580
- resolveDir: themePath
581
- };
582
- });
583
- const lucideImports = /* @__PURE__ */ new Set();
584
- let lucideThemeScanned = false;
585
- tryResolveOrStub(/^lucide-react/, "lucide-stub");
586
- build2.onLoad({ filter: /.*/, namespace: "lucide-stub" }, async () => {
587
- if (!lucideThemeScanned) {
588
- lucideThemeScanned = true;
589
- try {
590
- const scanned = await scanImportsFromPackage(
591
- themePath,
592
- "lucide-react"
593
- );
594
- for (const names of Object.values(scanned)) {
595
- for (const name of names) lucideImports.add(name);
596
- }
597
- } catch {
598
- }
599
- }
600
- const iconNames = [...lucideImports];
601
- const exports$1 = iconNames.map((n) => `icon as ${n}`).join(", ");
602
- return {
603
- contents: `
604
- const icon = (props) => null;
605
- export { ${exports$1} };
606
- export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true : icon });
607
- `.trim(),
608
- loader: "jsx"
609
- };
610
- });
611
- tryResolveOrStub(/^framer-motion/, "motion-stub");
612
- build2.onLoad({ filter: /.*/, namespace: "motion-stub" }, () => ({
613
- contents: `
614
- import React from 'react';
615
- const handler = { get: (_, name) => {
616
- if (name === '__esModule') return true;
617
- return React.forwardRef((props, ref) => React.createElement(name, { ...props, ref }));
618
- }};
619
- export const motion = new Proxy({}, handler);
620
- export const AnimatePresence = ({ children }) => children || null;
621
- export function useInView() { return true; }
622
- export default { motion, AnimatePresence, useInView };
623
- `.trim(),
624
- loader: "jsx",
625
- resolveDir: themePath
626
- }));
627
- tryResolveOrStub(/^sonner$/, "sonner-stub");
628
- build2.onLoad({ filter: /.*/, namespace: "sonner-stub" }, () => ({
629
- contents: `
630
- export const toast = new Proxy(() => {}, { get: () => () => {} });
631
- export const Toaster = () => null;
632
- export default { toast, Toaster };
633
- `.trim(),
634
- loader: "jsx"
635
- }));
636
- tryResolveOrStub(/^react-hook-form$/, "rhf-stub");
637
- build2.onLoad({ filter: /.*/, namespace: "rhf-stub" }, () => ({
638
- contents: `
639
- export function useForm() {
640
- return {
641
- register: () => ({}),
642
- handleSubmit: (fn) => (e) => { e?.preventDefault?.(); fn({}); },
643
- formState: { errors: {}, isSubmitting: false, isValid: true },
644
- watch: () => undefined,
645
- setValue: () => {},
646
- reset: () => {},
647
- control: {},
648
- };
649
- }
650
- export function useController() { return { field: {}, fieldState: {} }; }
651
- export function useFormContext() { return useForm(); }
652
- `.trim(),
653
- loader: "js"
654
- }));
655
- tryResolveOrStub(/^@hookform\/resolvers/, "hookform-resolvers-stub");
656
- build2.onLoad(
657
- { filter: /.*/, namespace: "hookform-resolvers-stub" },
658
- () => ({
659
- contents: `export function zodResolver() { return () => ({ values: {}, errors: {} }); }`,
660
- loader: "js"
661
- })
662
- );
663
- tryResolveOrStub(/^next-intl$/, "next-intl-stub");
664
- build2.onLoad({ filter: /.*/, namespace: "next-intl-stub" }, () => ({
665
- contents: `
666
- export function useTranslations(ns) {
667
- return (key) => ns ? ns + '.' + key : key;
668
- }
669
- export function useLocale() { return 'en'; }
670
- export function useMessages() { return {}; }
671
- `.trim(),
672
- loader: "js"
673
- }));
674
- tryResolveOrStub(/^zod$/, "zod-stub");
675
- build2.onLoad({ filter: /.*/, namespace: "zod-stub" }, () => ({
676
- contents: `
677
- const schema = () => ({ parse: (v) => v, safeParse: (v) => ({ success: true, data: v }), optional: schema, min: schema, max: schema, email: schema, url: schema, regex: schema, refine: schema, transform: schema });
678
- export const z = { string: schema, number: schema, boolean: schema, object: (s) => ({ ...schema(), shape: s }), array: schema, enum: schema, union: schema, literal: schema, infer: undefined };
679
- export default z;
680
- `.trim(),
681
- loader: "js"
682
- }));
683
- }
684
- };
685
- }
686
614
  async function generateThemeData(themePath, outputDir, themeId) {
687
615
  const { createJiti } = await import('jiti');
688
616
  const jiti = createJiti((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
@@ -691,7 +619,7 @@ async function generateThemeData(themePath, outputDir, themeId) {
691
619
  const pages = {};
692
620
  for (const ext of [".ts", ".js"]) {
693
621
  try {
694
- const mod = await jiti.import(path11__default.default.join(themePath, `theme.config${ext}`));
622
+ const mod = await jiti.import(path13__default.default.join(themePath, `theme.config${ext}`));
695
623
  themeConfig = mod.default || mod;
696
624
  break;
697
625
  } catch {
@@ -699,20 +627,20 @@ async function generateThemeData(themePath, outputDir, themeId) {
699
627
  }
700
628
  for (const ext of [".ts", ".js"]) {
701
629
  try {
702
- const mod = await jiti.import(path11__default.default.join(themePath, `theme.layout${ext}`));
630
+ const mod = await jiti.import(path13__default.default.join(themePath, `theme.layout${ext}`));
703
631
  layoutConfig = mod.default || mod;
704
632
  break;
705
633
  } catch {
706
634
  }
707
635
  }
708
636
  const schemas = {};
709
- const sectionsDir = path11__default.default.join(themePath, "sections");
637
+ const sectionsDir = path13__default.default.join(themePath, "sections");
710
638
  try {
711
- const sectionDirs = await fs9__default.default.readdir(sectionsDir);
639
+ const sectionDirs = await fs11__default.default.readdir(sectionsDir);
712
640
  for (const dir of sectionDirs) {
713
- const schemaFile = path11__default.default.join(sectionsDir, dir, `${dir}.schema.ts`);
641
+ const schemaFile = path13__default.default.join(sectionsDir, dir, `${dir}.schema.ts`);
714
642
  try {
715
- await fs9__default.default.access(schemaFile);
643
+ await fs11__default.default.access(schemaFile);
716
644
  const mod = await jiti.import(schemaFile);
717
645
  for (const [key, value] of Object.entries(mod)) {
718
646
  if (key.endsWith("Schema") && value && typeof value === "object" && value.type) {
@@ -724,14 +652,14 @@ async function generateThemeData(themePath, outputDir, themeId) {
724
652
  }
725
653
  } catch {
726
654
  }
727
- const pagesDir = path11__default.default.join(themePath, "pages");
655
+ const pagesDir = path13__default.default.join(themePath, "pages");
728
656
  try {
729
- const files = await fs9__default.default.readdir(pagesDir);
657
+ const files = await fs11__default.default.readdir(pagesDir);
730
658
  for (const file of files) {
731
659
  if (!file.match(/\.(ts|js)$/)) continue;
732
660
  const name = file.replace(/\.(ts|js)$/, "");
733
661
  try {
734
- const mod = await jiti.import(path11__default.default.join(pagesDir, file));
662
+ const mod = await jiti.import(path13__default.default.join(pagesDir, file));
735
663
  const config = mod.default || mod;
736
664
  const sections = (config.sections || []).map((section) => {
737
665
  const schema = schemas[section.type];
@@ -759,8 +687,16 @@ async function generateThemeData(themePath, outputDir, themeId) {
759
687
  }
760
688
  } catch {
761
689
  }
762
- await fs9__default.default.writeFile(
763
- path11__default.default.join(outputDir, "theme-data.json"),
690
+ if (isNextjsProject(themePath)) {
691
+ const nextjsPages = await scanAppDirectory(themePath);
692
+ if (nextjsPages.length > 0) {
693
+ const nextjsPagesMap = buildNextjsPagesMap(nextjsPages, themeId);
694
+ Object.assign(pages, nextjsPagesMap);
695
+ logger.info(`Scanned ${nextjsPages.length} Next.js app/ pages`);
696
+ }
697
+ }
698
+ await fs11__default.default.writeFile(
699
+ path13__default.default.join(outputDir, "theme-data.json"),
764
700
  JSON.stringify(
765
701
  {
766
702
  themeId,
@@ -783,22 +719,22 @@ async function generateThemeData(themePath, outputDir, themeId) {
783
719
  logger.info(`Generated theme-data.json (${Object.keys(pages).length} pages)`);
784
720
  }
785
721
  async function contentHashEntry(outputDir) {
786
- const entryPath = path11__default.default.join(outputDir, "bundle-entry.js");
787
- const mapPath = path11__default.default.join(outputDir, "bundle-entry.js.map");
722
+ const entryPath = path13__default.default.join(outputDir, "bundle-entry.js");
723
+ const mapPath = path13__default.default.join(outputDir, "bundle-entry.js.map");
788
724
  let entryContent;
789
725
  try {
790
- entryContent = await fs9__default.default.readFile(entryPath, "utf-8");
726
+ entryContent = await fs11__default.default.readFile(entryPath, "utf-8");
791
727
  } catch {
792
- const indexPath = path11__default.default.join(outputDir, "index.js");
728
+ const indexPath = path13__default.default.join(outputDir, "index.js");
793
729
  try {
794
- entryContent = await fs9__default.default.readFile(indexPath, "utf-8");
730
+ entryContent = await fs11__default.default.readFile(indexPath, "utf-8");
795
731
  } catch {
796
732
  logger.warning("No entry file found in output, skipping content hash");
797
733
  return;
798
734
  }
799
735
  const hash2 = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
800
736
  const hashedName2 = `bundle-entry-${hash2}.js`;
801
- const indexMapPath = path11__default.default.join(outputDir, "index.js.map");
737
+ const indexMapPath = path13__default.default.join(outputDir, "index.js.map");
802
738
  const hashedMapName2 = `bundle-entry-${hash2}.js.map`;
803
739
  entryContent = entryContent.replace(
804
740
  /\/\/# sourceMappingURL=index\.js\.map/,
@@ -806,18 +742,18 @@ async function contentHashEntry(outputDir) {
806
742
  );
807
743
  const oldFiles2 = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
808
744
  for (const f of oldFiles2) {
809
- await fs9__default.default.unlink(path11__default.default.join(outputDir, f));
745
+ await fs11__default.default.unlink(path13__default.default.join(outputDir, f));
810
746
  }
811
- await fs9__default.default.writeFile(path11__default.default.join(outputDir, hashedName2), entryContent);
812
- await fs9__default.default.unlink(indexPath);
747
+ await fs11__default.default.writeFile(path13__default.default.join(outputDir, hashedName2), entryContent);
748
+ await fs11__default.default.unlink(indexPath);
813
749
  try {
814
- await fs9__default.default.unlink(entryPath);
750
+ await fs11__default.default.unlink(entryPath);
815
751
  } catch {
816
752
  }
817
- await fs9__default.default.writeFile(entryPath, entryContent);
753
+ await fs11__default.default.writeFile(entryPath, entryContent);
818
754
  try {
819
- await fs9__default.default.access(indexMapPath);
820
- await fs9__default.default.rename(indexMapPath, path11__default.default.join(outputDir, hashedMapName2));
755
+ await fs11__default.default.access(indexMapPath);
756
+ await fs11__default.default.rename(indexMapPath, path13__default.default.join(outputDir, hashedMapName2));
821
757
  } catch {
822
758
  }
823
759
  logger.info(`Entry hashed: ${hashedName2}`);
@@ -832,17 +768,17 @@ async function contentHashEntry(outputDir) {
832
768
  );
833
769
  const oldFiles = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
834
770
  for (const f of oldFiles) {
835
- await fs9__default.default.unlink(path11__default.default.join(outputDir, f));
771
+ await fs11__default.default.unlink(path13__default.default.join(outputDir, f));
836
772
  }
837
- await fs9__default.default.writeFile(path11__default.default.join(outputDir, hashedName), entryContent);
773
+ await fs11__default.default.writeFile(path13__default.default.join(outputDir, hashedName), entryContent);
838
774
  try {
839
- await fs9__default.default.unlink(entryPath);
775
+ await fs11__default.default.unlink(entryPath);
840
776
  } catch {
841
777
  }
842
- await fs9__default.default.writeFile(entryPath, entryContent);
778
+ await fs11__default.default.writeFile(entryPath, entryContent);
843
779
  try {
844
- await fs9__default.default.access(mapPath);
845
- await fs9__default.default.rename(mapPath, path11__default.default.join(outputDir, hashedMapName));
780
+ await fs11__default.default.access(mapPath);
781
+ await fs11__default.default.rename(mapPath, path13__default.default.join(outputDir, hashedMapName));
846
782
  } catch {
847
783
  }
848
784
  logger.info(`Entry hashed: ${hashedName}`);
@@ -854,7 +790,7 @@ async function extractDataRequirements(themePath) {
854
790
  const requirements = {};
855
791
  for (const file of schemaFiles) {
856
792
  try {
857
- const mod = await jiti.import(path11__default.default.join(themePath, file));
793
+ const mod = await jiti.import(path13__default.default.join(themePath, file));
858
794
  const exports$1 = mod;
859
795
  for (const value of Object.values(exports$1)) {
860
796
  if (value && typeof value === "object" && typeof value.type === "string" && value.dataRequirements && typeof value.dataRequirements === "object") {
@@ -872,8 +808,8 @@ async function extractDataRequirements(themePath) {
872
808
  async function writeGateManifests(themePath, outputDir) {
873
809
  try {
874
810
  const schemas = await extractSchemas(themePath);
875
- await fs9__default.default.writeFile(
876
- path11__default.default.join(outputDir, "schemas.json"),
811
+ await fs11__default.default.writeFile(
812
+ path13__default.default.join(outputDir, "schemas.json"),
877
813
  serializeManifest(schemas)
878
814
  );
879
815
  logger.info(
@@ -892,8 +828,8 @@ async function writeGateManifests(themePath, outputDir) {
892
828
  size: e.size,
893
829
  contentType: e.contentType
894
830
  }));
895
- await fs9__default.default.writeFile(
896
- path11__default.default.join(outputDir, "asset-manifest.json"),
831
+ await fs11__default.default.writeFile(
832
+ path13__default.default.join(outputDir, "asset-manifest.json"),
897
833
  JSON.stringify({ manifestVersion: 1, assets }, null, 2)
898
834
  );
899
835
  logger.info(`Generated asset-manifest.json (${assets.length} assets)`);
@@ -903,12 +839,71 @@ async function writeGateManifests(themePath, outputDir) {
903
839
  );
904
840
  }
905
841
  }
842
+ async function compileSections(themePath, outputDir) {
843
+ const sectionsDir = path13__default.default.join(themePath, "sections");
844
+ let sectionDirs;
845
+ try {
846
+ sectionDirs = await fs11__default.default.readdir(sectionsDir);
847
+ } catch {
848
+ return;
849
+ }
850
+ for (const dirName of sectionDirs) {
851
+ const sectionSrc = path13__default.default.join(sectionsDir, dirName);
852
+ const sectionOut = path13__default.default.join(outputDir, "sections", dirName);
853
+ let section = null;
854
+ try {
855
+ const raw = await fs11__default.default.readFile(
856
+ path13__default.default.join(sectionSrc, "section.manifest.json"),
857
+ "utf-8"
858
+ );
859
+ section = JSON.parse(raw);
860
+ } catch {
861
+ continue;
862
+ }
863
+ switch (section.type) {
864
+ case "editable":
865
+ case "opaque-react":
866
+ break;
867
+ case "html": {
868
+ await fs11__default.default.mkdir(sectionOut, { recursive: true });
869
+ const htmlSrc = path13__default.default.join(sectionSrc, section.html);
870
+ let htmlContent = await fs11__default.default.readFile(htmlSrc, "utf-8");
871
+ htmlContent = htmlContent.replace(
872
+ /<script[^>]+src=["']https?:\/\/[^"']*["'][^>]*><\/script>/gi,
873
+ ""
874
+ );
875
+ await fs11__default.default.writeFile(path13__default.default.join(sectionOut, path13__default.default.basename(section.html)), htmlContent);
876
+ if (section.css) {
877
+ await fs11__default.default.copyFile(
878
+ path13__default.default.join(sectionSrc, section.css),
879
+ path13__default.default.join(sectionOut, path13__default.default.basename(section.css))
880
+ );
881
+ }
882
+ break;
883
+ }
884
+ case "iframe":
885
+ break;
886
+ case "webcomponent": {
887
+ await fs11__default.default.mkdir(sectionOut, { recursive: true });
888
+ await fs11__default.default.copyFile(
889
+ path13__default.default.join(sectionSrc, section.bundle),
890
+ path13__default.default.join(sectionOut, path13__default.default.basename(section.bundle))
891
+ );
892
+ break;
893
+ }
894
+ default:
895
+ throw new Error(
896
+ `Unknown section type. Valid types: editable, opaque-react, html, iframe, webcomponent`
897
+ );
898
+ }
899
+ }
900
+ }
906
901
  async function generateManifest(themeName, themePath, outputDir) {
907
902
  let version2 = "1.0.0";
908
903
  let themeId = themeName;
909
904
  try {
910
- const pkgContent = await fs9__default.default.readFile(
911
- path11__default.default.join(themePath, "package.json"),
905
+ const pkgContent = await fs11__default.default.readFile(
906
+ path13__default.default.join(themePath, "package.json"),
912
907
  "utf-8"
913
908
  );
914
909
  const pkg = JSON.parse(pkgContent);
@@ -926,7 +921,7 @@ async function generateManifest(themeName, themePath, outputDir) {
926
921
  const dataRequirements = await extractDataRequirements(themePath);
927
922
  let hasThemeConfig = false;
928
923
  try {
929
- await fs9__default.default.access(path11__default.default.join(themePath, "theme.config.ts"));
924
+ await fs11__default.default.access(path13__default.default.join(themePath, "theme.config.ts"));
930
925
  hasThemeConfig = true;
931
926
  } catch {
932
927
  }
@@ -967,24 +962,34 @@ async function generateManifest(themeName, themePath, outputDir) {
967
962
  // Section data requirements for server-side prefetching (keyed by section type)
968
963
  dataRequirements
969
964
  };
970
- await fs9__default.default.writeFile(
971
- path11__default.default.join(outputDir, "manifest.json"),
965
+ await fs11__default.default.writeFile(
966
+ path13__default.default.join(outputDir, "manifest.json"),
972
967
  JSON.stringify(manifest, null, 2)
973
968
  );
974
969
  }
975
970
  async function compileStandaloneTheme(themePath, themeName) {
976
- const outputDir = path11__default.default.join(themePath, "dist");
977
- const bundleEntry = path11__default.default.join(themePath, "bundle-entry.ts");
978
- const indexEntry = path11__default.default.join(themePath, "index.ts");
971
+ const outputDir = path13__default.default.join(themePath, "dist");
972
+ const isNextjs = isNextjsProject(themePath);
973
+ if (isNextjs) {
974
+ logger.info("Detected Next.js project \u2014 using next/* shims");
975
+ }
976
+ const bundleEntry = path13__default.default.join(themePath, "bundle-entry.ts");
977
+ const indexEntry = path13__default.default.join(themePath, "index.ts");
979
978
  let entryPoint = indexEntry;
980
979
  try {
981
- await fs9__default.default.access(bundleEntry);
980
+ await fs11__default.default.access(bundleEntry);
982
981
  entryPoint = bundleEntry;
983
982
  } catch {
984
983
  }
985
- const shimPath = path11__default.default.join(outputDir, ".process-shim.js");
986
- await fs9__default.default.mkdir(outputDir, { recursive: true });
987
- await fs9__default.default.writeFile(shimPath, PROCESS_SHIM);
984
+ const shimPath = path13__default.default.join(outputDir, ".process-shim.js");
985
+ await fs11__default.default.mkdir(outputDir, { recursive: true });
986
+ await fs11__default.default.writeFile(shimPath, PROCESS_SHIM);
987
+ const plugins = [
988
+ reactGlobalPlugin,
989
+ reactQueryGlobalPlugin,
990
+ createCoreGlobalPlugin(themePath)
991
+ ];
992
+ if (isNextjs) plugins.unshift(nextShimPlugin);
988
993
  const buildOptions = {
989
994
  entryPoints: [entryPoint],
990
995
  bundle: true,
@@ -996,12 +1001,7 @@ async function compileStandaloneTheme(themePath, themeName) {
996
1001
  banner: {
997
1002
  js: '"use client";'
998
1003
  },
999
- plugins: [
1000
- reactGlobalPlugin,
1001
- reactQueryGlobalPlugin,
1002
- createCoreGlobalPlugin(themePath),
1003
- createThemeDepsStubPlugin(themePath)
1004
- ],
1004
+ plugins,
1005
1005
  external: [],
1006
1006
  alias: {
1007
1007
  events: "events/",
@@ -1035,15 +1035,16 @@ async function compileStandaloneTheme(themePath, themeName) {
1035
1035
  try {
1036
1036
  const result = await esbuild__namespace.build(buildOptions);
1037
1037
  try {
1038
- await fs9__default.default.unlink(shimPath);
1038
+ await fs11__default.default.unlink(shimPath);
1039
1039
  } catch {
1040
1040
  }
1041
+ await compileSections(themePath, outputDir);
1041
1042
  await contentHashEntry(outputDir);
1042
- const themeAssetsDir = path11__default.default.join(themePath, "assets");
1043
- const distThemeAssets = path11__default.default.join(outputDir, "theme-assets");
1043
+ const themeAssetsDir = path13__default.default.join(themePath, "assets");
1044
+ const distThemeAssets = path13__default.default.join(outputDir, "theme-assets");
1044
1045
  try {
1045
- await fs9__default.default.access(themeAssetsDir);
1046
- await fs9__default.default.cp(themeAssetsDir, distThemeAssets, { recursive: true });
1046
+ await fs11__default.default.access(themeAssetsDir);
1047
+ await fs11__default.default.cp(themeAssetsDir, distThemeAssets, { recursive: true });
1047
1048
  logger.info("Copied static assets to dist/theme-assets/");
1048
1049
  } catch {
1049
1050
  }
@@ -1063,7 +1064,7 @@ async function compileStandaloneTheme(themePath, themeName) {
1063
1064
  return true;
1064
1065
  } catch (error) {
1065
1066
  try {
1066
- await fs9__default.default.unlink(shimPath);
1067
+ await fs11__default.default.unlink(shimPath);
1067
1068
  } catch {
1068
1069
  }
1069
1070
  logger.error(`esbuild compilation failed: ${error}`);
@@ -1071,18 +1072,25 @@ async function compileStandaloneTheme(themePath, themeName) {
1071
1072
  }
1072
1073
  }
1073
1074
  async function compileStandaloneThemeDev(themePath, themeName) {
1074
- const outputDir = path11__default.default.join(themePath, "dist");
1075
- const bundleEntry = path11__default.default.join(themePath, "bundle-entry.ts");
1076
- const indexEntry = path11__default.default.join(themePath, "index.ts");
1075
+ const outputDir = path13__default.default.join(themePath, "dist");
1076
+ const isNextjs = isNextjsProject(themePath);
1077
+ const bundleEntry = path13__default.default.join(themePath, "bundle-entry.ts");
1078
+ const indexEntry = path13__default.default.join(themePath, "index.ts");
1077
1079
  let entryPoint = indexEntry;
1078
1080
  try {
1079
- await fs9__default.default.access(bundleEntry);
1081
+ await fs11__default.default.access(bundleEntry);
1080
1082
  entryPoint = bundleEntry;
1081
1083
  } catch {
1082
1084
  }
1083
- const shimPath = path11__default.default.join(outputDir, ".process-shim.js");
1084
- await fs9__default.default.mkdir(outputDir, { recursive: true });
1085
- await fs9__default.default.writeFile(shimPath, PROCESS_SHIM);
1085
+ const shimPath = path13__default.default.join(outputDir, ".process-shim.js");
1086
+ await fs11__default.default.mkdir(outputDir, { recursive: true });
1087
+ await fs11__default.default.writeFile(shimPath, PROCESS_SHIM);
1088
+ const devPlugins = [
1089
+ reactGlobalPlugin,
1090
+ reactQueryGlobalPlugin,
1091
+ createCoreGlobalPlugin(themePath)
1092
+ ];
1093
+ if (isNextjs) devPlugins.unshift(nextShimPlugin);
1086
1094
  const buildOptions = {
1087
1095
  entryPoints: [entryPoint],
1088
1096
  bundle: true,
@@ -1093,12 +1101,7 @@ async function compileStandaloneThemeDev(themePath, themeName) {
1093
1101
  banner: {
1094
1102
  js: '"use client";'
1095
1103
  },
1096
- plugins: [
1097
- reactGlobalPlugin,
1098
- reactQueryGlobalPlugin,
1099
- createCoreGlobalPlugin(themePath),
1100
- createThemeDepsStubPlugin(themePath)
1101
- ],
1104
+ plugins: devPlugins,
1102
1105
  external: [],
1103
1106
  alias: {
1104
1107
  events: "events/",
@@ -1136,18 +1139,18 @@ async function compileStandaloneThemeDev(themePath, themeName) {
1136
1139
  return { context: context2, outputDir };
1137
1140
  }
1138
1141
  async function compilePreviewRuntime(themePath) {
1139
- const outputDir = path11__default.default.join(themePath, "dist");
1140
- await fs9__default.default.mkdir(outputDir, { recursive: true });
1141
- const outputPath = path11__default.default.join(outputDir, "preview-runtime.js");
1142
+ const outputDir = path13__default.default.join(themePath, "dist");
1143
+ await fs11__default.default.mkdir(outputDir, { recursive: true });
1144
+ const outputPath = path13__default.default.join(outputDir, "preview-runtime.js");
1142
1145
  const locations = [
1143
- path11__default.default.join(__dirname, "..", "preview", "preview-app.tsx"),
1144
- path11__default.default.join(__dirname, "preview", "preview-app.tsx"),
1145
- path11__default.default.join(__dirname, "..", "..", "src", "preview", "preview-app.tsx")
1146
+ path13__default.default.join(__dirname, "..", "preview", "preview-app.tsx"),
1147
+ path13__default.default.join(__dirname, "preview", "preview-app.tsx"),
1148
+ path13__default.default.join(__dirname, "..", "..", "src", "preview", "preview-app.tsx")
1146
1149
  ];
1147
1150
  let previewEntryPath = null;
1148
1151
  for (const loc of locations) {
1149
1152
  try {
1150
- await fs9__default.default.access(loc);
1153
+ await fs11__default.default.access(loc);
1151
1154
  previewEntryPath = loc;
1152
1155
  break;
1153
1156
  } catch {
@@ -1230,10 +1233,10 @@ ${locations.join("\n")}`
1230
1233
  if (!lucideScanned) {
1231
1234
  lucideScanned = true;
1232
1235
  const coreSrcCandidates = [
1233
- path11__default.default.join(themePath, "node_modules", "@onexapis", "core", "src"),
1234
- path11__default.default.join(themePath, "..", "..", "packages", "core", "src"),
1236
+ path13__default.default.join(themePath, "node_modules", "@onexapis", "core", "src"),
1237
+ path13__default.default.join(themePath, "..", "..", "packages", "core", "src"),
1235
1238
  // monorepo sibling
1236
- path11__default.default.join(
1239
+ path13__default.default.join(
1237
1240
  __dirname,
1238
1241
  "..",
1239
1242
  "..",
@@ -1248,7 +1251,7 @@ ${locations.join("\n")}`
1248
1251
  let coreSourceDir = null;
1249
1252
  for (const candidate of coreSrcCandidates) {
1250
1253
  try {
1251
- await fs9__default.default.access(candidate);
1254
+ await fs11__default.default.access(candidate);
1252
1255
  coreSourceDir = candidate;
1253
1256
  break;
1254
1257
  } catch {
@@ -1267,21 +1270,21 @@ ${locations.join("\n")}`
1267
1270
  }
1268
1271
  } else {
1269
1272
  const coreDistCandidates = [
1270
- path11__default.default.join(themePath, "node_modules", "@onexapis", "core", "dist")
1273
+ path13__default.default.join(themePath, "node_modules", "@onexapis", "core", "dist")
1271
1274
  ];
1272
1275
  const resolvedDist = await resolveNodeModulesFile(
1273
1276
  __dirname,
1274
- path11__default.default.join("@onexapis", "core", "dist")
1277
+ path13__default.default.join("@onexapis", "core", "dist")
1275
1278
  );
1276
1279
  if (resolvedDist) coreDistCandidates.push(resolvedDist);
1277
1280
  for (const candidate of coreDistCandidates) {
1278
1281
  try {
1279
- await fs9__default.default.access(candidate);
1282
+ await fs11__default.default.access(candidate);
1280
1283
  const mjsFiles = await glob.glob("*.mjs", { cwd: candidate });
1281
1284
  const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']lucide-react["']/g;
1282
1285
  for (const file of mjsFiles) {
1283
- const content = await fs9__default.default.readFile(
1284
- path11__default.default.join(candidate, file),
1286
+ const content = await fs11__default.default.readFile(
1287
+ path13__default.default.join(candidate, file),
1285
1288
  "utf-8"
1286
1289
  );
1287
1290
  for (const match of content.matchAll(importRegex)) {
@@ -1336,7 +1339,7 @@ export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true :
1336
1339
  const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)) || __filename);
1337
1340
  const cjsPath = req.resolve("framer-motion");
1338
1341
  const pkgDir = cjsPath.replace(/[/\\]dist[/\\].*$/, "");
1339
- const esmEntry = path11__default.default.join(pkgDir, "dist", "es", "index.mjs");
1342
+ const esmEntry = path13__default.default.join(pkgDir, "dist", "es", "index.mjs");
1340
1343
  const { existsSync } = await import('fs');
1341
1344
  if (existsSync(esmEntry)) {
1342
1345
  return { path: esmEntry, namespace: "file" };
@@ -1435,8 +1438,8 @@ export function headers() { return new Headers(); }
1435
1438
  });
1436
1439
  }
1437
1440
  };
1438
- const shimPath = path11__default.default.join(outputDir, ".process-shim-preview.js");
1439
- await fs9__default.default.writeFile(shimPath, PROCESS_SHIM);
1441
+ const shimPath = path13__default.default.join(outputDir, ".process-shim-preview.js");
1442
+ await fs11__default.default.writeFile(shimPath, PROCESS_SHIM);
1440
1443
  await esbuild__namespace.build({
1441
1444
  entryPoints: [previewEntryPath],
1442
1445
  bundle: true,
@@ -1471,17 +1474,19 @@ export function headers() { return new Headers(); }
1471
1474
  }
1472
1475
  });
1473
1476
  try {
1474
- await fs9__default.default.unlink(shimPath);
1477
+ await fs11__default.default.unlink(shimPath);
1475
1478
  } catch {
1476
1479
  }
1477
1480
  return outputPath;
1478
1481
  }
1479
- var PROCESS_SHIM, reactGlobalPlugin, reactQueryGlobalPlugin;
1482
+ var PROCESS_SHIM, reactGlobalPlugin, reactQueryGlobalPlugin, nextShimPlugin;
1480
1483
  var init_compile_theme = __esm({
1481
1484
  "src/utils/compile-theme.ts"() {
1482
1485
  init_logger();
1483
1486
  init_extract_schemas();
1484
1487
  init_scan_theme_assets();
1488
+ init_detect_nextjs();
1489
+ init_nextjs_page_scanner();
1485
1490
  PROCESS_SHIM = `
1486
1491
  if (typeof process === "undefined") {
1487
1492
  globalThis.process = {
@@ -1627,6 +1632,145 @@ export const {
1627
1632
  }));
1628
1633
  }
1629
1634
  };
1635
+ nextShimPlugin = {
1636
+ name: "next-shim",
1637
+ setup(build2) {
1638
+ for (const serverModule of ["next/headers", "next/server", "next/cache"]) {
1639
+ build2.onResolve({ filter: new RegExp(`^${serverModule.replace("/", "\\/")}`) }, (args) => ({
1640
+ path: args.path,
1641
+ namespace: "next-server-error"
1642
+ }));
1643
+ }
1644
+ build2.onLoad({ filter: /.*/, namespace: "next-server-error" }, (args) => ({
1645
+ errors: [
1646
+ {
1647
+ text: `"${args.path}" is server-only and cannot be used in a OneX theme bundle. Use client-side equivalents or remove the import.`
1648
+ }
1649
+ ]
1650
+ }));
1651
+ build2.onResolve({ filter: /^next\/navigation$/ }, () => ({
1652
+ path: "next-navigation-shim",
1653
+ namespace: "next-shim"
1654
+ }));
1655
+ build2.onLoad({ filter: /^next-navigation-shim$/, namespace: "next-shim" }, () => ({
1656
+ contents: `
1657
+ export function usePathname() {
1658
+ if (typeof window === 'undefined') return '/';
1659
+ return window.location.pathname;
1660
+ }
1661
+ export function useSearchParams() {
1662
+ if (typeof window === 'undefined') return new URLSearchParams();
1663
+ return new URLSearchParams(window.location.search);
1664
+ }
1665
+ export function useParams() {
1666
+ if (typeof window === 'undefined') return {};
1667
+ return (globalThis.__ONEX_ROUTE_PARAMS__) ?? {};
1668
+ }
1669
+ export function useRouter() {
1670
+ return {
1671
+ push(url) { if (typeof window !== 'undefined') window.location.href = url; },
1672
+ replace(url) { if (typeof window !== 'undefined') window.location.replace(url); },
1673
+ back() { if (typeof window !== 'undefined') window.history.back(); },
1674
+ forward() { if (typeof window !== 'undefined') window.history.forward(); },
1675
+ refresh() { if (typeof window !== 'undefined') window.location.reload(); },
1676
+ prefetch() {},
1677
+ };
1678
+ }
1679
+ export function redirect(url) {
1680
+ if (typeof window !== 'undefined') window.location.href = url;
1681
+ throw new Error('redirect');
1682
+ }
1683
+ export function notFound() { throw new Error('not-found'); }
1684
+ `.trim(),
1685
+ loader: "js"
1686
+ }));
1687
+ build2.onResolve({ filter: /^next\/font\// }, () => ({
1688
+ path: "next-font-shim",
1689
+ namespace: "next-shim"
1690
+ }));
1691
+ build2.onLoad({ filter: /^next-font-shim$/, namespace: "next-shim" }, () => ({
1692
+ contents: `
1693
+ function makeFont(family) {
1694
+ return function(_opts) {
1695
+ return {
1696
+ className: '',
1697
+ style: { fontFamily: family + ', system-ui, sans-serif' },
1698
+ variable: '--font-' + family.toLowerCase().replace(/\\s+/g, '-'),
1699
+ };
1700
+ };
1701
+ }
1702
+ export const Inter = makeFont('Inter');
1703
+ export const Roboto = makeFont('Roboto');
1704
+ export const Open_Sans = makeFont('Open Sans');
1705
+ export const Lato = makeFont('Lato');
1706
+ export const Montserrat = makeFont('Montserrat');
1707
+ export const Poppins = makeFont('Poppins');
1708
+ export const Raleway = makeFont('Raleway');
1709
+ export const Nunito = makeFont('Nunito');
1710
+ export const Geist = makeFont('Geist');
1711
+ export const Geist_Mono = makeFont('Geist Mono');
1712
+ export const DM_Sans = makeFont('DM Sans');
1713
+ export const Plus_Jakarta_Sans = makeFont('Plus Jakarta Sans');
1714
+ export function localFont(_opts) {
1715
+ return { className: '', style: { fontFamily: 'system-ui, sans-serif' }, variable: '--font-local' };
1716
+ }
1717
+ `.trim(),
1718
+ loader: "js"
1719
+ }));
1720
+ build2.onResolve({ filter: /^next\/dynamic$/ }, () => ({
1721
+ path: "next-dynamic-shim",
1722
+ namespace: "next-shim"
1723
+ }));
1724
+ build2.onLoad({ filter: /^next-dynamic-shim$/, namespace: "next-shim" }, () => ({
1725
+ contents: `
1726
+ import { lazy, Suspense, createElement } from 'react';
1727
+ export default function dynamic(loader, opts) {
1728
+ const Lazy = lazy(loader);
1729
+ return function DynamicComponent(props) {
1730
+ return createElement(Suspense, { fallback: opts?.loading ? createElement(opts.loading) : null },
1731
+ createElement(Lazy, props));
1732
+ };
1733
+ }
1734
+ `.trim(),
1735
+ loader: "js"
1736
+ }));
1737
+ build2.onResolve({ filter: /^next\/image$/ }, () => ({
1738
+ path: "next-image-shim",
1739
+ namespace: "next-shim"
1740
+ }));
1741
+ build2.onLoad({ filter: /^next-image-shim$/, namespace: "next-shim" }, () => ({
1742
+ contents: `
1743
+ import { createElement } from 'react';
1744
+ export default function Image({ src, alt, width, height, style, className, ...rest }) {
1745
+ return createElement('img', { src, alt, width, height, style, className, ...rest });
1746
+ }
1747
+ `.trim(),
1748
+ loader: "js"
1749
+ }));
1750
+ build2.onResolve({ filter: /^next\/link$/ }, () => ({
1751
+ path: "next-link-shim",
1752
+ namespace: "next-shim"
1753
+ }));
1754
+ build2.onLoad({ filter: /^next-link-shim$/, namespace: "next-shim" }, () => ({
1755
+ contents: `
1756
+ import { createElement } from 'react';
1757
+ export default function Link({ href, children, className, style, ...rest }) {
1758
+ return createElement('a', { href, className, style, ...rest }, children);
1759
+ }
1760
+ `.trim(),
1761
+ loader: "js"
1762
+ }));
1763
+ build2.onResolve({ filter: /^next\// }, () => ({
1764
+ path: "next-noop-shim",
1765
+ namespace: "next-shim"
1766
+ }));
1767
+ build2.onLoad({ filter: /^next-noop-shim$/, namespace: "next-shim" }, () => ({
1768
+ contents: `export default {};
1769
+ `,
1770
+ loader: "js"
1771
+ }));
1772
+ }
1773
+ };
1630
1774
  }
1631
1775
  });
1632
1776
 
@@ -1637,7 +1781,7 @@ __export(dev_server_exports, {
1637
1781
  });
1638
1782
  function createDevServer(options) {
1639
1783
  const clients = /* @__PURE__ */ new Set();
1640
- const themeDataPath = path11__default.default.join(options.distDir, "theme-data.json");
1784
+ const themeDataPath = path13__default.default.join(options.distDir, "theme-data.json");
1641
1785
  const server = http__default.default.createServer((req, res) => {
1642
1786
  res.setHeader("Access-Control-Allow-Origin", "*");
1643
1787
  res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
@@ -1663,8 +1807,8 @@ function createDevServer(options) {
1663
1807
  if (pathname.startsWith("/_assets/")) {
1664
1808
  const parts = pathname.replace(/^\/_assets\//, "").split("/");
1665
1809
  const assetSubpath = parts.slice(1).join("/");
1666
- const assetPath = path11__default.default.join(options.themePath, "assets", assetSubpath);
1667
- if (!assetPath.startsWith(path11__default.default.join(options.themePath, "assets"))) {
1810
+ const assetPath = path13__default.default.join(options.themePath, "assets", assetSubpath);
1811
+ if (!assetPath.startsWith(path13__default.default.join(options.themePath, "assets"))) {
1668
1812
  res.writeHead(403);
1669
1813
  res.end("Forbidden");
1670
1814
  return;
@@ -1675,8 +1819,8 @@ function createDevServer(options) {
1675
1819
  if (pathname.startsWith("/themes/")) {
1676
1820
  const match = pathname.match(/^\/themes\/[^/]+\/assets\/(.+)/);
1677
1821
  if (match) {
1678
- const assetPath = path11__default.default.join(options.themePath, "assets", match[1]);
1679
- if (!assetPath.startsWith(path11__default.default.join(options.themePath, "assets"))) {
1822
+ const assetPath = path13__default.default.join(options.themePath, "assets", match[1]);
1823
+ if (!assetPath.startsWith(path13__default.default.join(options.themePath, "assets"))) {
1680
1824
  res.writeHead(403);
1681
1825
  res.end("Forbidden");
1682
1826
  return;
@@ -1688,26 +1832,26 @@ function createDevServer(options) {
1688
1832
  if (pathname.startsWith("/assets/")) {
1689
1833
  const subpath = pathname.replace(/^\/assets\//, "");
1690
1834
  const segments = subpath.split("/");
1691
- const assetsBase = path11__default.default.join(options.themePath, "assets");
1835
+ const assetsBase = path13__default.default.join(options.themePath, "assets");
1692
1836
  let assetPath;
1693
1837
  if (segments[0] === options.themeName || segments[0] === options.themeName.replace(/^my-/, "")) {
1694
- assetPath = path11__default.default.join(assetsBase, segments.slice(1).join("/"));
1838
+ assetPath = path13__default.default.join(assetsBase, segments.slice(1).join("/"));
1695
1839
  } else {
1696
- assetPath = path11__default.default.join(assetsBase, subpath);
1840
+ assetPath = path13__default.default.join(assetsBase, subpath);
1697
1841
  }
1698
1842
  if (assetPath.startsWith(assetsBase) && fs3__default.default.existsSync(assetPath)) {
1699
1843
  serveFile(res, assetPath);
1700
1844
  return;
1701
1845
  }
1702
1846
  if (segments.length > 1) {
1703
- const fallbackPath = path11__default.default.join(assetsBase, segments.slice(1).join("/"));
1847
+ const fallbackPath = path13__default.default.join(assetsBase, segments.slice(1).join("/"));
1704
1848
  if (fallbackPath.startsWith(assetsBase) && fs3__default.default.existsSync(fallbackPath)) {
1705
1849
  serveFile(res, fallbackPath);
1706
1850
  return;
1707
1851
  }
1708
1852
  }
1709
1853
  }
1710
- const filePath = path11__default.default.join(options.distDir, pathname);
1854
+ const filePath = path13__default.default.join(options.distDir, pathname);
1711
1855
  if (!filePath.startsWith(options.distDir)) {
1712
1856
  res.writeHead(403);
1713
1857
  res.end("Forbidden");
@@ -1750,7 +1894,7 @@ function serveFile(res, filePath) {
1750
1894
  res.end("Not Found");
1751
1895
  return;
1752
1896
  }
1753
- const ext = path11__default.default.extname(filePath);
1897
+ const ext = path13__default.default.extname(filePath);
1754
1898
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
1755
1899
  const content = fs3__default.default.readFileSync(filePath);
1756
1900
  res.writeHead(200, { "Content-Type": contentType });
@@ -1867,26 +2011,26 @@ var init_dev_server = __esm({
1867
2011
  // src/utils/file-helpers.ts
1868
2012
  init_logger();
1869
2013
  async function renderTemplate(templatePath, data) {
1870
- const template = await fs__default.default.readFile(templatePath, "utf-8");
2014
+ const template = await fs8__default.default.readFile(templatePath, "utf-8");
1871
2015
  return ejs__default.default.render(template, data);
1872
2016
  }
1873
2017
  async function writeFile(filePath, content) {
1874
- await fs__default.default.ensureDir(path11__default.default.dirname(filePath));
1875
- await fs__default.default.writeFile(filePath, content, "utf-8");
2018
+ await fs8__default.default.ensureDir(path13__default.default.dirname(filePath));
2019
+ await fs8__default.default.writeFile(filePath, content, "utf-8");
1876
2020
  }
1877
2021
  function getTemplatesDir() {
1878
2022
  const locations = [
1879
- path11__default.default.join(__dirname, "../../templates"),
2023
+ path13__default.default.join(__dirname, "../../templates"),
1880
2024
  // Development
1881
- path11__default.default.join(__dirname, "../templates"),
2025
+ path13__default.default.join(__dirname, "../templates"),
1882
2026
  // Production (dist/)
1883
- path11__default.default.join(process.cwd(), "templates"),
2027
+ path13__default.default.join(process.cwd(), "templates"),
1884
2028
  // Fallback
1885
- path11__default.default.join(process.cwd(), "packages/cli/templates")
2029
+ path13__default.default.join(process.cwd(), "packages/cli/templates")
1886
2030
  // Monorepo
1887
2031
  ];
1888
2032
  for (const location of locations) {
1889
- if (fs__default.default.existsSync(location)) {
2033
+ if (fs8__default.default.existsSync(location)) {
1890
2034
  return location;
1891
2035
  }
1892
2036
  }
@@ -1894,18 +2038,18 @@ function getTemplatesDir() {
1894
2038
  }
1895
2039
  async function copyTemplate(templateName, targetDir, data) {
1896
2040
  const templatesDir = getTemplatesDir();
1897
- const templateDir = path11__default.default.join(templatesDir, templateName);
1898
- if (!fs__default.default.existsSync(templateDir)) {
2041
+ const templateDir = path13__default.default.join(templatesDir, templateName);
2042
+ if (!fs8__default.default.existsSync(templateDir)) {
1899
2043
  throw new Error(
1900
- `Template "${templateName}" not found at ${templateDir}. Available templates: ${fs__default.default.readdirSync(templatesDir).join(", ")}`
2044
+ `Template "${templateName}" not found at ${templateDir}. Available templates: ${fs8__default.default.readdirSync(templatesDir).join(", ")}`
1901
2045
  );
1902
2046
  }
1903
- await fs__default.default.ensureDir(targetDir);
1904
- const files = await fs__default.default.readdir(templateDir);
2047
+ await fs8__default.default.ensureDir(targetDir);
2048
+ const files = await fs8__default.default.readdir(templateDir);
1905
2049
  for (const file of files) {
1906
- const templatePath = path11__default.default.join(templateDir, file);
1907
- const targetPath = path11__default.default.join(targetDir, file);
1908
- const stat = await fs__default.default.stat(templatePath);
2050
+ const templatePath = path13__default.default.join(templateDir, file);
2051
+ const targetPath = path13__default.default.join(targetDir, file);
2052
+ const stat = await fs8__default.default.stat(templatePath);
1909
2053
  if (stat.isDirectory()) {
1910
2054
  await copyTemplateDir(templatePath, targetPath, data);
1911
2055
  } else if (file.endsWith(".ejs")) {
@@ -1913,17 +2057,17 @@ async function copyTemplate(templateName, targetDir, data) {
1913
2057
  const outputPath = targetPath.replace(/\.ejs$/, "");
1914
2058
  await writeFile(outputPath, content);
1915
2059
  } else {
1916
- await fs__default.default.copy(templatePath, targetPath);
2060
+ await fs8__default.default.copy(templatePath, targetPath);
1917
2061
  }
1918
2062
  }
1919
2063
  }
1920
2064
  async function copyTemplateDir(templateDir, targetDir, data) {
1921
- await fs__default.default.ensureDir(targetDir);
1922
- const files = await fs__default.default.readdir(templateDir);
2065
+ await fs8__default.default.ensureDir(targetDir);
2066
+ const files = await fs8__default.default.readdir(templateDir);
1923
2067
  for (const file of files) {
1924
- const templatePath = path11__default.default.join(templateDir, file);
1925
- const targetPath = path11__default.default.join(targetDir, file);
1926
- const stat = await fs__default.default.stat(templatePath);
2068
+ const templatePath = path13__default.default.join(templateDir, file);
2069
+ const targetPath = path13__default.default.join(targetDir, file);
2070
+ const stat = await fs8__default.default.stat(templatePath);
1927
2071
  if (stat.isDirectory()) {
1928
2072
  await copyTemplateDir(templatePath, targetPath, data);
1929
2073
  } else if (file.endsWith(".ejs")) {
@@ -1931,38 +2075,38 @@ async function copyTemplateDir(templateDir, targetDir, data) {
1931
2075
  const outputPath = targetPath.replace(/\.ejs$/, "");
1932
2076
  await writeFile(outputPath, content);
1933
2077
  } else {
1934
- await fs__default.default.copy(templatePath, targetPath);
2078
+ await fs8__default.default.copy(templatePath, targetPath);
1935
2079
  }
1936
2080
  }
1937
2081
  }
1938
2082
  function getProjectRoot() {
1939
2083
  let currentDir = process.cwd();
1940
- while (currentDir !== path11__default.default.parse(currentDir).root) {
1941
- const packageJsonPath = path11__default.default.join(currentDir, "package.json");
1942
- if (fs__default.default.existsSync(packageJsonPath)) {
1943
- const packageJson = fs__default.default.readJsonSync(packageJsonPath);
1944
- if (packageJson.workspaces || fs__default.default.existsSync(path11__default.default.join(currentDir, "src/themes")) || fs__default.default.existsSync(path11__default.default.join(currentDir, "themes"))) {
2084
+ while (currentDir !== path13__default.default.parse(currentDir).root) {
2085
+ const packageJsonPath = path13__default.default.join(currentDir, "package.json");
2086
+ if (fs8__default.default.existsSync(packageJsonPath)) {
2087
+ const packageJson = fs8__default.default.readJsonSync(packageJsonPath);
2088
+ if (packageJson.workspaces || fs8__default.default.existsSync(path13__default.default.join(currentDir, "src/themes")) || fs8__default.default.existsSync(path13__default.default.join(currentDir, "themes"))) {
1945
2089
  return currentDir;
1946
2090
  }
1947
2091
  }
1948
- currentDir = path11__default.default.dirname(currentDir);
2092
+ currentDir = path13__default.default.dirname(currentDir);
1949
2093
  }
1950
2094
  return process.cwd();
1951
2095
  }
1952
2096
  function getThemesDir() {
1953
2097
  const root = getProjectRoot();
1954
- if (fs__default.default.existsSync(path11__default.default.join(root, "themes")))
1955
- return path11__default.default.join(root, "themes");
1956
- if (fs__default.default.existsSync(path11__default.default.join(root, "src/themes")))
1957
- return path11__default.default.join(root, "src/themes");
1958
- return path11__default.default.dirname(root);
2098
+ if (fs8__default.default.existsSync(path13__default.default.join(root, "themes")))
2099
+ return path13__default.default.join(root, "themes");
2100
+ if (fs8__default.default.existsSync(path13__default.default.join(root, "src/themes")))
2101
+ return path13__default.default.join(root, "src/themes");
2102
+ return path13__default.default.dirname(root);
1959
2103
  }
1960
2104
  function getFeaturesDir() {
1961
- return path11__default.default.join(getProjectRoot(), "src/features");
2105
+ return path13__default.default.join(getProjectRoot(), "src/features");
1962
2106
  }
1963
2107
  function isOneXProject() {
1964
2108
  const root = getProjectRoot();
1965
- return fs__default.default.existsSync(path11__default.default.join(root, "themes")) || fs__default.default.existsSync(path11__default.default.join(root, "src/themes")) || fs__default.default.existsSync(path11__default.default.join(root, "theme.config.ts")) || fs__default.default.existsSync(path11__default.default.join(root, "bundle-entry.ts"));
2109
+ return fs8__default.default.existsSync(path13__default.default.join(root, "themes")) || fs8__default.default.existsSync(path13__default.default.join(root, "src/themes")) || fs8__default.default.existsSync(path13__default.default.join(root, "theme.config.ts")) || fs8__default.default.existsSync(path13__default.default.join(root, "bundle-entry.ts"));
1966
2110
  }
1967
2111
  function ensureOneXProject() {
1968
2112
  if (!isOneXProject()) {
@@ -1974,17 +2118,17 @@ function ensureOneXProject() {
1974
2118
  }
1975
2119
  function listThemes() {
1976
2120
  const themesDir = getThemesDir();
1977
- if (!fs__default.default.existsSync(themesDir)) {
2121
+ if (!fs8__default.default.existsSync(themesDir)) {
1978
2122
  return [];
1979
2123
  }
1980
- return fs__default.default.readdirSync(themesDir).filter((name) => {
1981
- const themePath = path11__default.default.join(themesDir, name);
1982
- return fs__default.default.statSync(themePath).isDirectory() && (fs__default.default.existsSync(path11__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path11__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path11__default.default.join(themePath, "manifest.ts")));
2124
+ return fs8__default.default.readdirSync(themesDir).filter((name) => {
2125
+ const themePath = path13__default.default.join(themesDir, name);
2126
+ return fs8__default.default.statSync(themePath).isDirectory() && (fs8__default.default.existsSync(path13__default.default.join(themePath, "theme.config.ts")) || fs8__default.default.existsSync(path13__default.default.join(themePath, "bundle-entry.ts")) || fs8__default.default.existsSync(path13__default.default.join(themePath, "manifest.ts")));
1983
2127
  });
1984
2128
  }
1985
2129
  function themeExists(themeName) {
1986
- const themePath = path11__default.default.join(getThemesDir(), themeName);
1987
- return fs__default.default.existsSync(themePath) && (fs__default.default.existsSync(path11__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path11__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path11__default.default.join(themePath, "manifest.ts")));
2130
+ const themePath = path13__default.default.join(getThemesDir(), themeName);
2131
+ return fs8__default.default.existsSync(themePath) && (fs8__default.default.existsSync(path13__default.default.join(themePath, "theme.config.ts")) || fs8__default.default.existsSync(path13__default.default.join(themePath, "bundle-entry.ts")) || fs8__default.default.existsSync(path13__default.default.join(themePath, "manifest.ts")));
1988
2132
  }
1989
2133
  function detectPackageManager() {
1990
2134
  const userAgent = process.env.npm_config_user_agent || "";
@@ -1992,9 +2136,9 @@ function detectPackageManager() {
1992
2136
  if (userAgent.includes("yarn")) return "yarn";
1993
2137
  if (userAgent.includes("bun")) return "bun";
1994
2138
  const cwd = process.cwd();
1995
- if (fs__default.default.existsSync(path11__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
1996
- if (fs__default.default.existsSync(path11__default.default.join(cwd, "yarn.lock"))) return "yarn";
1997
- if (fs__default.default.existsSync(path11__default.default.join(cwd, "bun.lockb"))) return "bun";
2139
+ if (fs8__default.default.existsSync(path13__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
2140
+ if (fs8__default.default.existsSync(path13__default.default.join(cwd, "yarn.lock"))) return "yarn";
2141
+ if (fs8__default.default.existsSync(path13__default.default.join(cwd, "bun.lockb"))) return "bun";
1998
2142
  return "npm";
1999
2143
  }
2000
2144
  async function installDependencies(projectPath, packageManager = "npm") {
@@ -2043,23 +2187,23 @@ function getValidCategories() {
2043
2187
  "contact"
2044
2188
  ];
2045
2189
  }
2046
- var AUTH_DIR = path11__default.default.join(os__default.default.homedir(), ".onexthm");
2190
+ var AUTH_DIR = path13__default.default.join(os__default.default.homedir(), ".onexthm");
2047
2191
  var ENV_URLS = {
2048
2192
  dev: "https://platform-dev.onexeos.com",
2049
2193
  staging: "https://platform-staging.onexeos.com",
2050
2194
  prod: "https://platform-apis.onexeos.com"
2051
2195
  };
2052
2196
  function getAuthFile(env = "dev") {
2053
- const newFile = path11__default.default.join(AUTH_DIR, `auth-${env}.json`);
2197
+ const newFile = path13__default.default.join(AUTH_DIR, `auth-${env}.json`);
2054
2198
  if (env === "dev") {
2055
- const legacyFile = path11__default.default.join(AUTH_DIR, "auth.json");
2056
- if (fs__default.default.existsSync(legacyFile) && !fs__default.default.existsSync(newFile)) {
2199
+ const legacyFile = path13__default.default.join(AUTH_DIR, "auth.json");
2200
+ if (fs8__default.default.existsSync(legacyFile) && !fs8__default.default.existsSync(newFile)) {
2057
2201
  try {
2058
- fs__default.default.moveSync(legacyFile, newFile);
2202
+ fs8__default.default.moveSync(legacyFile, newFile);
2059
2203
  } catch {
2060
2204
  try {
2061
- fs__default.default.copySync(legacyFile, newFile);
2062
- fs__default.default.removeSync(legacyFile);
2205
+ fs8__default.default.copySync(legacyFile, newFile);
2206
+ fs8__default.default.removeSync(legacyFile);
2063
2207
  } catch {
2064
2208
  }
2065
2209
  }
@@ -2071,17 +2215,17 @@ function getApiUrl(env = "dev") {
2071
2215
  return process.env.ONEXTHM_API_URL || ENV_URLS[env];
2072
2216
  }
2073
2217
  async function saveAuthTokens(tokens, env = "dev") {
2074
- await fs__default.default.ensureDir(AUTH_DIR);
2218
+ await fs8__default.default.ensureDir(AUTH_DIR);
2075
2219
  const key = getMachineKey();
2076
2220
  const data = JSON.stringify(tokens);
2077
2221
  const encrypted = encrypt(data, key);
2078
- await fs__default.default.writeFile(getAuthFile(env), encrypted, "utf-8");
2222
+ await fs8__default.default.writeFile(getAuthFile(env), encrypted, "utf-8");
2079
2223
  }
2080
2224
  function loadAuthTokens(env = "dev") {
2081
2225
  try {
2082
2226
  const file = getAuthFile(env);
2083
- if (!fs__default.default.existsSync(file)) return null;
2084
- const encrypted = fs__default.default.readFileSync(file, "utf-8");
2227
+ if (!fs8__default.default.existsSync(file)) return null;
2228
+ const encrypted = fs8__default.default.readFileSync(file, "utf-8");
2085
2229
  const key = getMachineKey();
2086
2230
  const data = decrypt(encrypted, key);
2087
2231
  return JSON.parse(data);
@@ -2091,7 +2235,7 @@ function loadAuthTokens(env = "dev") {
2091
2235
  }
2092
2236
  async function clearAuthTokens(env = "dev") {
2093
2237
  try {
2094
- await fs__default.default.remove(getAuthFile(env));
2238
+ await fs8__default.default.remove(getAuthFile(env));
2095
2239
  } catch {
2096
2240
  }
2097
2241
  }
@@ -2150,7 +2294,7 @@ function getMachineKey() {
2150
2294
  seed = `onexthm:${os__default.default.hostname()}:${os__default.default.userInfo().username}`;
2151
2295
  } else if (process.platform === "linux") {
2152
2296
  try {
2153
- seed = `onexthm:${fs__default.default.readFileSync("/etc/machine-id", "utf-8").trim()}`;
2297
+ seed = `onexthm:${fs8__default.default.readFileSync("/etc/machine-id", "utf-8").trim()}`;
2154
2298
  } catch {
2155
2299
  seed = `onexthm:${os__default.default.hostname()}:${os__default.default.userInfo().username}`;
2156
2300
  }
@@ -2188,7 +2332,7 @@ function parseJwtClaims(idToken) {
2188
2332
  }
2189
2333
 
2190
2334
  // src/commands/init.ts
2191
- async function initCommand(projectName, options = {}) {
2335
+ async function initCommand(projectName, options) {
2192
2336
  logger.header("Create New OneX Theme Project");
2193
2337
  let name;
2194
2338
  if (!projectName) {
@@ -2203,7 +2347,7 @@ async function initCommand(projectName, options = {}) {
2203
2347
  if (!validateThemeName(kebabName)) {
2204
2348
  return "Invalid project name. Use lowercase letters, numbers, and hyphens only.";
2205
2349
  }
2206
- if (fs3__default.default.existsSync(path11__default.default.join(process.cwd(), kebabName))) {
2350
+ if (fs3__default.default.existsSync(path13__default.default.join(process.cwd(), kebabName))) {
2207
2351
  return `Directory "${kebabName}" already exists`;
2208
2352
  }
2209
2353
  return true;
@@ -2214,14 +2358,14 @@ async function initCommand(projectName, options = {}) {
2214
2358
  } else {
2215
2359
  name = toKebabCase(projectName);
2216
2360
  }
2217
- const projectPath = path11__default.default.join(process.cwd(), name);
2361
+ const projectPath = path13__default.default.join(process.cwd(), name);
2218
2362
  if (fs3__default.default.existsSync(projectPath)) {
2219
2363
  logger.error(`Directory "${name}" already exists.`);
2220
2364
  process.exit(1);
2221
2365
  }
2222
2366
  if (!options.yes) {
2223
2367
  try {
2224
- const apiUrl = getApiUrl(options.env ?? "dev");
2368
+ const apiUrl = getApiUrl(options.env);
2225
2369
  const controller = new AbortController();
2226
2370
  const timeout = setTimeout(() => controller.abort(), 3e3);
2227
2371
  const response = await fetch(
@@ -2330,7 +2474,7 @@ async function initCommand(projectName, options = {}) {
2330
2474
  description,
2331
2475
  author
2332
2476
  );
2333
- const mcpJsonPath = path11__default.default.join(projectPath, ".mcp.json");
2477
+ const mcpJsonPath = path13__default.default.join(projectPath, ".mcp.json");
2334
2478
  if (fs3__default.default.existsSync(mcpJsonPath)) {
2335
2479
  let mcpContent = fs3__default.default.readFileSync(mcpJsonPath, "utf-8");
2336
2480
  if (figmaApiKey) {
@@ -2410,7 +2554,7 @@ async function initCommand(projectName, options = {}) {
2410
2554
  }
2411
2555
  }
2412
2556
  async function renameThemeInFiles(projectPath, themeName, displayName, description, author) {
2413
- const configPath = path11__default.default.join(projectPath, "theme.config.ts");
2557
+ const configPath = path13__default.default.join(projectPath, "theme.config.ts");
2414
2558
  if (fs3__default.default.existsSync(configPath)) {
2415
2559
  let content = fs3__default.default.readFileSync(configPath, "utf-8");
2416
2560
  content = content.replace(
@@ -2423,7 +2567,7 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
2423
2567
  );
2424
2568
  fs3__default.default.writeFileSync(configPath, content, "utf-8");
2425
2569
  }
2426
- const pkgPath = path11__default.default.join(projectPath, "package.json");
2570
+ const pkgPath = path13__default.default.join(projectPath, "package.json");
2427
2571
  if (fs3__default.default.existsSync(pkgPath)) {
2428
2572
  let content = fs3__default.default.readFileSync(pkgPath, "utf-8");
2429
2573
  content = content.replace(
@@ -2445,10 +2589,10 @@ async function createSectionCommand(name, options) {
2445
2589
  ensureOneXProject();
2446
2590
  if (!options.theme) {
2447
2591
  const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
2448
- (f) => fs__default.default.existsSync(path11__default.default.join(process.cwd(), f))
2592
+ (f) => fs8__default.default.existsSync(path13__default.default.join(process.cwd(), f))
2449
2593
  );
2450
2594
  if (isStandaloneTheme) {
2451
- options.theme = path11__default.default.basename(process.cwd());
2595
+ options.theme = path13__default.default.basename(process.cwd());
2452
2596
  }
2453
2597
  }
2454
2598
  const sectionName = toKebabCase(name);
@@ -2511,35 +2655,35 @@ async function createSectionCommand(name, options) {
2511
2655
  };
2512
2656
  logger.startSpinner("Creating section files...");
2513
2657
  try {
2514
- const themePath = path11__default.default.join(getThemesDir(), themeName);
2515
- const sectionPath = path11__default.default.join(themePath, "sections", sectionName);
2658
+ const themePath = path13__default.default.join(getThemesDir(), themeName);
2659
+ const sectionPath = path13__default.default.join(themePath, "sections", sectionName);
2516
2660
  const schemaContent = generateSectionSchema(data);
2517
2661
  await writeFile(
2518
- path11__default.default.join(sectionPath, `${sectionName}.schema.ts`),
2662
+ path13__default.default.join(sectionPath, `${sectionName}.schema.ts`),
2519
2663
  schemaContent
2520
2664
  );
2521
2665
  if (createTemplate) {
2522
2666
  const templateContent = generateSectionTemplate(data);
2523
2667
  await writeFile(
2524
- path11__default.default.join(sectionPath, `${sectionName}-default.tsx`),
2668
+ path13__default.default.join(sectionPath, `${sectionName}-default.tsx`),
2525
2669
  templateContent
2526
2670
  );
2527
2671
  }
2528
2672
  const indexContent = generateSectionIndex(data, createTemplate);
2529
- await writeFile(path11__default.default.join(sectionPath, "index.ts"), indexContent);
2673
+ await writeFile(path13__default.default.join(sectionPath, "index.ts"), indexContent);
2530
2674
  logger.stopSpinner(true, "Section files created successfully!");
2531
2675
  logger.newLine();
2532
2676
  logger.section("Next steps:");
2533
2677
  logger.log(
2534
- ` 1. Edit schema: ${path11__default.default.relative(process.cwd(), path11__default.default.join(sectionPath, `${sectionName}.schema.ts`))}`
2678
+ ` 1. Edit schema: ${path13__default.default.relative(process.cwd(), path13__default.default.join(sectionPath, `${sectionName}.schema.ts`))}`
2535
2679
  );
2536
2680
  if (createTemplate) {
2537
2681
  logger.log(
2538
- ` 2. Edit template: ${path11__default.default.relative(process.cwd(), path11__default.default.join(sectionPath, `${sectionName}-default.tsx`))}`
2682
+ ` 2. Edit template: ${path13__default.default.relative(process.cwd(), path13__default.default.join(sectionPath, `${sectionName}-default.tsx`))}`
2539
2683
  );
2540
2684
  }
2541
2685
  logger.log(
2542
- ` 3. Add to theme manifest: ${path11__default.default.relative(process.cwd(), path11__default.default.join(themePath, "manifest.ts"))}`
2686
+ ` 3. Add to theme manifest: ${path13__default.default.relative(process.cwd(), path13__default.default.join(themePath, "manifest.ts"))}`
2543
2687
  );
2544
2688
  logger.newLine();
2545
2689
  logger.success("Section created successfully!");
@@ -2687,10 +2831,10 @@ async function createBlockCommand(name, options) {
2687
2831
  ensureOneXProject();
2688
2832
  if (!options.theme) {
2689
2833
  const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
2690
- (f) => fs__default.default.existsSync(path11__default.default.join(process.cwd(), f))
2834
+ (f) => fs8__default.default.existsSync(path13__default.default.join(process.cwd(), f))
2691
2835
  );
2692
2836
  if (isStandaloneTheme) {
2693
- options.theme = path11__default.default.basename(process.cwd());
2837
+ options.theme = path13__default.default.basename(process.cwd());
2694
2838
  }
2695
2839
  }
2696
2840
  const blockName = toKebabCase(name);
@@ -2765,24 +2909,24 @@ async function createBlockCommand(name, options) {
2765
2909
  };
2766
2910
  logger.startSpinner("Creating block files...");
2767
2911
  try {
2768
- const blockPath = scope === "shared" ? path11__default.default.join(getFeaturesDir(), "blocks", blockName) : path11__default.default.join(getThemesDir(), themeName, "blocks", blockName);
2912
+ const blockPath = scope === "shared" ? path13__default.default.join(getFeaturesDir(), "blocks", blockName) : path13__default.default.join(getThemesDir(), themeName, "blocks", blockName);
2769
2913
  const schemaContent = generateBlockSchema(data);
2770
2914
  await writeFile(
2771
- path11__default.default.join(blockPath, `${blockName}.schema.ts`),
2915
+ path13__default.default.join(blockPath, `${blockName}.schema.ts`),
2772
2916
  schemaContent
2773
2917
  );
2774
2918
  const componentContent = generateBlockComponent(data);
2775
- await writeFile(path11__default.default.join(blockPath, `${blockName}.tsx`), componentContent);
2919
+ await writeFile(path13__default.default.join(blockPath, `${blockName}.tsx`), componentContent);
2776
2920
  const indexContent = generateBlockIndex(data);
2777
- await writeFile(path11__default.default.join(blockPath, "index.ts"), indexContent);
2921
+ await writeFile(path13__default.default.join(blockPath, "index.ts"), indexContent);
2778
2922
  logger.stopSpinner(true, "Block files created successfully!");
2779
2923
  logger.newLine();
2780
2924
  logger.section("Next steps:");
2781
2925
  logger.log(
2782
- ` 1. Edit schema: ${path11__default.default.relative(process.cwd(), path11__default.default.join(blockPath, `${blockName}.schema.ts`))}`
2926
+ ` 1. Edit schema: ${path13__default.default.relative(process.cwd(), path13__default.default.join(blockPath, `${blockName}.schema.ts`))}`
2783
2927
  );
2784
2928
  logger.log(
2785
- ` 2. Edit component: ${path11__default.default.relative(process.cwd(), path11__default.default.join(blockPath, `${blockName}.tsx`))}`
2929
+ ` 2. Edit component: ${path13__default.default.relative(process.cwd(), path13__default.default.join(blockPath, `${blockName}.tsx`))}`
2786
2930
  );
2787
2931
  logger.log(
2788
2932
  ` 3. Register in block registry: src/lib/registry/block-registry.ts`
@@ -2960,31 +3104,31 @@ async function createComponentCommand(name, options) {
2960
3104
  };
2961
3105
  logger.startSpinner("Creating component files...");
2962
3106
  try {
2963
- const componentPath = path11__default.default.join(
3107
+ const componentPath = path13__default.default.join(
2964
3108
  getFeaturesDir(),
2965
3109
  "components",
2966
3110
  componentName
2967
3111
  );
2968
3112
  const schemaContent = generateComponentSchema(data);
2969
3113
  await writeFile(
2970
- path11__default.default.join(componentPath, `${componentName}.schema.ts`),
3114
+ path13__default.default.join(componentPath, `${componentName}.schema.ts`),
2971
3115
  schemaContent
2972
3116
  );
2973
3117
  const componentContent = generateComponent(data);
2974
3118
  await writeFile(
2975
- path11__default.default.join(componentPath, `${componentName}.tsx`),
3119
+ path13__default.default.join(componentPath, `${componentName}.tsx`),
2976
3120
  componentContent
2977
3121
  );
2978
3122
  const indexContent = generateComponentIndex(data);
2979
- await writeFile(path11__default.default.join(componentPath, "index.ts"), indexContent);
3123
+ await writeFile(path13__default.default.join(componentPath, "index.ts"), indexContent);
2980
3124
  logger.stopSpinner(true, "Component files created successfully!");
2981
3125
  logger.newLine();
2982
3126
  logger.section("Next steps:");
2983
3127
  logger.log(
2984
- ` 1. Edit schema: ${path11__default.default.relative(process.cwd(), path11__default.default.join(componentPath, `${componentName}.schema.ts`))}`
3128
+ ` 1. Edit schema: ${path13__default.default.relative(process.cwd(), path13__default.default.join(componentPath, `${componentName}.schema.ts`))}`
2985
3129
  );
2986
3130
  logger.log(
2987
- ` 2. Edit component: ${path11__default.default.relative(process.cwd(), path11__default.default.join(componentPath, `${componentName}.tsx`))}`
3131
+ ` 2. Edit component: ${path13__default.default.relative(process.cwd(), path13__default.default.join(componentPath, `${componentName}.tsx`))}`
2988
3132
  );
2989
3133
  logger.log(
2990
3134
  ` 3. Register in component registry: src/lib/registry/component-registry.ts`
@@ -3141,13 +3285,13 @@ async function listSections(themeFilter) {
3141
3285
  return;
3142
3286
  }
3143
3287
  for (const theme of themes) {
3144
- const sectionsDir = path11__default.default.join(getThemesDir(), theme, "sections");
3145
- if (!fs__default.default.existsSync(sectionsDir)) {
3288
+ const sectionsDir = path13__default.default.join(getThemesDir(), theme, "sections");
3289
+ if (!fs8__default.default.existsSync(sectionsDir)) {
3146
3290
  continue;
3147
3291
  }
3148
- const sections = fs__default.default.readdirSync(sectionsDir).filter((name) => {
3149
- const sectionPath = path11__default.default.join(sectionsDir, name);
3150
- return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(path11__default.default.join(sectionPath, "index.ts"));
3292
+ const sections = fs8__default.default.readdirSync(sectionsDir).filter((name) => {
3293
+ const sectionPath = path13__default.default.join(sectionsDir, name);
3294
+ return fs8__default.default.statSync(sectionPath).isDirectory() && fs8__default.default.existsSync(path13__default.default.join(sectionPath, "index.ts"));
3151
3295
  });
3152
3296
  if (sections.length > 0) {
3153
3297
  logger.log(chalk4__default.default.cyan(`
@@ -3161,11 +3305,11 @@ async function listSections(themeFilter) {
3161
3305
  }
3162
3306
  async function listBlocks(themeFilter) {
3163
3307
  logger.section("\u{1F9F1} Blocks");
3164
- const sharedBlocksDir = path11__default.default.join(getFeaturesDir(), "blocks");
3165
- if (fs__default.default.existsSync(sharedBlocksDir)) {
3166
- const sharedBlocks = fs__default.default.readdirSync(sharedBlocksDir).filter((name) => {
3167
- const blockPath = path11__default.default.join(sharedBlocksDir, name);
3168
- return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path11__default.default.join(blockPath, "index.ts"));
3308
+ const sharedBlocksDir = path13__default.default.join(getFeaturesDir(), "blocks");
3309
+ if (fs8__default.default.existsSync(sharedBlocksDir)) {
3310
+ const sharedBlocks = fs8__default.default.readdirSync(sharedBlocksDir).filter((name) => {
3311
+ const blockPath = path13__default.default.join(sharedBlocksDir, name);
3312
+ return fs8__default.default.statSync(blockPath).isDirectory() && fs8__default.default.existsSync(path13__default.default.join(blockPath, "index.ts"));
3169
3313
  });
3170
3314
  if (sharedBlocks.length > 0) {
3171
3315
  logger.log(chalk4__default.default.cyan("\n Shared:"));
@@ -3176,13 +3320,13 @@ async function listBlocks(themeFilter) {
3176
3320
  }
3177
3321
  const themes = themeFilter ? [themeFilter] : listThemes();
3178
3322
  for (const theme of themes) {
3179
- const blocksDir = path11__default.default.join(getThemesDir(), theme, "blocks");
3180
- if (!fs__default.default.existsSync(blocksDir)) {
3323
+ const blocksDir = path13__default.default.join(getThemesDir(), theme, "blocks");
3324
+ if (!fs8__default.default.existsSync(blocksDir)) {
3181
3325
  continue;
3182
3326
  }
3183
- const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => {
3184
- const blockPath = path11__default.default.join(blocksDir, name);
3185
- return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path11__default.default.join(blockPath, "index.ts"));
3327
+ const blocks = fs8__default.default.readdirSync(blocksDir).filter((name) => {
3328
+ const blockPath = path13__default.default.join(blocksDir, name);
3329
+ return fs8__default.default.statSync(blockPath).isDirectory() && fs8__default.default.existsSync(path13__default.default.join(blockPath, "index.ts"));
3186
3330
  });
3187
3331
  if (blocks.length > 0) {
3188
3332
  logger.log(chalk4__default.default.cyan(`
@@ -3196,14 +3340,14 @@ async function listBlocks(themeFilter) {
3196
3340
  }
3197
3341
  async function listComponents() {
3198
3342
  logger.section("\u2699\uFE0F Components");
3199
- const componentsDir = path11__default.default.join(getFeaturesDir(), "components");
3200
- if (!fs__default.default.existsSync(componentsDir)) {
3343
+ const componentsDir = path13__default.default.join(getFeaturesDir(), "components");
3344
+ if (!fs8__default.default.existsSync(componentsDir)) {
3201
3345
  logger.warning("No components directory found");
3202
3346
  return;
3203
3347
  }
3204
- const components = fs__default.default.readdirSync(componentsDir).filter((name) => {
3205
- const componentPath = path11__default.default.join(componentsDir, name);
3206
- return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(path11__default.default.join(componentPath, "index.ts"));
3348
+ const components = fs8__default.default.readdirSync(componentsDir).filter((name) => {
3349
+ const componentPath = path13__default.default.join(componentsDir, name);
3350
+ return fs8__default.default.statSync(componentPath).isDirectory() && fs8__default.default.existsSync(path13__default.default.join(componentPath, "index.ts"));
3207
3351
  });
3208
3352
  if (components.length === 0) {
3209
3353
  logger.warning("No components found");
@@ -3224,13 +3368,13 @@ async function listThemesInfo() {
3224
3368
  }
3225
3369
  logger.log("");
3226
3370
  for (const theme of themes) {
3227
- const themeDir = path11__default.default.join(getThemesDir(), theme);
3371
+ const themeDir = path13__default.default.join(getThemesDir(), theme);
3228
3372
  const candidates = ["theme.config.ts", "bundle-entry.ts", "manifest.ts"];
3229
3373
  let manifestContent = "";
3230
3374
  for (const candidate of candidates) {
3231
- const candidatePath = path11__default.default.join(themeDir, candidate);
3232
- if (fs__default.default.existsSync(candidatePath)) {
3233
- manifestContent = fs__default.default.readFileSync(candidatePath, "utf-8");
3375
+ const candidatePath = path13__default.default.join(themeDir, candidate);
3376
+ if (fs8__default.default.existsSync(candidatePath)) {
3377
+ manifestContent = fs8__default.default.readFileSync(candidatePath, "utf-8");
3234
3378
  break;
3235
3379
  }
3236
3380
  }
@@ -3250,6 +3394,7 @@ async function listThemesInfo() {
3250
3394
 
3251
3395
  // src/commands/validate.ts
3252
3396
  init_logger();
3397
+ init_detect_nextjs();
3253
3398
  async function validateCommand(options) {
3254
3399
  logger.header("Validate Theme");
3255
3400
  ensureOneXProject();
@@ -3265,10 +3410,13 @@ async function validateCommand(options) {
3265
3410
  const isThemeDir2 = [
3266
3411
  "theme.config.ts",
3267
3412
  "bundle-entry.ts",
3268
- "manifest.ts"
3269
- ].some((f) => fs__default.default.existsSync(path11__default.default.join(process.cwd(), f)));
3413
+ "manifest.ts",
3414
+ "next.config.ts",
3415
+ "next.config.js",
3416
+ "next.config.mjs"
3417
+ ].some((f) => fs8__default.default.existsSync(path13__default.default.join(process.cwd(), f)));
3270
3418
  if (isThemeDir2) {
3271
- themeToValidate = path11__default.default.basename(process.cwd());
3419
+ themeToValidate = path13__default.default.basename(process.cwd());
3272
3420
  logger.info(`Validating current theme: ${themeToValidate}`);
3273
3421
  } else {
3274
3422
  logger.error(
@@ -3277,11 +3425,11 @@ async function validateCommand(options) {
3277
3425
  process.exit(1);
3278
3426
  }
3279
3427
  }
3280
- const themePath = path11__default.default.join(getThemesDir(), themeToValidate);
3428
+ const themePath = path13__default.default.join(getThemesDir(), themeToValidate);
3281
3429
  logger.startSpinner("Running validation checks...");
3282
3430
  const entryFiles = ["manifest.ts", "theme.config.ts", "bundle-entry.ts"];
3283
3431
  const foundEntry = entryFiles.find(
3284
- (f) => fs__default.default.existsSync(path11__default.default.join(themePath, f))
3432
+ (f) => fs8__default.default.existsSync(path13__default.default.join(themePath, f))
3285
3433
  );
3286
3434
  if (!foundEntry) {
3287
3435
  issues.push({
@@ -3290,8 +3438,8 @@ async function validateCommand(options) {
3290
3438
  message: "No theme entry file found (need at least one of: manifest.ts, theme.config.ts, bundle-entry.ts)"
3291
3439
  });
3292
3440
  } else if (foundEntry === "manifest.ts") {
3293
- const manifestContent = fs__default.default.readFileSync(
3294
- path11__default.default.join(themePath, foundEntry),
3441
+ const manifestContent = fs8__default.default.readFileSync(
3442
+ path13__default.default.join(themePath, foundEntry),
3295
3443
  "utf-8"
3296
3444
  );
3297
3445
  if (!manifestContent.includes("export const") && !manifestContent.includes("export default") && !manifestContent.includes("export interface")) {
@@ -3302,56 +3450,56 @@ async function validateCommand(options) {
3302
3450
  });
3303
3451
  }
3304
3452
  }
3305
- const configPath = path11__default.default.join(themePath, "theme.config.ts");
3306
- if (!fs__default.default.existsSync(configPath)) {
3453
+ const configPath = path13__default.default.join(themePath, "theme.config.ts");
3454
+ if (!fs8__default.default.existsSync(configPath)) {
3307
3455
  issues.push({
3308
3456
  type: "warning",
3309
3457
  file: "theme.config.ts",
3310
3458
  message: "Theme config file not found (recommended)"
3311
3459
  });
3312
3460
  }
3313
- const indexPath = path11__default.default.join(themePath, "index.ts");
3314
- if (!fs__default.default.existsSync(indexPath)) {
3461
+ const indexPath = path13__default.default.join(themePath, "index.ts");
3462
+ if (!fs8__default.default.existsSync(indexPath)) {
3315
3463
  issues.push({
3316
3464
  type: "warning",
3317
3465
  file: "index.ts",
3318
3466
  message: "Index file not found (recommended)"
3319
3467
  });
3320
3468
  }
3321
- const sectionsDir = path11__default.default.join(themePath, "sections");
3322
- if (!fs__default.default.existsSync(sectionsDir)) {
3469
+ const sectionsDir = path13__default.default.join(themePath, "sections");
3470
+ if (!fs8__default.default.existsSync(sectionsDir)) {
3323
3471
  issues.push({
3324
3472
  type: "warning",
3325
3473
  file: "sections/",
3326
3474
  message: "Sections directory not found"
3327
3475
  });
3328
3476
  } else {
3329
- const sections = fs__default.default.readdirSync(sectionsDir).filter(
3330
- (name) => fs__default.default.statSync(path11__default.default.join(sectionsDir, name)).isDirectory()
3477
+ const sections = fs8__default.default.readdirSync(sectionsDir).filter(
3478
+ (name) => fs8__default.default.statSync(path13__default.default.join(sectionsDir, name)).isDirectory()
3331
3479
  );
3332
3480
  for (const sectionName of sections) {
3333
- const sectionPath = path11__default.default.join(sectionsDir, sectionName);
3334
- const schemaFile = path11__default.default.join(sectionPath, `${sectionName}.schema.ts`);
3335
- const defaultTemplate = path11__default.default.join(
3481
+ const sectionPath = path13__default.default.join(sectionsDir, sectionName);
3482
+ const schemaFile = path13__default.default.join(sectionPath, `${sectionName}.schema.ts`);
3483
+ const defaultTemplate = path13__default.default.join(
3336
3484
  sectionPath,
3337
3485
  `${sectionName}-default.tsx`
3338
3486
  );
3339
- const indexFile = path11__default.default.join(sectionPath, "index.ts");
3340
- if (!fs__default.default.existsSync(schemaFile)) {
3487
+ const indexFile = path13__default.default.join(sectionPath, "index.ts");
3488
+ if (!fs8__default.default.existsSync(schemaFile)) {
3341
3489
  issues.push({
3342
3490
  type: "error",
3343
3491
  file: `sections/${sectionName}/${sectionName}.schema.ts`,
3344
3492
  message: "Section schema file missing"
3345
3493
  });
3346
3494
  }
3347
- if (!fs__default.default.existsSync(indexFile)) {
3495
+ if (!fs8__default.default.existsSync(indexFile)) {
3348
3496
  issues.push({
3349
3497
  type: "error",
3350
3498
  file: `sections/${sectionName}/index.ts`,
3351
3499
  message: "Section index file missing"
3352
3500
  });
3353
3501
  }
3354
- if (!fs__default.default.existsSync(defaultTemplate)) {
3502
+ if (!fs8__default.default.existsSync(defaultTemplate)) {
3355
3503
  issues.push({
3356
3504
  type: "warning",
3357
3505
  file: `sections/${sectionName}/${sectionName}-default.tsx`,
@@ -3360,29 +3508,29 @@ async function validateCommand(options) {
3360
3508
  }
3361
3509
  }
3362
3510
  }
3363
- const blocksDir = path11__default.default.join(themePath, "blocks");
3364
- if (fs__default.default.existsSync(blocksDir)) {
3365
- const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => fs__default.default.statSync(path11__default.default.join(blocksDir, name)).isDirectory());
3511
+ const blocksDir = path13__default.default.join(themePath, "blocks");
3512
+ if (fs8__default.default.existsSync(blocksDir)) {
3513
+ const blocks = fs8__default.default.readdirSync(blocksDir).filter((name) => fs8__default.default.statSync(path13__default.default.join(blocksDir, name)).isDirectory());
3366
3514
  for (const blockName of blocks) {
3367
- const blockPath = path11__default.default.join(blocksDir, blockName);
3368
- const schemaFile = path11__default.default.join(blockPath, `${blockName}.schema.ts`);
3369
- const componentFile = path11__default.default.join(blockPath, `${blockName}.tsx`);
3370
- const indexFile = path11__default.default.join(blockPath, "index.ts");
3371
- if (!fs__default.default.existsSync(schemaFile)) {
3515
+ const blockPath = path13__default.default.join(blocksDir, blockName);
3516
+ const schemaFile = path13__default.default.join(blockPath, `${blockName}.schema.ts`);
3517
+ const componentFile = path13__default.default.join(blockPath, `${blockName}.tsx`);
3518
+ const indexFile = path13__default.default.join(blockPath, "index.ts");
3519
+ if (!fs8__default.default.existsSync(schemaFile)) {
3372
3520
  issues.push({
3373
3521
  type: "error",
3374
3522
  file: `blocks/${blockName}/${blockName}.schema.ts`,
3375
3523
  message: "Block schema file missing"
3376
3524
  });
3377
3525
  }
3378
- if (!fs__default.default.existsSync(componentFile)) {
3526
+ if (!fs8__default.default.existsSync(componentFile)) {
3379
3527
  issues.push({
3380
3528
  type: "error",
3381
3529
  file: `blocks/${blockName}/${blockName}.tsx`,
3382
3530
  message: "Block component file missing"
3383
3531
  });
3384
3532
  }
3385
- if (!fs__default.default.existsSync(indexFile)) {
3533
+ if (!fs8__default.default.existsSync(indexFile)) {
3386
3534
  issues.push({
3387
3535
  type: "error",
3388
3536
  file: `blocks/${blockName}/index.ts`,
@@ -3391,16 +3539,16 @@ async function validateCommand(options) {
3391
3539
  }
3392
3540
  }
3393
3541
  }
3394
- if (fs__default.default.existsSync(sectionsDir)) {
3395
- const sections = fs__default.default.readdirSync(sectionsDir).filter(
3396
- (name) => fs__default.default.statSync(path11__default.default.join(sectionsDir, name)).isDirectory()
3542
+ if (fs8__default.default.existsSync(sectionsDir)) {
3543
+ const sections = fs8__default.default.readdirSync(sectionsDir).filter(
3544
+ (name) => fs8__default.default.statSync(path13__default.default.join(sectionsDir, name)).isDirectory()
3397
3545
  );
3398
3546
  for (const sectionName of sections) {
3399
- const sectionPath = path11__default.default.join(sectionsDir, sectionName);
3400
- const tsxFiles = fs__default.default.readdirSync(sectionPath).filter((f) => f.endsWith(".tsx") && !f.endsWith(".schema.ts"));
3547
+ const sectionPath = path13__default.default.join(sectionsDir, sectionName);
3548
+ const tsxFiles = fs8__default.default.readdirSync(sectionPath).filter((f) => f.endsWith(".tsx") && !f.endsWith(".schema.ts"));
3401
3549
  for (const tsxFile of tsxFiles) {
3402
- const filePath = path11__default.default.join(sectionPath, tsxFile);
3403
- const content = fs__default.default.readFileSync(filePath, "utf-8");
3550
+ const filePath = path13__default.default.join(sectionPath, tsxFile);
3551
+ const content = fs8__default.default.readFileSync(filePath, "utf-8");
3404
3552
  const relPath = `sections/${sectionName}/${tsxFile}`;
3405
3553
  if (!content.includes('"use client"') && !content.includes("'use client'")) {
3406
3554
  issues.push({
@@ -3447,12 +3595,12 @@ async function validateCommand(options) {
3447
3595
  }
3448
3596
  }
3449
3597
  }
3450
- const registryPath = path11__default.default.join(themePath, "sections-registry.ts");
3451
- const bundleEntryPath = path11__default.default.join(themePath, "bundle-entry.ts");
3452
- const registryContent = fs__default.default.existsSync(registryPath) ? fs__default.default.readFileSync(registryPath, "utf-8") : fs__default.default.existsSync(bundleEntryPath) ? fs__default.default.readFileSync(bundleEntryPath, "utf-8") : "";
3453
- if (fs__default.default.existsSync(sectionsDir) && registryContent) {
3454
- const sections = fs__default.default.readdirSync(sectionsDir).filter(
3455
- (name) => fs__default.default.statSync(path11__default.default.join(sectionsDir, name)).isDirectory()
3598
+ const registryPath = path13__default.default.join(themePath, "sections-registry.ts");
3599
+ const bundleEntryPath = path13__default.default.join(themePath, "bundle-entry.ts");
3600
+ const registryContent = fs8__default.default.existsSync(registryPath) ? fs8__default.default.readFileSync(registryPath, "utf-8") : fs8__default.default.existsSync(bundleEntryPath) ? fs8__default.default.readFileSync(bundleEntryPath, "utf-8") : "";
3601
+ if (fs8__default.default.existsSync(sectionsDir) && registryContent) {
3602
+ const sections = fs8__default.default.readdirSync(sectionsDir).filter(
3603
+ (name) => fs8__default.default.statSync(path13__default.default.join(sectionsDir, name)).isDirectory()
3456
3604
  );
3457
3605
  for (const sectionName of sections) {
3458
3606
  if (!registryContent.includes(`sections/${sectionName}`) && !registryContent.includes(`"${sectionName}"`)) {
@@ -3464,7 +3612,7 @@ async function validateCommand(options) {
3464
3612
  }
3465
3613
  }
3466
3614
  }
3467
- if (fs__default.default.existsSync(sectionsDir)) {
3615
+ if (fs8__default.default.existsSync(sectionsDir)) {
3468
3616
  const schemaTypes = await loadSchemaTypes(themePath, sectionsDir);
3469
3617
  for (const { folderName, schemaType } of schemaTypes) {
3470
3618
  if (schemaType && schemaType !== folderName) {
@@ -3475,8 +3623,8 @@ async function validateCommand(options) {
3475
3623
  });
3476
3624
  }
3477
3625
  }
3478
- const pagesDir = path11__default.default.join(themePath, "pages");
3479
- if (fs__default.default.existsSync(pagesDir)) {
3626
+ const pagesDir = path13__default.default.join(themePath, "pages");
3627
+ if (fs8__default.default.existsSync(pagesDir)) {
3480
3628
  const allSchemaTypeSet = new Set(
3481
3629
  schemaTypes.map((s) => s.schemaType || s.folderName)
3482
3630
  );
@@ -3487,6 +3635,10 @@ async function validateCommand(options) {
3487
3635
  issues.push(...pageIssues);
3488
3636
  }
3489
3637
  }
3638
+ if (isNextjsProject(themePath)) {
3639
+ const nextjsIssues = await validateNextjsComponents(themePath);
3640
+ issues.push(...nextjsIssues);
3641
+ }
3490
3642
  logger.stopSpinner(true, "Validation complete");
3491
3643
  const errors = issues.filter((i) => i.type === "error");
3492
3644
  const warnings = issues.filter((i) => i.type === "warning");
@@ -3527,18 +3679,18 @@ async function validateCommand(options) {
3527
3679
  }
3528
3680
  async function loadSchemaTypes(themePath, sectionsDir) {
3529
3681
  const results = [];
3530
- const sections = fs__default.default.readdirSync(sectionsDir).filter((name) => fs__default.default.statSync(path11__default.default.join(sectionsDir, name)).isDirectory());
3682
+ const sections = fs8__default.default.readdirSync(sectionsDir).filter((name) => fs8__default.default.statSync(path13__default.default.join(sectionsDir, name)).isDirectory());
3531
3683
  for (const sectionName of sections) {
3532
- const schemaFile = path11__default.default.join(
3684
+ const schemaFile = path13__default.default.join(
3533
3685
  sectionsDir,
3534
3686
  sectionName,
3535
3687
  `${sectionName}.schema.ts`
3536
3688
  );
3537
- if (!fs__default.default.existsSync(schemaFile)) {
3689
+ if (!fs8__default.default.existsSync(schemaFile)) {
3538
3690
  results.push({ folderName: sectionName, schemaType: null });
3539
3691
  continue;
3540
3692
  }
3541
- const content = fs__default.default.readFileSync(schemaFile, "utf-8");
3693
+ const content = fs8__default.default.readFileSync(schemaFile, "utf-8");
3542
3694
  let schemaType = null;
3543
3695
  const schemaExportMatch = content.match(
3544
3696
  /:\s*SectionSchema\s*=\s*\{[\s\S]*?\btype:\s*["']([^"']+)["']/
@@ -3565,9 +3717,9 @@ async function loadSchemaTypes(themePath, sectionsDir) {
3565
3717
  }
3566
3718
  async function validatePageSectionTypes(pagesDir, validTypes) {
3567
3719
  const issues = [];
3568
- const files = fs__default.default.readdirSync(pagesDir).filter((f) => f.match(/\.(ts|js)$/));
3720
+ const files = fs8__default.default.readdirSync(pagesDir).filter((f) => f.match(/\.(ts|js)$/));
3569
3721
  for (const file of files) {
3570
- const content = fs__default.default.readFileSync(path11__default.default.join(pagesDir, file), "utf-8");
3722
+ const content = fs8__default.default.readFileSync(path13__default.default.join(pagesDir, file), "utf-8");
3571
3723
  const pageName = file.replace(/\.(ts|js)$/, "");
3572
3724
  const sectionsMatch = content.match(/\bsections:\s*\[/);
3573
3725
  if (!sectionsMatch || sectionsMatch.index === void 0) continue;
@@ -3697,9 +3849,70 @@ var BLOCK_TYPES = /* @__PURE__ */ new Set([
3697
3849
  "team-member",
3698
3850
  "hero-content"
3699
3851
  ]);
3852
+ var SERVER_ONLY_APIS = [
3853
+ "next/headers",
3854
+ "next/server",
3855
+ "next/cache",
3856
+ "cookies()",
3857
+ "headers()",
3858
+ "draftMode()"
3859
+ ];
3860
+ async function validateNextjsComponents(themePath) {
3861
+ const issues = [];
3862
+ const { glob: glob6 } = await import('glob');
3863
+ const componentFiles = await glob6("components/**/*.{tsx,ts}", {
3864
+ cwd: themePath,
3865
+ ignore: ["**/node_modules/**"]
3866
+ });
3867
+ for (const relFile of componentFiles) {
3868
+ const absFile = path13__default.default.join(themePath, relFile);
3869
+ const content = fs8__default.default.readFileSync(absFile, "utf-8");
3870
+ const dir = path13__default.default.dirname(absFile);
3871
+ const hasSectionJson = fs8__default.default.existsSync(path13__default.default.join(dir, "section.json"));
3872
+ if (!hasSectionJson) continue;
3873
+ for (const api of SERVER_ONLY_APIS) {
3874
+ if (content.includes(`"${api}"`) || content.includes(`'${api}'`)) {
3875
+ issues.push({
3876
+ type: "error",
3877
+ file: relFile,
3878
+ message: `"${api}" is server-only and cannot be used in a OneX theme bundle. Remove this import or move data fetching to a client-side useEffect/useQuery.`
3879
+ });
3880
+ }
3881
+ if (content.includes(api.replace("()", "") + "(")) {
3882
+ issues.push({
3883
+ type: "error",
3884
+ file: relFile,
3885
+ message: `${api} is server-only and cannot be called in a browser bundle. Use useQuery or fetch() inside useEffect instead.`
3886
+ });
3887
+ }
3888
+ }
3889
+ const isAsyncComponent = /export\s+default\s+async\s+function/.test(content) || /export\s+default\s+async\s+\(/.test(content);
3890
+ if (isAsyncComponent) {
3891
+ const hasUseClient2 = content.includes('"use client"') || content.includes("'use client'");
3892
+ if (!hasUseClient2) {
3893
+ issues.push({
3894
+ type: "error",
3895
+ file: relFile,
3896
+ message: 'Async Server Components cannot be compiled to a browser bundle. Add "use client" at the top and convert data fetching to useQuery or useEffect.'
3897
+ });
3898
+ }
3899
+ }
3900
+ const usesHooks = /\buse[A-Z]\w+\s*\(/.test(content);
3901
+ const hasUseClient = content.includes('"use client"') || content.includes("'use client'");
3902
+ if (usesHooks && !hasUseClient) {
3903
+ issues.push({
3904
+ type: "warning",
3905
+ file: relFile,
3906
+ message: 'Component uses React hooks but is missing "use client" directive. Add "use client" at the top of the file.'
3907
+ });
3908
+ }
3909
+ }
3910
+ return issues;
3911
+ }
3700
3912
 
3701
3913
  // src/commands/build.ts
3702
3914
  init_logger();
3915
+ init_detect_nextjs();
3703
3916
  async function buildCommand(options) {
3704
3917
  logger.header("Build Theme");
3705
3918
  let themePath;
@@ -3707,16 +3920,16 @@ async function buildCommand(options) {
3707
3920
  if (options.theme) {
3708
3921
  themeName = options.theme;
3709
3922
  try {
3710
- const workspaceThemePath = path11__default.default.join(getThemesDir(), themeName);
3711
- if (fs__default.default.existsSync(workspaceThemePath)) {
3923
+ const workspaceThemePath = path13__default.default.join(getThemesDir(), themeName);
3924
+ if (fs8__default.default.existsSync(workspaceThemePath)) {
3712
3925
  themePath = workspaceThemePath;
3713
3926
  } else {
3714
- themePath = path11__default.default.join(process.cwd(), themeName);
3927
+ themePath = path13__default.default.join(process.cwd(), themeName);
3715
3928
  }
3716
3929
  } catch {
3717
- themePath = path11__default.default.join(process.cwd(), themeName);
3930
+ themePath = path13__default.default.join(process.cwd(), themeName);
3718
3931
  }
3719
- if (!fs__default.default.existsSync(themePath)) {
3932
+ if (!fs8__default.default.existsSync(themePath)) {
3720
3933
  logger.error(`Theme "${themeName}" not found.`);
3721
3934
  process.exit(1);
3722
3935
  }
@@ -3724,11 +3937,14 @@ async function buildCommand(options) {
3724
3937
  const isThemeDir2 = [
3725
3938
  "theme.config.ts",
3726
3939
  "bundle-entry.ts",
3727
- "manifest.ts"
3728
- ].some((f) => fs__default.default.existsSync(path11__default.default.join(process.cwd(), f)));
3940
+ "manifest.ts",
3941
+ "next.config.ts",
3942
+ "next.config.js",
3943
+ "next.config.mjs"
3944
+ ].some((f) => fs8__default.default.existsSync(path13__default.default.join(process.cwd(), f)));
3729
3945
  if (isThemeDir2) {
3730
3946
  themePath = process.cwd();
3731
- themeName = path11__default.default.basename(themePath);
3947
+ themeName = path13__default.default.basename(themePath);
3732
3948
  logger.info(`Building current theme: ${themeName}`);
3733
3949
  } else {
3734
3950
  logger.error(
@@ -3737,8 +3953,8 @@ async function buildCommand(options) {
3737
3953
  process.exit(1);
3738
3954
  }
3739
3955
  }
3740
- const packageJsonPath = path11__default.default.join(themePath, "package.json");
3741
- const hasPkgJson = fs__default.default.existsSync(packageJsonPath);
3956
+ const packageJsonPath = path13__default.default.join(themePath, "package.json");
3957
+ const hasPkgJson = fs8__default.default.existsSync(packageJsonPath);
3742
3958
  if (!hasPkgJson) {
3743
3959
  logger.warning(
3744
3960
  "No package.json found in theme. Skipping build (themes in monorepo are built via turbo)."
@@ -3753,30 +3969,42 @@ async function buildCommand(options) {
3753
3969
  }
3754
3970
  logger.newLine();
3755
3971
  logger.section("Build Steps");
3756
- logger.startSpinner("Running type check...");
3757
- const typeCheckSuccess = await runCommand("pnpm", ["type-check"], themePath);
3758
- if (!typeCheckSuccess) {
3759
- logger.stopSpinner(false, "Type check failed");
3760
- logger.error("Fix type errors before building.");
3761
- process.exit(1);
3762
- }
3763
- logger.stopSpinner(true, "Type check passed");
3764
- logger.startSpinner("Running linter...");
3765
- const lintSuccess = await runCommand("pnpm", ["lint"], themePath);
3766
- if (!lintSuccess) {
3767
- logger.stopSpinner(false, "Lint failed");
3768
- logger.error("Fix lint errors before building.");
3769
- process.exit(1);
3972
+ const pkgJson = fs8__default.default.readJsonSync(packageJsonPath);
3973
+ if (pkgJson.scripts?.["type-check"]) {
3974
+ logger.startSpinner("Running type check...");
3975
+ const typeCheckSuccess = await runCommand("pnpm", ["type-check"], themePath);
3976
+ if (!typeCheckSuccess) {
3977
+ logger.stopSpinner(false, "Type check failed");
3978
+ logger.error("Fix type errors before building.");
3979
+ process.exit(1);
3980
+ }
3981
+ logger.stopSpinner(true, "Type check passed");
3982
+ } else {
3983
+ logger.info("Skipping type check (no type-check script in package.json)");
3984
+ }
3985
+ const isNextjsForLint = isNextjsProject(themePath);
3986
+ if (!isNextjsForLint && pkgJson.scripts?.lint) {
3987
+ logger.startSpinner("Running linter...");
3988
+ const lintSuccess = await runCommand("pnpm", ["lint"], themePath);
3989
+ if (!lintSuccess) {
3990
+ logger.stopSpinner(false, "Lint failed");
3991
+ logger.error("Fix lint errors before building.");
3992
+ process.exit(1);
3993
+ }
3994
+ logger.stopSpinner(true, "Lint passed");
3995
+ } else if (isNextjsForLint) {
3996
+ logger.info("Skipping lint (Next.js project compiled via esbuild)");
3997
+ } else {
3998
+ logger.info("Skipping lint (no lint script in package.json)");
3770
3999
  }
3771
- logger.stopSpinner(true, "Lint passed");
3772
- const pkgJson = fs__default.default.readJsonSync(packageJsonPath);
3773
4000
  const buildScript = pkgJson.scripts?.build || "";
3774
4001
  const isRecursive = buildScript.includes("onexthm build") || buildScript.includes("onex build") || buildScript.includes("onex-cli build");
4002
+ const isNextjs = isNextjsProject(themePath);
3775
4003
  logger.startSpinner(
3776
4004
  options.watch ? "Building (watch mode)..." : "Building..."
3777
4005
  );
3778
4006
  let buildSuccess;
3779
- if (isRecursive) {
4007
+ if (isRecursive || isNextjs) {
3780
4008
  const { compileStandaloneTheme: compileStandaloneTheme2 } = await Promise.resolve().then(() => (init_compile_theme(), compile_theme_exports));
3781
4009
  buildSuccess = await compileStandaloneTheme2(themePath, themeName);
3782
4010
  } else {
@@ -3793,10 +4021,10 @@ async function buildCommand(options) {
3793
4021
  logger.success("\u2713 Theme built successfully!");
3794
4022
  logger.newLine();
3795
4023
  logger.info(`Theme: ${themeName}`);
3796
- const distPath = path11__default.default.join(themePath, "dist");
3797
- if (fs__default.default.existsSync(distPath)) {
3798
- logger.log(`Output: ${path11__default.default.relative(process.cwd(), distPath)}`);
3799
- const files = fs__default.default.readdirSync(distPath);
4024
+ const distPath = path13__default.default.join(themePath, "dist");
4025
+ if (fs8__default.default.existsSync(distPath)) {
4026
+ logger.log(`Output: ${path13__default.default.relative(process.cwd(), distPath)}`);
4027
+ const files = fs8__default.default.readdirSync(distPath);
3800
4028
  logger.log(`Files: ${files.length}`);
3801
4029
  }
3802
4030
  }
@@ -3851,8 +4079,8 @@ async function packageCommand(options) {
3851
4079
  let themeName;
3852
4080
  if (options.theme) {
3853
4081
  themeName = options.theme;
3854
- themePath = path11__default.default.join(getThemesDir(), themeName);
3855
- if (!fs__default.default.existsSync(themePath)) {
4082
+ themePath = path13__default.default.join(getThemesDir(), themeName);
4083
+ if (!fs8__default.default.existsSync(themePath)) {
3856
4084
  logger.error(`Theme "${themeName}" not found.`);
3857
4085
  process.exit(1);
3858
4086
  }
@@ -3860,11 +4088,14 @@ async function packageCommand(options) {
3860
4088
  const isThemeDir2 = [
3861
4089
  "theme.config.ts",
3862
4090
  "bundle-entry.ts",
3863
- "manifest.ts"
3864
- ].some((f) => fs__default.default.existsSync(path11__default.default.join(process.cwd(), f)));
4091
+ "manifest.ts",
4092
+ "next.config.ts",
4093
+ "next.config.js",
4094
+ "next.config.mjs"
4095
+ ].some((f) => fs8__default.default.existsSync(path13__default.default.join(process.cwd(), f)));
3865
4096
  if (isThemeDir2) {
3866
4097
  themePath = process.cwd();
3867
- themeName = path11__default.default.basename(themePath);
4098
+ themeName = path13__default.default.basename(themePath);
3868
4099
  logger.info(`Packaging current theme: ${themeName}`);
3869
4100
  } else {
3870
4101
  logger.error(
@@ -3873,22 +4104,19 @@ async function packageCommand(options) {
3873
4104
  process.exit(1);
3874
4105
  }
3875
4106
  }
3876
- const packageJsonPath = path11__default.default.join(themePath, "package.json");
4107
+ const packageJsonPath = path13__default.default.join(themePath, "package.json");
3877
4108
  let version2 = "1.0.0";
3878
- if (fs__default.default.existsSync(packageJsonPath)) {
3879
- const packageJson = await fs__default.default.readJson(packageJsonPath);
4109
+ if (fs8__default.default.existsSync(packageJsonPath)) {
4110
+ const packageJson = await fs8__default.default.readJson(packageJsonPath);
3880
4111
  version2 = packageJson.version || "1.0.0";
3881
4112
  }
3882
4113
  logger.newLine();
3883
4114
  logger.info(`Theme: ${themeName}`);
3884
4115
  logger.info(`Version: ${version2}`);
3885
4116
  logger.newLine();
3886
- const compiledThemePath = path11__default.default.join(
3887
- process.cwd(),
3888
- "themes",
3889
- themeName,
3890
- "dist"
3891
- );
4117
+ const standaloneDistPath = path13__default.default.join(themePath, "dist");
4118
+ const monorepoDistPath = path13__default.default.join(process.cwd(), "themes", themeName, "dist");
4119
+ const compiledThemePath = fs8__default.default.existsSync(standaloneDistPath) ? standaloneDistPath : monorepoDistPath;
3892
4120
  if (!options.skipBuild) {
3893
4121
  logger.section("Step 1: Compile Theme");
3894
4122
  logger.startSpinner("Compiling theme with esbuild...");
@@ -3909,7 +4137,7 @@ async function packageCommand(options) {
3909
4137
  } else {
3910
4138
  logger.info("Skipping build (--skip-build flag)");
3911
4139
  }
3912
- if (!fs__default.default.existsSync(compiledThemePath)) {
4140
+ if (!fs8__default.default.existsSync(compiledThemePath)) {
3913
4141
  logger.error(`Compiled theme not found at: ${compiledThemePath}`);
3914
4142
  logger.info("Run without --skip-build to compile first.");
3915
4143
  process.exit(1);
@@ -3917,25 +4145,25 @@ async function packageCommand(options) {
3917
4145
  logger.newLine();
3918
4146
  logger.section("Step 2: Create Package");
3919
4147
  const packageName = options.name || `${themeName}-${version2}`;
3920
- const outputDir = options.output || path11__default.default.join(process.cwd(), "dist");
3921
- const outputPath = path11__default.default.join(outputDir, `${packageName}.zip`);
3922
- await fs__default.default.ensureDir(outputDir);
4148
+ const outputDir = options.output || path13__default.default.join(process.cwd(), "dist");
4149
+ const outputPath = path13__default.default.join(outputDir, `${packageName}.zip`);
4150
+ await fs8__default.default.ensureDir(outputDir);
3923
4151
  logger.startSpinner("Creating zip archive...");
3924
4152
  try {
3925
4153
  await createZipArchive(compiledThemePath, outputPath);
3926
4154
  logger.stopSpinner(true, "Package created");
3927
- const stats = await fs__default.default.stat(outputPath);
4155
+ const stats = await fs8__default.default.stat(outputPath);
3928
4156
  const sizeMB = (stats.size / 1024 / 1024).toFixed(2);
3929
4157
  logger.newLine();
3930
4158
  logger.success("\u2713 Theme packaged successfully!");
3931
4159
  logger.newLine();
3932
4160
  logger.info(`Package: ${packageName}.zip`);
3933
4161
  logger.log(`Size: ${sizeMB} MB`);
3934
- logger.log(`Location: ${path11__default.default.relative(process.cwd(), outputPath)}`);
4162
+ logger.log(`Location: ${path13__default.default.relative(process.cwd(), outputPath)}`);
3935
4163
  logger.newLine();
3936
4164
  logger.section("Next steps:");
3937
4165
  logger.log(
3938
- ` onexthm deploy --package ${path11__default.default.relative(process.cwd(), outputPath)}`
4166
+ ` onexthm deploy --package ${path13__default.default.relative(process.cwd(), outputPath)}`
3939
4167
  );
3940
4168
  } catch (error) {
3941
4169
  logger.stopSpinner(false, "Failed to create package");
@@ -3969,7 +4197,7 @@ function runCommand2(command, args) {
3969
4197
  }
3970
4198
  async function createZipArchive(compiledThemePath, outputPath) {
3971
4199
  return new Promise((resolve, reject) => {
3972
- const output = fs__default.default.createWriteStream(outputPath);
4200
+ const output = fs8__default.default.createWriteStream(outputPath);
3973
4201
  const archive = archiver__default.default("zip", {
3974
4202
  zlib: { level: 9 }
3975
4203
  // Maximum compression
@@ -3993,14 +4221,14 @@ async function deployCommand(options) {
3993
4221
  ensureOneXProject();
3994
4222
  let packagePath;
3995
4223
  if (options.package) {
3996
- packagePath = path11__default.default.resolve(options.package);
4224
+ packagePath = path13__default.default.resolve(options.package);
3997
4225
  } else if (options.theme) {
3998
- const distDir = path11__default.default.join(process.cwd(), "dist");
3999
- if (!fs__default.default.existsSync(distDir)) {
4226
+ const distDir = path13__default.default.join(process.cwd(), "dist");
4227
+ if (!fs8__default.default.existsSync(distDir)) {
4000
4228
  logger.error("No dist/ directory found. Run 'onexthm package' first.");
4001
4229
  process.exit(1);
4002
4230
  }
4003
- const files = fs__default.default.readdirSync(distDir);
4231
+ const files = fs8__default.default.readdirSync(distDir);
4004
4232
  const packageFiles = files.filter(
4005
4233
  (f) => f.startsWith(options.theme) && f.endsWith(".zip")
4006
4234
  );
@@ -4010,7 +4238,7 @@ async function deployCommand(options) {
4010
4238
  process.exit(1);
4011
4239
  }
4012
4240
  packageFiles.sort().reverse();
4013
- packagePath = path11__default.default.join(distDir, packageFiles[0]);
4241
+ packagePath = path13__default.default.join(distDir, packageFiles[0]);
4014
4242
  } else {
4015
4243
  logger.error("Either --package or --theme must be specified.");
4016
4244
  logger.info("Examples:");
@@ -4018,17 +4246,17 @@ async function deployCommand(options) {
4018
4246
  logger.log(" onexthm deploy --theme tinan");
4019
4247
  process.exit(1);
4020
4248
  }
4021
- if (!fs__default.default.existsSync(packagePath)) {
4249
+ if (!fs8__default.default.existsSync(packagePath)) {
4022
4250
  logger.error(`Package not found: ${packagePath}`);
4023
4251
  process.exit(1);
4024
4252
  }
4025
- const stats = await fs__default.default.stat(packagePath);
4253
+ const stats = await fs8__default.default.stat(packagePath);
4026
4254
  const sizeMB = (stats.size / 1024 / 1024).toFixed(2);
4027
- const fileName = path11__default.default.basename(packagePath);
4255
+ const fileName = path13__default.default.basename(packagePath);
4028
4256
  logger.newLine();
4029
4257
  logger.info(`Package: ${fileName}`);
4030
4258
  logger.log(`Size: ${sizeMB} MB`);
4031
- logger.log(`Path: ${path11__default.default.relative(process.cwd(), packagePath)}`);
4259
+ logger.log(`Path: ${path13__default.default.relative(process.cwd(), packagePath)}`);
4032
4260
  logger.newLine();
4033
4261
  const apiUrl = options.apiUrl || process.env.ONEX_API_URL || "http://localhost:3001";
4034
4262
  const uploadEndpoint = `${apiUrl}/website-api/themes/upload`;
@@ -4038,7 +4266,7 @@ async function deployCommand(options) {
4038
4266
  logger.startSpinner("Uploading theme package...");
4039
4267
  try {
4040
4268
  const formData = new FormData__default.default();
4041
- formData.append("theme", fs__default.default.createReadStream(packagePath), {
4269
+ formData.append("theme", fs8__default.default.createReadStream(packagePath), {
4042
4270
  filename: fileName,
4043
4271
  contentType: "application/zip"
4044
4272
  });
@@ -4185,24 +4413,24 @@ async function downloadBundleZip(apiUrl, themeId, version2) {
4185
4413
  async function createCompatibilityFiles(outputDir, manifest) {
4186
4414
  const entryFile = manifest.output?.entry || "bundle-entry.js";
4187
4415
  if (entryFile !== "bundle-entry.js" && entryFile.startsWith("bundle-entry-")) {
4188
- const hashedPath = path11__default.default.join(outputDir, entryFile);
4189
- const stablePath = path11__default.default.join(outputDir, "bundle-entry.js");
4190
- if (await fs__default.default.pathExists(hashedPath)) {
4191
- await fs__default.default.copy(hashedPath, stablePath);
4416
+ const hashedPath = path13__default.default.join(outputDir, entryFile);
4417
+ const stablePath = path13__default.default.join(outputDir, "bundle-entry.js");
4418
+ if (await fs8__default.default.pathExists(hashedPath)) {
4419
+ await fs8__default.default.copy(hashedPath, stablePath);
4192
4420
  const mapPath = hashedPath + ".map";
4193
- if (await fs__default.default.pathExists(mapPath)) {
4194
- await fs__default.default.copy(mapPath, stablePath + ".map");
4421
+ if (await fs8__default.default.pathExists(mapPath)) {
4422
+ await fs8__default.default.copy(mapPath, stablePath + ".map");
4195
4423
  }
4196
4424
  }
4197
4425
  }
4198
- const sectionsRegistryPath = path11__default.default.join(outputDir, "sections-registry.js");
4426
+ const sectionsRegistryPath = path13__default.default.join(outputDir, "sections-registry.js");
4199
4427
  const content = `// Re-export all sections from bundle-entry
4200
4428
  // This file exists to maintain compatibility with the import path
4201
4429
  export * from './bundle-entry.js';
4202
4430
  `;
4203
- await fs__default.default.writeFile(sectionsRegistryPath, content, "utf-8");
4204
- const pkgJsonPath = path11__default.default.join(outputDir, "package.json");
4205
- await fs__default.default.writeFile(pkgJsonPath, '{\n "type": "module"\n}\n', "utf-8");
4431
+ await fs8__default.default.writeFile(sectionsRegistryPath, content, "utf-8");
4432
+ const pkgJsonPath = path13__default.default.join(outputDir, "package.json");
4433
+ await fs8__default.default.writeFile(pkgJsonPath, '{\n "type": "module"\n}\n', "utf-8");
4206
4434
  }
4207
4435
  function showDownloadFailureHelp(themeId, apiUrl) {
4208
4436
  console.log();
@@ -4242,7 +4470,7 @@ function showDownloadFailureHelp(themeId, apiUrl) {
4242
4470
  }
4243
4471
  async function downloadCommand(options) {
4244
4472
  logger.header("Download Theme");
4245
- const env = options.env ?? "dev";
4473
+ const env = options.env;
4246
4474
  const apiUrl = getApiUrl(env);
4247
4475
  logger.info(`Environment: ${env} (${apiUrl})`);
4248
4476
  const spinner = ora__default.default("Initializing download...").start();
@@ -4294,14 +4522,14 @@ async function downloadCommand(options) {
4294
4522
  const sizeMB = (zipBuffer.length / 1024 / 1024).toFixed(2);
4295
4523
  spinner.succeed(`Downloaded bundle.zip (${sizeMB} MB)`);
4296
4524
  spinner.start("Extracting bundle...");
4297
- await fs__default.default.remove(outputDir);
4298
- await fs__default.default.ensureDir(outputDir);
4525
+ await fs8__default.default.remove(outputDir);
4526
+ await fs8__default.default.ensureDir(outputDir);
4299
4527
  const zip = new AdmZip__default.default(zipBuffer);
4300
4528
  zip.extractAllTo(outputDir, true);
4301
4529
  const entries = zip.getEntries().filter((e) => !e.isDirectory);
4302
4530
  spinner.succeed(`Extracted ${entries.length} files to ${outputDir}`);
4303
- const manifestPath = path11__default.default.join(outputDir, "manifest.json");
4304
- const manifest = await fs__default.default.readJson(manifestPath);
4531
+ const manifestPath = path13__default.default.join(outputDir, "manifest.json");
4532
+ const manifest = await fs8__default.default.readJson(manifestPath);
4305
4533
  await createCompatibilityFiles(outputDir, manifest);
4306
4534
  console.log();
4307
4535
  logger.success(chalk4__default.default.green.bold("Theme downloaded successfully!"));
@@ -4421,9 +4649,9 @@ async function renameTheme(themeDir, oldName, newName) {
4421
4649
  const oldPrefix = `${oldName}-`;
4422
4650
  const newPrefix = `${newName}-`;
4423
4651
  const newDisplayName = newName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
4424
- const pkgPath = path11__default.default.join(themeDir, "package.json");
4425
- if (await fs__default.default.pathExists(pkgPath)) {
4426
- const pkg = await fs__default.default.readJson(pkgPath);
4652
+ const pkgPath = path13__default.default.join(themeDir, "package.json");
4653
+ if (await fs8__default.default.pathExists(pkgPath)) {
4654
+ const pkg = await fs8__default.default.readJson(pkgPath);
4427
4655
  pkg.name = `@onex-themes/${newName}`;
4428
4656
  if (pkg.description) {
4429
4657
  pkg.description = pkg.description.replace(
@@ -4435,33 +4663,33 @@ async function renameTheme(themeDir, oldName, newName) {
4435
4663
  if (pkg.devDependencies?.["@onexapis/cli"]) {
4436
4664
  delete pkg.devDependencies["@onexapis/cli"];
4437
4665
  }
4438
- await fs__default.default.writeJson(pkgPath, pkg, { spaces: 2 });
4666
+ await fs8__default.default.writeJson(pkgPath, pkg, { spaces: 2 });
4439
4667
  }
4440
- const configPath = path11__default.default.join(themeDir, "theme.config.ts");
4441
- if (await fs__default.default.pathExists(configPath)) {
4442
- let content = await fs__default.default.readFile(configPath, "utf-8");
4668
+ const configPath = path13__default.default.join(themeDir, "theme.config.ts");
4669
+ if (await fs8__default.default.pathExists(configPath)) {
4670
+ let content = await fs8__default.default.readFile(configPath, "utf-8");
4443
4671
  content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
4444
4672
  content = content.replace(
4445
4673
  /name:\s*"[^"]*Theme"/,
4446
4674
  `name: "${newDisplayName} Theme"`
4447
4675
  );
4448
- await fs__default.default.writeFile(configPath, content);
4676
+ await fs8__default.default.writeFile(configPath, content);
4449
4677
  }
4450
- const layoutPath = path11__default.default.join(themeDir, "theme.layout.ts");
4451
- if (await fs__default.default.pathExists(layoutPath)) {
4452
- let content = await fs__default.default.readFile(layoutPath, "utf-8");
4678
+ const layoutPath = path13__default.default.join(themeDir, "theme.layout.ts");
4679
+ if (await fs8__default.default.pathExists(layoutPath)) {
4680
+ let content = await fs8__default.default.readFile(layoutPath, "utf-8");
4453
4681
  content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
4454
4682
  content = content.replace(
4455
4683
  /name:\s*"[^"]*Theme"/,
4456
4684
  `name: "${newDisplayName} Theme"`
4457
4685
  );
4458
- await fs__default.default.writeFile(layoutPath, content);
4686
+ await fs8__default.default.writeFile(layoutPath, content);
4459
4687
  }
4460
4688
  const oldDisplayName = oldName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
4461
4689
  const tsFiles = await glob.glob("**/*.ts", { cwd: themeDir, nodir: true });
4462
4690
  for (const file of tsFiles) {
4463
- const filePath = path11__default.default.join(themeDir, file);
4464
- let content = await fs__default.default.readFile(filePath, "utf-8");
4691
+ const filePath = path13__default.default.join(themeDir, file);
4692
+ let content = await fs8__default.default.readFile(filePath, "utf-8");
4465
4693
  const original = content;
4466
4694
  content = content.replace(
4467
4695
  new RegExp(`"${oldPrefix}`, "g"),
@@ -4476,13 +4704,13 @@ async function renameTheme(themeDir, oldName, newName) {
4476
4704
  `${newDisplayName} Theme`
4477
4705
  );
4478
4706
  if (content !== original) {
4479
- await fs__default.default.writeFile(filePath, content);
4707
+ await fs8__default.default.writeFile(filePath, content);
4480
4708
  }
4481
4709
  }
4482
4710
  }
4483
4711
  async function cloneCommand(themeName, options) {
4484
4712
  logger.header("Clone Theme Source");
4485
- const env = options.env ?? "dev";
4713
+ const env = options.env;
4486
4714
  const apiUrl = getApiUrl(env);
4487
4715
  logger.info(`Environment: ${env} (${apiUrl})`);
4488
4716
  if (options.bucket) {
@@ -4503,8 +4731,8 @@ async function cloneCommand(themeName, options) {
4503
4731
  }
4504
4732
  const spinner = ora__default.default("Initializing clone...").start();
4505
4733
  try {
4506
- const outputDir = options.output || path11__default.default.resolve(process.cwd(), newName);
4507
- if (await fs__default.default.pathExists(outputDir)) {
4734
+ const outputDir = options.output || path13__default.default.resolve(process.cwd(), newName);
4735
+ if (await fs8__default.default.pathExists(outputDir)) {
4508
4736
  spinner.fail(chalk4__default.default.red(`Directory already exists: ${outputDir}`));
4509
4737
  logger.info(
4510
4738
  chalk4__default.default.gray(
@@ -4537,7 +4765,7 @@ async function cloneCommand(themeName, options) {
4537
4765
  const sizeMB = (zipBuffer.length / 1024 / 1024).toFixed(2);
4538
4766
  spinner.succeed(`Downloaded source.zip (${sizeMB} MB)`);
4539
4767
  spinner.start(`Extracting to ${outputDir}...`);
4540
- await fs__default.default.ensureDir(outputDir);
4768
+ await fs8__default.default.ensureDir(outputDir);
4541
4769
  const zip = new AdmZip__default.default(zipBuffer);
4542
4770
  zip.extractAllTo(outputDir, true);
4543
4771
  const entries = zip.getEntries().filter((e) => !e.isDirectory);
@@ -4549,9 +4777,9 @@ async function cloneCommand(themeName, options) {
4549
4777
  spinner.succeed(
4550
4778
  `Renamed theme: ${chalk4__default.default.gray(themeName)} \u2192 ${chalk4__default.default.cyan(newName)}`
4551
4779
  );
4552
- const envExamplePath = path11__default.default.join(outputDir, ".env.example");
4553
- if (!await fs__default.default.pathExists(envExamplePath)) {
4554
- await fs__default.default.writeFile(
4780
+ const envExamplePath = path13__default.default.join(outputDir, ".env.example");
4781
+ if (!await fs8__default.default.pathExists(envExamplePath)) {
4782
+ await fs8__default.default.writeFile(
4555
4783
  envExamplePath,
4556
4784
  [
4557
4785
  "# API Configuration (enables real data in preview)",
@@ -4562,8 +4790,8 @@ async function cloneCommand(themeName, options) {
4562
4790
  ].join("\n")
4563
4791
  );
4564
4792
  }
4565
- const mcpJsonPath = path11__default.default.join(outputDir, ".mcp.json");
4566
- if (await fs__default.default.pathExists(mcpJsonPath)) {
4793
+ const mcpJsonPath = path13__default.default.join(outputDir, ".mcp.json");
4794
+ if (await fs8__default.default.pathExists(mcpJsonPath)) {
4567
4795
  const { default: inquirerMod } = await import('inquirer');
4568
4796
  const { figmaApiKey } = await inquirerMod.prompt([
4569
4797
  {
@@ -4572,7 +4800,7 @@ async function cloneCommand(themeName, options) {
4572
4800
  message: "Figma API Key (optional, for Figma-to-code MCP \u2014 press Enter to skip):"
4573
4801
  }
4574
4802
  ]);
4575
- let mcpContent = await fs__default.default.readFile(mcpJsonPath, "utf-8");
4803
+ let mcpContent = await fs8__default.default.readFile(mcpJsonPath, "utf-8");
4576
4804
  if (figmaApiKey) {
4577
4805
  mcpContent = mcpContent.replace("__FIGMA_API_KEY__", figmaApiKey);
4578
4806
  } else {
@@ -4583,11 +4811,11 @@ async function cloneCommand(themeName, options) {
4583
4811
  } catch {
4584
4812
  }
4585
4813
  }
4586
- await fs__default.default.writeFile(mcpJsonPath, mcpContent, "utf-8");
4814
+ await fs8__default.default.writeFile(mcpJsonPath, mcpContent, "utf-8");
4587
4815
  }
4588
4816
  if (options.install !== false) {
4589
- const hasPkgJson = await fs__default.default.pathExists(
4590
- path11__default.default.join(outputDir, "package.json")
4817
+ const hasPkgJson = await fs8__default.default.pathExists(
4818
+ path13__default.default.join(outputDir, "package.json")
4591
4819
  );
4592
4820
  if (hasPkgJson) {
4593
4821
  spinner.start("Installing dependencies...");
@@ -4615,7 +4843,7 @@ async function cloneCommand(themeName, options) {
4615
4843
  console.log(chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(entries.length));
4616
4844
  console.log();
4617
4845
  console.log(chalk4__default.default.cyan("Next steps:"));
4618
- console.log(chalk4__default.default.gray(` cd ${path11__default.default.relative(process.cwd(), outputDir)}`));
4846
+ console.log(chalk4__default.default.gray(` cd ${path13__default.default.relative(process.cwd(), outputDir)}`));
4619
4847
  console.log(
4620
4848
  chalk4__default.default.gray(" cp .env.example .env # then add your Company ID")
4621
4849
  );
@@ -4642,16 +4870,16 @@ async function devCommand(options) {
4642
4870
  if (options.theme) {
4643
4871
  themeName = options.theme;
4644
4872
  try {
4645
- const workspaceThemePath = path11__default.default.join(getThemesDir(), themeName);
4646
- if (fs__default.default.existsSync(workspaceThemePath)) {
4873
+ const workspaceThemePath = path13__default.default.join(getThemesDir(), themeName);
4874
+ if (fs8__default.default.existsSync(workspaceThemePath)) {
4647
4875
  themePath = workspaceThemePath;
4648
4876
  } else {
4649
- themePath = path11__default.default.join(process.cwd(), themeName);
4877
+ themePath = path13__default.default.join(process.cwd(), themeName);
4650
4878
  }
4651
4879
  } catch {
4652
- themePath = path11__default.default.join(process.cwd(), themeName);
4880
+ themePath = path13__default.default.join(process.cwd(), themeName);
4653
4881
  }
4654
- if (!fs__default.default.existsSync(themePath)) {
4882
+ if (!fs8__default.default.existsSync(themePath)) {
4655
4883
  logger.error(`Theme "${themeName}" not found.`);
4656
4884
  process.exit(1);
4657
4885
  }
@@ -4659,11 +4887,14 @@ async function devCommand(options) {
4659
4887
  const isThemeDir2 = [
4660
4888
  "theme.config.ts",
4661
4889
  "bundle-entry.ts",
4662
- "manifest.ts"
4663
- ].some((f) => fs__default.default.existsSync(path11__default.default.join(process.cwd(), f)));
4890
+ "manifest.ts",
4891
+ "next.config.ts",
4892
+ "next.config.js",
4893
+ "next.config.mjs"
4894
+ ].some((f) => fs8__default.default.existsSync(path13__default.default.join(process.cwd(), f)));
4664
4895
  if (isThemeDir2) {
4665
4896
  themePath = process.cwd();
4666
- themeName = path11__default.default.basename(themePath);
4897
+ themeName = path13__default.default.basename(themePath);
4667
4898
  } else {
4668
4899
  logger.error(
4669
4900
  "Not in a theme directory and no --theme specified. Run from theme root or use --theme flag."
@@ -4732,9 +4963,9 @@ async function devCommand(options) {
4732
4963
  watcher.close();
4733
4964
  await context2.dispose();
4734
4965
  server.close();
4735
- const shimPath = path11__default.default.join(outputDir, ".process-shim.js");
4966
+ const shimPath = path13__default.default.join(outputDir, ".process-shim.js");
4736
4967
  try {
4737
- await fs9__default.default.unlink(shimPath);
4968
+ await fs11__default.default.unlink(shimPath);
4738
4969
  } catch {
4739
4970
  }
4740
4971
  process.exit(0);
@@ -4743,8 +4974,8 @@ async function devCommand(options) {
4743
4974
 
4744
4975
  // src/commands/config.ts
4745
4976
  init_logger();
4746
- var CONFIG_DIR = path11__default.default.join(os__default.default.homedir(), ".onexthm");
4747
- var CONFIG_FILE = path11__default.default.join(CONFIG_DIR, ".env");
4977
+ var CONFIG_DIR = path13__default.default.join(os__default.default.homedir(), ".onexthm");
4978
+ var CONFIG_FILE = path13__default.default.join(CONFIG_DIR, ".env");
4748
4979
  var CONFIG_ENTRIES = [
4749
4980
  {
4750
4981
  key: "AWS_ACCESS_KEY_ID",
@@ -4830,7 +5061,7 @@ async function configCommand() {
4830
5061
  logger.header("OneX CLI Configuration");
4831
5062
  let existing = {};
4832
5063
  try {
4833
- const content = await fs__default.default.readFile(CONFIG_FILE, "utf-8");
5064
+ const content = await fs8__default.default.readFile(CONFIG_FILE, "utf-8");
4834
5065
  existing = parseEnvFile(content);
4835
5066
  logger.info(`Existing config found at: ${CONFIG_FILE}`);
4836
5067
  logger.newLine();
@@ -4866,8 +5097,8 @@ async function configCommand() {
4866
5097
  for (const key of Object.keys(merged)) {
4867
5098
  if (!merged[key]) delete merged[key];
4868
5099
  }
4869
- await fs__default.default.ensureDir(CONFIG_DIR);
4870
- await fs__default.default.writeFile(CONFIG_FILE, serializeEnv(merged));
5100
+ await fs8__default.default.ensureDir(CONFIG_DIR);
5101
+ await fs8__default.default.writeFile(CONFIG_FILE, serializeEnv(merged));
4871
5102
  logger.newLine();
4872
5103
  logger.success(`Config saved to: ${CONFIG_FILE}`);
4873
5104
  logger.newLine();
@@ -4886,8 +5117,8 @@ async function configCommand() {
4886
5117
 
4887
5118
  // src/commands/login.ts
4888
5119
  init_logger();
4889
- async function loginCommand(options = {}) {
4890
- const env = options.env ?? "dev";
5120
+ async function loginCommand(options) {
5121
+ const env = options.env;
4891
5122
  const apiUrl = getApiUrl(env);
4892
5123
  logger.header("OneX Theme Developer Login");
4893
5124
  logger.info(`Environment: ${env} (${apiUrl})`);
@@ -4976,8 +5207,8 @@ async function loginCommand(options = {}) {
4976
5207
 
4977
5208
  // src/commands/logout.ts
4978
5209
  init_logger();
4979
- async function logoutCommand(options = {}) {
4980
- const env = options.env ?? "dev";
5210
+ async function logoutCommand(options) {
5211
+ const env = options.env;
4981
5212
  const tokens = loadAuthTokens(env);
4982
5213
  if (!tokens) {
4983
5214
  logger.info(`Not logged in to ${env} environment.`);
@@ -4989,8 +5220,8 @@ async function logoutCommand(options = {}) {
4989
5220
 
4990
5221
  // src/commands/whoami.ts
4991
5222
  init_logger();
4992
- async function whoamiCommand(options = {}) {
4993
- const env = options.env ?? "dev";
5223
+ async function whoamiCommand(options) {
5224
+ const env = options.env;
4994
5225
  const tokens = loadAuthTokens(env);
4995
5226
  if (!tokens) {
4996
5227
  logger.error(
@@ -5243,11 +5474,11 @@ function diffFieldList(prior, current, pathPrefix, out) {
5243
5474
  }
5244
5475
  }
5245
5476
  }
5246
- function diffFieldPair(p, c, path23, out) {
5477
+ function diffFieldPair(p, c, path25, out) {
5247
5478
  if (p.type !== c.type) {
5248
5479
  out.push({
5249
5480
  kind: "breaking",
5250
- path: path23,
5481
+ path: path25,
5251
5482
  detail: `Type changed (${p.type} \u2192 ${c.type}). Saved values may misrender.`
5252
5483
  });
5253
5484
  return;
@@ -5255,7 +5486,7 @@ function diffFieldPair(p, c, path23, out) {
5255
5486
  if (p.required !== true && c.required === true) {
5256
5487
  out.push({
5257
5488
  kind: "breaking",
5258
- path: path23,
5489
+ path: path25,
5259
5490
  detail: "Field became required. Existing empty instances now invalid."
5260
5491
  });
5261
5492
  }
@@ -5263,7 +5494,7 @@ function diffFieldPair(p, c, path23, out) {
5263
5494
  if ((c.maxLength ?? Infinity) < (p.maxLength ?? Infinity)) {
5264
5495
  out.push({
5265
5496
  kind: "breaking",
5266
- path: path23,
5497
+ path: path25,
5267
5498
  detail: `maxLength tightened (${p.maxLength ?? "\u221E"} \u2192 ${c.maxLength}).`
5268
5499
  });
5269
5500
  }
@@ -5272,7 +5503,7 @@ function diffFieldPair(p, c, path23, out) {
5272
5503
  if ((c.min ?? -Infinity) > (p.min ?? -Infinity)) {
5273
5504
  out.push({
5274
5505
  kind: "breaking",
5275
- path: path23,
5506
+ path: path25,
5276
5507
  detail: `min raised (${p.min ?? "-\u221E"} \u2192 ${c.min}).`
5277
5508
  });
5278
5509
  }
@@ -5281,7 +5512,7 @@ function diffFieldPair(p, c, path23, out) {
5281
5512
  if ((c.max ?? Infinity) < (p.max ?? Infinity)) {
5282
5513
  out.push({
5283
5514
  kind: "breaking",
5284
- path: path23,
5515
+ path: path25,
5285
5516
  detail: `max lowered (${p.max ?? "\u221E"} \u2192 ${c.max}).`
5286
5517
  });
5287
5518
  }
@@ -5294,14 +5525,14 @@ function diffFieldPair(p, c, path23, out) {
5294
5525
  if (removed.length > 0) {
5295
5526
  out.push({
5296
5527
  kind: "breaking",
5297
- path: path23,
5528
+ path: path25,
5298
5529
  detail: `Option(s) removed: ${removed.join(", ")}. Existing saved values may be orphaned.`
5299
5530
  });
5300
5531
  }
5301
5532
  if (added.length > 0) {
5302
5533
  out.push({
5303
5534
  kind: "additive",
5304
- path: path23,
5535
+ path: path25,
5305
5536
  detail: `Option(s) added: ${added.join(", ")}.`
5306
5537
  });
5307
5538
  }
@@ -5309,7 +5540,7 @@ function diffFieldPair(p, c, path23, out) {
5309
5540
  if (!deepEqual(p.default, c.default)) {
5310
5541
  out.push({
5311
5542
  kind: "defaults-only",
5312
- path: path23,
5543
+ path: path25,
5313
5544
  detail: `Default changed: ${JSON.stringify(p.default)} \u2192 ${JSON.stringify(c.default)}.`
5314
5545
  });
5315
5546
  }
@@ -5367,7 +5598,7 @@ function deepEqual(a, b) {
5367
5598
 
5368
5599
  // src/commands/publish.ts
5369
5600
  async function publishCommand(options) {
5370
- const env = options.env ?? "dev";
5601
+ const env = options.env;
5371
5602
  logger.header("OneX Theme Publish");
5372
5603
  logger.info(`Environment: ${env} (${getApiUrl(env)})`);
5373
5604
  logger.newLine();
@@ -5381,13 +5612,13 @@ async function publishCommand(options) {
5381
5612
  logger.info(`Logged in as: ${tokens.user.email}`);
5382
5613
  let themePath;
5383
5614
  if (options.theme) {
5384
- themePath = path11__default.default.resolve(options.theme);
5615
+ themePath = path13__default.default.resolve(options.theme);
5385
5616
  } else {
5386
5617
  const isThemeDir2 = [
5387
5618
  "theme.config.ts",
5388
5619
  "bundle-entry.ts",
5389
5620
  "manifest.ts"
5390
- ].some((f) => fs__default.default.existsSync(path11__default.default.join(process.cwd(), f)));
5621
+ ].some((f) => fs8__default.default.existsSync(path13__default.default.join(process.cwd(), f)));
5391
5622
  if (isThemeDir2) {
5392
5623
  themePath = process.cwd();
5393
5624
  } else {
@@ -5397,13 +5628,13 @@ async function publishCommand(options) {
5397
5628
  process.exit(1);
5398
5629
  }
5399
5630
  }
5400
- const pkgPath = path11__default.default.join(themePath, "package.json");
5401
- if (!fs__default.default.existsSync(pkgPath)) {
5631
+ const pkgPath = path13__default.default.join(themePath, "package.json");
5632
+ if (!fs8__default.default.existsSync(pkgPath)) {
5402
5633
  logger.error("No package.json found in theme directory");
5403
5634
  process.exit(1);
5404
5635
  }
5405
- const pkg = fs__default.default.readJsonSync(pkgPath);
5406
- const themeId = pkg.name?.replace("@onex-themes/", "") || path11__default.default.basename(themePath);
5636
+ const pkg = fs8__default.default.readJsonSync(pkgPath);
5637
+ const themeId = pkg.name?.replace("@onex-themes/", "") || path13__default.default.basename(themePath);
5407
5638
  if (options.bump) {
5408
5639
  const currentVersion = pkg.version || "1.0.0";
5409
5640
  const newVersion = semver__default.default.inc(currentVersion, options.bump);
@@ -5412,7 +5643,7 @@ async function publishCommand(options) {
5412
5643
  process.exit(1);
5413
5644
  }
5414
5645
  pkg.version = newVersion;
5415
- fs__default.default.writeJsonSync(pkgPath, pkg, { spaces: 2 });
5646
+ fs8__default.default.writeJsonSync(pkgPath, pkg, { spaces: 2 });
5416
5647
  logger.info(`Bumped version: ${currentVersion} -> ${newVersion}`);
5417
5648
  }
5418
5649
  const version2 = pkg.version || "1.0.0";
@@ -5519,7 +5750,7 @@ Or use the --bump flag:
5519
5750
  logger.error(error instanceof Error ? error.message : "Build error");
5520
5751
  process.exit(1);
5521
5752
  }
5522
- const distDir = path11__default.default.join(themePath, "dist");
5753
+ const distDir = path13__default.default.join(themePath, "dist");
5523
5754
  const classification = await runSchemaDiffGate(
5524
5755
  themeId,
5525
5756
  distDir,
@@ -5568,8 +5799,8 @@ Or use the --bump flag:
5568
5799
  for (const [originalPath, url] of Object.entries(videoUrls)) {
5569
5800
  assetMap[originalPath] = url;
5570
5801
  }
5571
- const assetMapPath = path11__default.default.join(distDir, "asset-map.json");
5572
- await fs__default.default.writeFile(assetMapPath, JSON.stringify(assetMap, null, 2));
5802
+ const assetMapPath = path13__default.default.join(distDir, "asset-map.json");
5803
+ await fs8__default.default.writeFile(assetMapPath, JSON.stringify(assetMap, null, 2));
5573
5804
  } catch (error) {
5574
5805
  logger.error(
5575
5806
  `Failed to write asset-map.json: ${error instanceof Error ? error.message : "unknown"}`
@@ -5644,7 +5875,7 @@ Or use the --bump flag:
5644
5875
  continue;
5645
5876
  }
5646
5877
  try {
5647
- const buf = await fs__default.default.promises.readFile(entry.absPath);
5878
+ const buf = await fs8__default.default.promises.readFile(entry.absPath);
5648
5879
  const res = await fetch(item.upload_url, {
5649
5880
  method: "PUT",
5650
5881
  headers: {
@@ -5686,12 +5917,12 @@ Or use the --bump flag:
5686
5917
  }
5687
5918
  logger.startSpinner("Uploading bundle...");
5688
5919
  try {
5689
- if (!fs__default.default.existsSync(distDir)) {
5920
+ if (!fs8__default.default.existsSync(distDir)) {
5690
5921
  logger.stopSpinner(false, "No dist/ directory");
5691
5922
  logger.error("Build the theme first: onexthm build");
5692
5923
  process.exit(1);
5693
5924
  }
5694
- const bundleZipPath = path11__default.default.join(themePath, "dist", "bundle.zip");
5925
+ const bundleZipPath = path13__default.default.join(themePath, "dist", "bundle.zip");
5695
5926
  await createZip(distDir, bundleZipPath, [
5696
5927
  "bundle.zip",
5697
5928
  "source.zip",
@@ -5700,7 +5931,7 @@ Or use the --bump flag:
5700
5931
  "theme-assets",
5701
5932
  "theme-assets/**"
5702
5933
  ]);
5703
- const bundleBuffer = fs__default.default.readFileSync(bundleZipPath);
5934
+ const bundleBuffer = fs8__default.default.readFileSync(bundleZipPath);
5704
5935
  const bundleRes = await fetch(bundleUploadUrl, {
5705
5936
  method: "PUT",
5706
5937
  headers: { "Content-Type": "application/zip" },
@@ -5718,7 +5949,7 @@ Or use the --bump flag:
5718
5949
  }
5719
5950
  logger.startSpinner("Uploading source...");
5720
5951
  try {
5721
- const sourceZipPath = path11__default.default.join(themePath, "dist", "source.zip");
5952
+ const sourceZipPath = path13__default.default.join(themePath, "dist", "source.zip");
5722
5953
  await createZip(themePath, sourceZipPath, [
5723
5954
  "node_modules",
5724
5955
  "dist",
@@ -5726,7 +5957,7 @@ Or use the --bump flag:
5726
5957
  ".env",
5727
5958
  ".env.local"
5728
5959
  ]);
5729
- const sourceBuffer = fs__default.default.readFileSync(sourceZipPath);
5960
+ const sourceBuffer = fs8__default.default.readFileSync(sourceZipPath);
5730
5961
  const sourceRes = await fetch(sourceUploadUrl, {
5731
5962
  method: "PUT",
5732
5963
  headers: { "Content-Type": "application/zip" },
@@ -5804,9 +6035,9 @@ async function uploadThumbnail(apiUrl, themeId, themePath, distDir, env = "dev")
5804
6035
  let imageBase64 = null;
5805
6036
  let mimeType = "image/png";
5806
6037
  for (const { file, mime } of THUMBNAIL_CANDIDATES) {
5807
- const candidate = path11__default.default.join(themePath, file);
5808
- if (fs__default.default.existsSync(candidate)) {
5809
- const buf = fs__default.default.readFileSync(candidate);
6038
+ const candidate = path13__default.default.join(themePath, file);
6039
+ if (fs8__default.default.existsSync(candidate)) {
6040
+ const buf = fs8__default.default.readFileSync(candidate);
5810
6041
  imageBase64 = `data:${mime};base64,${buf.toString("base64")}`;
5811
6042
  mimeType = mime;
5812
6043
  logger.info(`Using local thumbnail: ${file}`);
@@ -5906,7 +6137,7 @@ async function screenshotHomePage(themePath, distDir) {
5906
6137
  const { compilePreviewRuntime: compilePreviewRuntime2 } = await Promise.resolve().then(() => (init_compile_theme(), compile_theme_exports));
5907
6138
  const { createDevServer: createDevServer2 } = await Promise.resolve().then(() => (init_dev_server(), dev_server_exports));
5908
6139
  const previewRuntimePath = await compilePreviewRuntime2(themePath);
5909
- const themeName = path11__default.default.basename(themePath);
6140
+ const themeName = path13__default.default.basename(themePath);
5910
6141
  const port = await findFreePort(4500);
5911
6142
  const server = createDevServer2({
5912
6143
  port,
@@ -5963,7 +6194,7 @@ async function findFreePort(start) {
5963
6194
  });
5964
6195
  }
5965
6196
  async function uploadVideoMultipart(apiUrl, themeId, video, env = "dev") {
5966
- const fileName = path11__default.default.basename(video.originalPath);
6197
+ const fileName = path13__default.default.basename(video.originalPath);
5967
6198
  const videoInitUrl = `${apiUrl}/media/videos/multipart/init`;
5968
6199
  const videoInitBody = {
5969
6200
  file_name: fileName,
@@ -5999,7 +6230,7 @@ async function uploadVideoMultipart(apiUrl, themeId, video, env = "dev") {
5999
6230
  );
6000
6231
  }
6001
6232
  const { upload_id, file_key, chunk_size, chunk_urls } = initBody;
6002
- const fileBuffer = await fs__default.default.promises.readFile(video.absPath);
6233
+ const fileBuffer = await fs8__default.default.promises.readFile(video.absPath);
6003
6234
  const CHUNK_CONCURRENCY = 4;
6004
6235
  const queue = [...chunk_urls];
6005
6236
  const parts = [];
@@ -6108,7 +6339,7 @@ async function runSchemaDiffGate(themeId, distDir, env, options) {
6108
6339
  let currentAssets;
6109
6340
  try {
6110
6341
  currentSchemas = JSON.parse(
6111
- await fs__default.default.readFile(path11__default.default.join(distDir, "schemas.json"), "utf-8")
6342
+ await fs8__default.default.readFile(path13__default.default.join(distDir, "schemas.json"), "utf-8")
6112
6343
  );
6113
6344
  } catch (err) {
6114
6345
  logger.warning(
@@ -6118,7 +6349,7 @@ async function runSchemaDiffGate(themeId, distDir, env, options) {
6118
6349
  }
6119
6350
  try {
6120
6351
  currentAssets = JSON.parse(
6121
- await fs__default.default.readFile(path11__default.default.join(distDir, "asset-manifest.json"), "utf-8")
6352
+ await fs8__default.default.readFile(path13__default.default.join(distDir, "asset-manifest.json"), "utf-8")
6122
6353
  );
6123
6354
  } catch {
6124
6355
  currentAssets = { manifestVersion: 1, assets: [] };
@@ -6188,24 +6419,24 @@ var AI_CONTEXT_FILES = [
6188
6419
  ".mcp.json"
6189
6420
  ];
6190
6421
  function resolveTargetDir(opts) {
6191
- return path11__default.default.resolve(opts.cwd ?? process.cwd());
6422
+ return path13__default.default.resolve(opts.cwd ?? process.cwd());
6192
6423
  }
6193
6424
  function resolveDefaultTemplateDir() {
6194
- return path11__default.default.join(getTemplatesDir(), "default");
6425
+ return path13__default.default.join(getTemplatesDir(), "default");
6195
6426
  }
6196
6427
  function isThemeDir(dir) {
6197
- return fs__default.default.existsSync(path11__default.default.join(dir, "theme.config.ts")) || fs__default.default.existsSync(path11__default.default.join(dir, "theme.config.js"));
6428
+ return fs8__default.default.existsSync(path13__default.default.join(dir, "theme.config.ts")) || fs8__default.default.existsSync(path13__default.default.join(dir, "theme.config.js"));
6198
6429
  }
6199
6430
  function inspectFiles(templateDir, targetDir) {
6200
6431
  return AI_CONTEXT_FILES.map((name) => {
6201
- const templatePath = path11__default.default.join(templateDir, name);
6202
- const targetPath = path11__default.default.join(targetDir, name);
6203
- const exists = fs__default.default.existsSync(targetPath);
6432
+ const templatePath = path13__default.default.join(templateDir, name);
6433
+ const targetPath = path13__default.default.join(targetDir, name);
6434
+ const exists = fs8__default.default.existsSync(targetPath);
6204
6435
  let identical = false;
6205
- if (exists && fs__default.default.existsSync(templatePath)) {
6436
+ if (exists && fs8__default.default.existsSync(templatePath)) {
6206
6437
  try {
6207
- const a = fs__default.default.readFileSync(templatePath, "utf-8");
6208
- const b = fs__default.default.readFileSync(targetPath, "utf-8");
6438
+ const a = fs8__default.default.readFileSync(templatePath, "utf-8");
6439
+ const b = fs8__default.default.readFileSync(targetPath, "utf-8");
6209
6440
  identical = a.replace(/\r\n/g, "\n") === b.replace(/\r\n/g, "\n");
6210
6441
  } catch {
6211
6442
  identical = false;
@@ -6255,11 +6486,11 @@ async function mcpSetupCommand(options = {}) {
6255
6486
  }
6256
6487
  }
6257
6488
  for (const s of missing) {
6258
- if (!fs__default.default.existsSync(s.templatePath)) {
6489
+ if (!fs8__default.default.existsSync(s.templatePath)) {
6259
6490
  logger.warning(` ! ${s.name} not in template \u2014 skipped`);
6260
6491
  continue;
6261
6492
  }
6262
- await fs__default.default.copy(s.templatePath, s.targetPath);
6493
+ await fs8__default.default.copy(s.templatePath, s.targetPath);
6263
6494
  logger.success(` \u2713 ${s.name}`);
6264
6495
  }
6265
6496
  logger.log("");
@@ -6320,11 +6551,11 @@ async function mcpUpgradeCommand(options = {}) {
6320
6551
  }
6321
6552
  }
6322
6553
  for (const s of toUpgrade) {
6323
- if (!fs__default.default.existsSync(s.templatePath)) {
6554
+ if (!fs8__default.default.existsSync(s.templatePath)) {
6324
6555
  logger.warning(` ! ${s.name} not in template \u2014 skipped`);
6325
6556
  continue;
6326
6557
  }
6327
- await fs__default.default.copy(s.templatePath, s.targetPath, { overwrite: true });
6558
+ await fs8__default.default.copy(s.templatePath, s.targetPath, { overwrite: true });
6328
6559
  logger.success(` \u2713 ${s.name}`);
6329
6560
  }
6330
6561
  logger.log("");
@@ -6342,12 +6573,12 @@ async function mcpDoctorCommand(options = {}) {
6342
6573
  return;
6343
6574
  }
6344
6575
  logger.success("theme.config.ts present");
6345
- const mcpJsonPath = path11__default.default.join(targetDir, ".mcp.json");
6346
- if (!fs__default.default.existsSync(mcpJsonPath)) {
6576
+ const mcpJsonPath = path13__default.default.join(targetDir, ".mcp.json");
6577
+ if (!fs8__default.default.existsSync(mcpJsonPath)) {
6347
6578
  logger.error(".mcp.json missing \u2014 run `onexthm mcp setup`");
6348
6579
  } else {
6349
6580
  try {
6350
- const mcpJson = JSON.parse(fs__default.default.readFileSync(mcpJsonPath, "utf-8"));
6581
+ const mcpJson = JSON.parse(fs8__default.default.readFileSync(mcpJsonPath, "utf-8"));
6351
6582
  const servers = mcpJson?.mcpServers ?? {};
6352
6583
  if (servers.onexthm) {
6353
6584
  logger.success(".mcp.json registers `onexthm`");
@@ -6380,8 +6611,8 @@ async function mcpDoctorCommand(options = {}) {
6380
6611
  logger.success(`${s.name} up to date`);
6381
6612
  }
6382
6613
  }
6383
- const registryPath = path11__default.default.join(targetDir, "sections-registry.ts");
6384
- if (fs__default.default.existsSync(registryPath)) {
6614
+ const registryPath = path13__default.default.join(targetDir, "sections-registry.ts");
6615
+ if (fs8__default.default.existsSync(registryPath)) {
6385
6616
  logger.success("sections-registry.ts present");
6386
6617
  } else {
6387
6618
  logger.warning(
@@ -6392,24 +6623,27 @@ async function mcpDoctorCommand(options = {}) {
6392
6623
 
6393
6624
  // src/cli.ts
6394
6625
  dotenv__default.default.config({
6395
- path: path11__default.default.join(process.cwd(), ".env.local"),
6626
+ path: path13__default.default.join(process.cwd(), ".env.local"),
6396
6627
  override: true
6397
6628
  });
6398
- dotenv__default.default.config({ path: path11__default.default.join(process.cwd(), ".env") });
6629
+ dotenv__default.default.config({ path: path13__default.default.join(process.cwd(), ".env") });
6399
6630
  try {
6400
6631
  const projectRoot = getProjectRoot();
6401
- if (path11__default.default.resolve(projectRoot) !== path11__default.default.resolve(process.cwd())) {
6632
+ if (path13__default.default.resolve(projectRoot) !== path13__default.default.resolve(process.cwd())) {
6402
6633
  dotenv__default.default.config({
6403
- path: path11__default.default.join(projectRoot, ".env.local")
6634
+ path: path13__default.default.join(projectRoot, ".env.local")
6404
6635
  });
6405
- dotenv__default.default.config({ path: path11__default.default.join(projectRoot, ".env") });
6636
+ dotenv__default.default.config({ path: path13__default.default.join(projectRoot, ".env") });
6406
6637
  }
6407
6638
  } catch {
6408
6639
  }
6409
6640
  dotenv__default.default.config({
6410
- path: path11__default.default.join(os__default.default.homedir(), ".onexthm", ".env"),
6641
+ path: path13__default.default.join(os__default.default.homedir(), ".onexthm", ".env"),
6411
6642
  quiet: true
6412
6643
  });
6644
+ function envOpt() {
6645
+ return new commander.Option("--env <env>", "Target environment: dev, staging, or prod").choices(["dev", "staging", "prod"]).makeOptionMandatory();
6646
+ }
6413
6647
  var require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
6414
6648
  var { version } = require2("../package.json");
6415
6649
  var program = new commander.Command();
@@ -6418,11 +6652,7 @@ program.command("init").description("Create a new OneX theme project").argument(
6418
6652
  "-t, --template <template>",
6419
6653
  "Template to use (default, minimal)",
6420
6654
  "default"
6421
- ).option("--no-install", "Skip installing dependencies").option("--git", "Initialize git repository").option("-y, --yes", "Skip prompts and use defaults").option(
6422
- "--env <env>",
6423
- "Target environment: dev, staging, or prod (default: dev)",
6424
- "dev"
6425
- ).action(initCommand);
6655
+ ).option("--no-install", "Skip installing dependencies").option("--git", "Initialize git repository").option("-y, --yes", "Skip prompts and use defaults").addOption(envOpt()).action(initCommand);
6426
6656
  program.command("create:section").alias("cs").description("Create a new section").argument("<name>", "Name of the section (e.g., hero, features)").option("-t, --theme <theme>", "Theme to create section in").option(
6427
6657
  "-c, --category <category>",
6428
6658
  "Section category (headers, content, footers)"
@@ -6449,36 +6679,16 @@ program.command("download").description("Download a published theme via the webs
6449
6679
  "-v, --version <version>",
6450
6680
  "Theme version (default: latest)",
6451
6681
  "latest"
6452
- ).option(
6453
- "--env <env>",
6454
- "Target environment: dev, staging, or prod (default: dev)",
6455
- "dev"
6456
- ).option("-b, --bucket <name>", "[deprecated] ignored").option("-o, --output <dir>", "Output directory", "./active-theme").action(downloadCommand);
6682
+ ).addOption(envOpt()).option("-b, --bucket <name>", "[deprecated] ignored").option("-o, --output <dir>", "Output directory", "./active-theme").action(downloadCommand);
6457
6683
  program.command("clone").description("Clone theme source code via the website-api").argument("<theme-name>", "Theme to clone").option(
6458
6684
  "-v, --version <version>",
6459
6685
  "Theme version (default: latest)",
6460
6686
  "latest"
6461
- ).option("-n, --name <name>", "New theme name (skips interactive prompt)").option("-o, --output <dir>", "Output directory").option(
6462
- "--env <env>",
6463
- "Target environment: dev, staging, or prod (default: dev)",
6464
- "dev"
6465
- ).option("-b, --bucket <name>", "[deprecated] ignored").option("--no-install", "Skip running pnpm install after clone").action(cloneCommand);
6687
+ ).option("-n, --name <name>", "New theme name (skips interactive prompt)").option("-o, --output <dir>", "Output directory").addOption(envOpt()).option("-b, --bucket <name>", "[deprecated] ignored").option("--no-install", "Skip running pnpm install after clone").action(cloneCommand);
6466
6688
  program.command("config").description("Configure OneX CLI credentials (AWS, API keys)").action(configCommand);
6467
- program.command("login").description("Login to OneX platform").option(
6468
- "--env <env>",
6469
- "Target environment: dev, staging, or prod (default: dev)",
6470
- "dev"
6471
- ).action(loginCommand);
6472
- program.command("logout").description("Logout from OneX platform").option(
6473
- "--env <env>",
6474
- "Target environment: dev, staging, or prod (default: dev)",
6475
- "dev"
6476
- ).action(logoutCommand);
6477
- program.command("whoami").description("Show current logged-in developer").option(
6478
- "--env <env>",
6479
- "Target environment: dev, staging, or prod (default: dev)",
6480
- "dev"
6481
- ).action(whoamiCommand);
6689
+ program.command("login").description("Login to OneX platform").addOption(envOpt()).action(loginCommand);
6690
+ program.command("logout").description("Logout from OneX platform").addOption(envOpt()).action(logoutCommand);
6691
+ program.command("whoami").description("Show current logged-in developer").addOption(envOpt()).action(whoamiCommand);
6482
6692
  var mcpCmd = program.command("mcp").description("Manage MCP server registration and AI-context files");
6483
6693
  mcpCmd.command("setup").description(
6484
6694
  "Install .mcp.json + CLAUDE.md + AGENTS.md + .cursorrules into the current theme"
@@ -6490,11 +6700,7 @@ mcpCmd.command("doctor").description("Diagnose MCP setup in the current theme di
6490
6700
  program.command("publish").description("Build, scan, and publish theme to marketplace (requires login)").option("-t, --theme <path>", "Theme directory path").option(
6491
6701
  "--bump <type>",
6492
6702
  "Auto-bump version before publish (patch|minor|major)"
6493
- ).option(
6494
- "--env <env>",
6495
- "Target environment: dev, staging, or prod (default: dev)",
6496
- "dev"
6497
- ).option(
6703
+ ).addOption(envOpt()).option(
6498
6704
  "--dry-run",
6499
6705
  "Build locally and print the schema-diff classification without publishing"
6500
6706
  ).option(