@onexapis/cli 1.1.37 → 1.1.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/cli.js +639 -401
  2. package/dist/cli.js.map +1 -1
  3. package/dist/cli.mjs +633 -396
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/index.js +255 -203
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +252 -200
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +6 -4
  10. package/templates/default/CLAUDE.md +334 -1
  11. package/templates/default/esbuild.config.js +20 -0
  12. package/templates/default/pages/about.ts +2 -2
  13. package/templates/default/pages/forgot-password.ts +1 -3
  14. package/templates/default/pages/home.ts +4 -4
  15. package/templates/default/pages/login.ts +1 -3
  16. package/templates/default/pages/profile.ts +2 -2
  17. package/templates/default/pages/register.ts +1 -3
  18. package/templates/default/pages/showcase.ts +7 -7
  19. package/templates/default/pages/verify-code.ts +1 -3
  20. package/templates/default/sections/about/about.schema.ts +1 -1
  21. package/templates/default/sections/auth-forgot-password/auth-forgot-password.schema.ts +1 -1
  22. package/templates/default/sections/auth-login/auth-login.schema.ts +1 -1
  23. package/templates/default/sections/auth-register/auth-register.schema.ts +1 -1
  24. package/templates/default/sections/auth-verify-code/auth-verify-code.schema.ts +1 -1
  25. package/templates/default/sections/cta/cta.schema.ts +1 -1
  26. package/templates/default/sections/features/features.schema.ts +1 -1
  27. package/templates/default/sections/footer/footer.schema.ts +1 -1
  28. package/templates/default/sections/gallery/gallery.schema.ts +1 -1
  29. package/templates/default/sections/header/header.schema.ts +1 -1
  30. package/templates/default/sections/hero/hero.schema.ts +1 -1
  31. package/templates/default/sections/profile/profile.schema.ts +1 -1
  32. package/templates/default/sections/stats/stats.schema.ts +1 -1
  33. package/templates/default/sections/testimonials/testimonials.schema.ts +1 -1
  34. package/templates/default/theme.layout.ts +18 -0
package/dist/cli.js CHANGED
@@ -4,18 +4,18 @@
4
4
  var chalk4 = require('chalk');
5
5
  var ora = require('ora');
6
6
  var esbuild = require('esbuild');
7
- var path8 = require('path');
8
- var fs7 = require('fs/promises');
9
- var crypto2 = require('crypto');
7
+ var path9 = require('path');
8
+ var fs8 = require('fs/promises');
9
+ var crypto = require('crypto');
10
10
  var glob = require('glob');
11
11
  var module$1 = require('module');
12
- var os3 = require('os');
12
+ var os = require('os');
13
13
  var dotenv = require('dotenv');
14
14
  var fs = require('fs-extra');
15
15
  var ejs = require('ejs');
16
16
  var child_process = require('child_process');
17
17
  var commander = require('commander');
18
- var fs2 = require('fs');
18
+ var fs3 = require('fs');
19
19
  var inquirer = require('inquirer');
20
20
  var archiver = require('archiver');
21
21
  var FormData = require('form-data');
@@ -25,6 +25,7 @@ var AdmZip = require('adm-zip');
25
25
  var chokidar = require('chokidar');
26
26
  var http = require('http');
27
27
  var ws = require('ws');
28
+ var semver = require('semver');
28
29
 
29
30
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
30
31
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -50,14 +51,14 @@ function _interopNamespace(e) {
50
51
  var chalk4__default = /*#__PURE__*/_interopDefault(chalk4);
51
52
  var ora__default = /*#__PURE__*/_interopDefault(ora);
52
53
  var esbuild__namespace = /*#__PURE__*/_interopNamespace(esbuild);
53
- var path8__default = /*#__PURE__*/_interopDefault(path8);
54
- var fs7__default = /*#__PURE__*/_interopDefault(fs7);
55
- var crypto2__default = /*#__PURE__*/_interopDefault(crypto2);
56
- var os3__default = /*#__PURE__*/_interopDefault(os3);
54
+ var path9__default = /*#__PURE__*/_interopDefault(path9);
55
+ var fs8__default = /*#__PURE__*/_interopDefault(fs8);
56
+ var crypto__default = /*#__PURE__*/_interopDefault(crypto);
57
+ var os__default = /*#__PURE__*/_interopDefault(os);
57
58
  var dotenv__default = /*#__PURE__*/_interopDefault(dotenv);
58
59
  var fs__default = /*#__PURE__*/_interopDefault(fs);
59
60
  var ejs__default = /*#__PURE__*/_interopDefault(ejs);
60
- var fs2__default = /*#__PURE__*/_interopDefault(fs2);
61
+ var fs3__default = /*#__PURE__*/_interopDefault(fs3);
61
62
  var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
62
63
  var archiver__default = /*#__PURE__*/_interopDefault(archiver);
63
64
  var FormData__default = /*#__PURE__*/_interopDefault(FormData);
@@ -65,6 +66,7 @@ var fetch2__default = /*#__PURE__*/_interopDefault(fetch2);
65
66
  var AdmZip__default = /*#__PURE__*/_interopDefault(AdmZip);
66
67
  var chokidar__default = /*#__PURE__*/_interopDefault(chokidar);
67
68
  var http__default = /*#__PURE__*/_interopDefault(http);
69
+ var semver__default = /*#__PURE__*/_interopDefault(semver);
68
70
 
69
71
  var __defProp = Object.defineProperty;
70
72
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -146,8 +148,8 @@ async function generateThemeCSS(themePath, outDir) {
146
148
  const tailwindcss = (await import('tailwindcss')).default;
147
149
  const tailwindConfig = {
148
150
  content: [
149
- path8__default.default.join(themePath, "sections/**/*.{ts,tsx}"),
150
- path8__default.default.join(themePath, "components/**/*.{ts,tsx}")
151
+ path9__default.default.join(themePath, "sections/**/*.{ts,tsx}"),
152
+ path9__default.default.join(themePath, "components/**/*.{ts,tsx}")
151
153
  ],
152
154
  theme: { extend: {} },
153
155
  plugins: []
@@ -157,7 +159,7 @@ async function generateThemeCSS(themePath, outDir) {
157
159
  inputCSS,
158
160
  { from: void 0 }
159
161
  );
160
- await fs7__default.default.writeFile(path8__default.default.join(outDir, "bundle.css"), result.css);
162
+ await fs8__default.default.writeFile(path9__default.default.join(outDir, "bundle.css"), result.css);
161
163
  logger.info("Generated bundle.css");
162
164
  } catch (err) {
163
165
  logger.warning(
@@ -168,12 +170,12 @@ async function generateThemeCSS(themePath, outDir) {
168
170
  async function resolveNodeModulesFile(startDir, relativePath) {
169
171
  let dir = startDir;
170
172
  while (true) {
171
- const candidate = path8__default.default.join(dir, "node_modules", relativePath);
173
+ const candidate = path9__default.default.join(dir, "node_modules", relativePath);
172
174
  try {
173
- await fs7__default.default.access(candidate);
175
+ await fs8__default.default.access(candidate);
174
176
  return candidate;
175
177
  } catch {
176
- const parent = path8__default.default.dirname(dir);
178
+ const parent = path9__default.default.dirname(dir);
177
179
  if (parent === dir) break;
178
180
  dir = parent;
179
181
  }
@@ -197,7 +199,7 @@ async function scanImportsFromPackage(sourceDir, packageName) {
197
199
  });
198
200
  for (const file of sourceFiles) {
199
201
  try {
200
- const content = await fs7__default.default.readFile(path8__default.default.join(sourceDir, file), "utf-8");
202
+ const content = await fs8__default.default.readFile(path9__default.default.join(sourceDir, file), "utf-8");
201
203
  for (const match of content.matchAll(namespaceImportRegex)) {
202
204
  const subpath = match[1] ? match[1].slice(1) : "";
203
205
  if (!result[subpath]) result[subpath] = /* @__PURE__ */ new Set();
@@ -251,17 +253,17 @@ function createCoreGlobalPlugin(themePath) {
251
253
  const distFileName = subpath ? `${subpath}.mjs` : "index.mjs";
252
254
  let distPath = await resolveNodeModulesFile(
253
255
  themePath,
254
- path8__default.default.join("@onexapis", "core", "dist", distFileName)
256
+ path9__default.default.join("@onexapis", "core", "dist", distFileName)
255
257
  );
256
258
  if (!distPath) {
257
259
  distPath = await resolveNodeModulesFile(
258
260
  __dirname,
259
- path8__default.default.join("@onexapis", "core", "dist", distFileName)
261
+ path9__default.default.join("@onexapis", "core", "dist", distFileName)
260
262
  );
261
263
  }
262
264
  try {
263
265
  if (!distPath) throw new Error("not found");
264
- const distContent = await fs7__default.default.readFile(distPath, "utf-8");
266
+ const distContent = await fs8__default.default.readFile(distPath, "utf-8");
265
267
  const exportMatches = distContent.matchAll(/export\s*\{([^}]+)\}/g);
266
268
  for (const m of exportMatches) {
267
269
  const names = m[1].split(",").map((n) => {
@@ -490,7 +492,7 @@ async function generateThemeData(themePath, outputDir, themeId) {
490
492
  const pages = {};
491
493
  for (const ext of [".ts", ".js"]) {
492
494
  try {
493
- const mod = await jiti.import(path8__default.default.join(themePath, `theme.config${ext}`));
495
+ const mod = await jiti.import(path9__default.default.join(themePath, `theme.config${ext}`));
494
496
  themeConfig = mod.default || mod;
495
497
  break;
496
498
  } catch {
@@ -498,20 +500,20 @@ async function generateThemeData(themePath, outputDir, themeId) {
498
500
  }
499
501
  for (const ext of [".ts", ".js"]) {
500
502
  try {
501
- const mod = await jiti.import(path8__default.default.join(themePath, `theme.layout${ext}`));
503
+ const mod = await jiti.import(path9__default.default.join(themePath, `theme.layout${ext}`));
502
504
  layoutConfig = mod.default || mod;
503
505
  break;
504
506
  } catch {
505
507
  }
506
508
  }
507
509
  const schemas = {};
508
- const sectionsDir = path8__default.default.join(themePath, "sections");
510
+ const sectionsDir = path9__default.default.join(themePath, "sections");
509
511
  try {
510
- const sectionDirs = await fs7__default.default.readdir(sectionsDir);
512
+ const sectionDirs = await fs8__default.default.readdir(sectionsDir);
511
513
  for (const dir of sectionDirs) {
512
- const schemaFile = path8__default.default.join(sectionsDir, dir, `${dir}.schema.ts`);
514
+ const schemaFile = path9__default.default.join(sectionsDir, dir, `${dir}.schema.ts`);
513
515
  try {
514
- await fs7__default.default.access(schemaFile);
516
+ await fs8__default.default.access(schemaFile);
515
517
  const mod = await jiti.import(schemaFile);
516
518
  for (const [key, value] of Object.entries(mod)) {
517
519
  if (key.endsWith("Schema") && value && typeof value === "object" && value.type) {
@@ -523,14 +525,14 @@ async function generateThemeData(themePath, outputDir, themeId) {
523
525
  }
524
526
  } catch {
525
527
  }
526
- const pagesDir = path8__default.default.join(themePath, "pages");
528
+ const pagesDir = path9__default.default.join(themePath, "pages");
527
529
  try {
528
- const files = await fs7__default.default.readdir(pagesDir);
530
+ const files = await fs8__default.default.readdir(pagesDir);
529
531
  for (const file of files) {
530
532
  if (!file.match(/\.(ts|js)$/)) continue;
531
533
  const name = file.replace(/\.(ts|js)$/, "");
532
534
  try {
533
- const mod = await jiti.import(path8__default.default.join(pagesDir, file));
535
+ const mod = await jiti.import(path9__default.default.join(pagesDir, file));
534
536
  const config = mod.default || mod;
535
537
  const sections = (config.sections || []).map((section) => {
536
538
  const schema = schemas[section.type];
@@ -558,8 +560,8 @@ async function generateThemeData(themePath, outputDir, themeId) {
558
560
  }
559
561
  } catch {
560
562
  }
561
- await fs7__default.default.writeFile(
562
- path8__default.default.join(outputDir, "theme-data.json"),
563
+ await fs8__default.default.writeFile(
564
+ path9__default.default.join(outputDir, "theme-data.json"),
563
565
  JSON.stringify(
564
566
  {
565
567
  themeId,
@@ -582,53 +584,53 @@ async function generateThemeData(themePath, outputDir, themeId) {
582
584
  logger.info(`Generated theme-data.json (${Object.keys(pages).length} pages)`);
583
585
  }
584
586
  async function contentHashEntry(outputDir) {
585
- const entryPath = path8__default.default.join(outputDir, "bundle-entry.js");
586
- const mapPath = path8__default.default.join(outputDir, "bundle-entry.js.map");
587
+ const entryPath = path9__default.default.join(outputDir, "bundle-entry.js");
588
+ const mapPath = path9__default.default.join(outputDir, "bundle-entry.js.map");
587
589
  const oldFiles = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
588
590
  for (const f of oldFiles) {
589
- await fs7__default.default.unlink(path8__default.default.join(outputDir, f));
591
+ await fs8__default.default.unlink(path9__default.default.join(outputDir, f));
590
592
  }
591
593
  let entryContent;
592
594
  try {
593
- entryContent = await fs7__default.default.readFile(entryPath, "utf-8");
595
+ entryContent = await fs8__default.default.readFile(entryPath, "utf-8");
594
596
  } catch {
595
- const indexPath = path8__default.default.join(outputDir, "index.js");
597
+ const indexPath = path9__default.default.join(outputDir, "index.js");
596
598
  try {
597
- entryContent = await fs7__default.default.readFile(indexPath, "utf-8");
599
+ entryContent = await fs8__default.default.readFile(indexPath, "utf-8");
598
600
  } catch {
599
601
  logger.warning("No entry file found in output, skipping content hash");
600
602
  return;
601
603
  }
602
- const hash2 = crypto2__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
604
+ const hash2 = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
603
605
  const hashedName2 = `bundle-entry-${hash2}.js`;
604
- const indexMapPath = path8__default.default.join(outputDir, "index.js.map");
606
+ const indexMapPath = path9__default.default.join(outputDir, "index.js.map");
605
607
  const hashedMapName2 = `bundle-entry-${hash2}.js.map`;
606
608
  entryContent = entryContent.replace(
607
609
  /\/\/# sourceMappingURL=index\.js\.map/,
608
610
  `//# sourceMappingURL=${hashedMapName2}`
609
611
  );
610
- await fs7__default.default.writeFile(path8__default.default.join(outputDir, hashedName2), entryContent);
611
- await fs7__default.default.unlink(indexPath);
612
+ await fs8__default.default.writeFile(path9__default.default.join(outputDir, hashedName2), entryContent);
613
+ await fs8__default.default.unlink(indexPath);
612
614
  try {
613
- await fs7__default.default.access(indexMapPath);
614
- await fs7__default.default.rename(indexMapPath, path8__default.default.join(outputDir, hashedMapName2));
615
+ await fs8__default.default.access(indexMapPath);
616
+ await fs8__default.default.rename(indexMapPath, path9__default.default.join(outputDir, hashedMapName2));
615
617
  } catch {
616
618
  }
617
619
  logger.info(`Entry hashed: ${hashedName2}`);
618
620
  return;
619
621
  }
620
- const hash = crypto2__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
622
+ const hash = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
621
623
  const hashedName = `bundle-entry-${hash}.js`;
622
624
  const hashedMapName = `bundle-entry-${hash}.js.map`;
623
625
  entryContent = entryContent.replace(
624
626
  /\/\/# sourceMappingURL=bundle-entry\.js\.map/,
625
627
  `//# sourceMappingURL=${hashedMapName}`
626
628
  );
627
- await fs7__default.default.writeFile(path8__default.default.join(outputDir, hashedName), entryContent);
628
- await fs7__default.default.unlink(entryPath);
629
+ await fs8__default.default.writeFile(path9__default.default.join(outputDir, hashedName), entryContent);
630
+ await fs8__default.default.unlink(entryPath);
629
631
  try {
630
- await fs7__default.default.access(mapPath);
631
- await fs7__default.default.rename(mapPath, path8__default.default.join(outputDir, hashedMapName));
632
+ await fs8__default.default.access(mapPath);
633
+ await fs8__default.default.rename(mapPath, path9__default.default.join(outputDir, hashedMapName));
632
634
  } catch {
633
635
  }
634
636
  logger.info(`Entry hashed: ${hashedName}`);
@@ -640,7 +642,7 @@ async function extractDataRequirements(themePath) {
640
642
  const requirements = {};
641
643
  for (const file of schemaFiles) {
642
644
  try {
643
- const mod = await jiti.import(path8__default.default.join(themePath, file));
645
+ const mod = await jiti.import(path9__default.default.join(themePath, file));
644
646
  const exports$1 = mod;
645
647
  for (const value of Object.values(exports$1)) {
646
648
  if (value && typeof value === "object" && typeof value.type === "string" && value.dataRequirements && typeof value.dataRequirements === "object") {
@@ -659,8 +661,8 @@ async function generateManifest(themeName, themePath, outputDir) {
659
661
  let version2 = "1.0.0";
660
662
  let themeId = themeName;
661
663
  try {
662
- const pkgContent = await fs7__default.default.readFile(
663
- path8__default.default.join(themePath, "package.json"),
664
+ const pkgContent = await fs8__default.default.readFile(
665
+ path9__default.default.join(themePath, "package.json"),
664
666
  "utf-8"
665
667
  );
666
668
  const pkg = JSON.parse(pkgContent);
@@ -678,7 +680,7 @@ async function generateManifest(themeName, themePath, outputDir) {
678
680
  const dataRequirements = await extractDataRequirements(themePath);
679
681
  let hasThemeConfig = false;
680
682
  try {
681
- await fs7__default.default.access(path8__default.default.join(themePath, "theme.config.ts"));
683
+ await fs8__default.default.access(path9__default.default.join(themePath, "theme.config.ts"));
682
684
  hasThemeConfig = true;
683
685
  } catch {
684
686
  }
@@ -719,24 +721,24 @@ async function generateManifest(themeName, themePath, outputDir) {
719
721
  // Section data requirements for server-side prefetching (keyed by section type)
720
722
  dataRequirements
721
723
  };
722
- await fs7__default.default.writeFile(
723
- path8__default.default.join(outputDir, "manifest.json"),
724
+ await fs8__default.default.writeFile(
725
+ path9__default.default.join(outputDir, "manifest.json"),
724
726
  JSON.stringify(manifest, null, 2)
725
727
  );
726
728
  }
727
729
  async function compileStandaloneTheme(themePath, themeName) {
728
- const outputDir = path8__default.default.join(themePath, "dist");
729
- const bundleEntry = path8__default.default.join(themePath, "bundle-entry.ts");
730
- const indexEntry = path8__default.default.join(themePath, "index.ts");
730
+ const outputDir = path9__default.default.join(themePath, "dist");
731
+ const bundleEntry = path9__default.default.join(themePath, "bundle-entry.ts");
732
+ const indexEntry = path9__default.default.join(themePath, "index.ts");
731
733
  let entryPoint = indexEntry;
732
734
  try {
733
- await fs7__default.default.access(bundleEntry);
735
+ await fs8__default.default.access(bundleEntry);
734
736
  entryPoint = bundleEntry;
735
737
  } catch {
736
738
  }
737
- const shimPath = path8__default.default.join(outputDir, ".process-shim.js");
738
- await fs7__default.default.mkdir(outputDir, { recursive: true });
739
- await fs7__default.default.writeFile(shimPath, PROCESS_SHIM);
739
+ const shimPath = path9__default.default.join(outputDir, ".process-shim.js");
740
+ await fs8__default.default.mkdir(outputDir, { recursive: true });
741
+ await fs8__default.default.writeFile(shimPath, PROCESS_SHIM);
740
742
  const buildOptions = {
741
743
  entryPoints: [entryPoint],
742
744
  bundle: true,
@@ -786,7 +788,7 @@ async function compileStandaloneTheme(themePath, themeName) {
786
788
  try {
787
789
  const result = await esbuild__namespace.build(buildOptions);
788
790
  try {
789
- await fs7__default.default.unlink(shimPath);
791
+ await fs8__default.default.unlink(shimPath);
790
792
  } catch {
791
793
  }
792
794
  await contentHashEntry(outputDir);
@@ -805,7 +807,7 @@ async function compileStandaloneTheme(themePath, themeName) {
805
807
  return true;
806
808
  } catch (error) {
807
809
  try {
808
- await fs7__default.default.unlink(shimPath);
810
+ await fs8__default.default.unlink(shimPath);
809
811
  } catch {
810
812
  }
811
813
  logger.error(`esbuild compilation failed: ${error}`);
@@ -813,18 +815,18 @@ async function compileStandaloneTheme(themePath, themeName) {
813
815
  }
814
816
  }
815
817
  async function compileStandaloneThemeDev(themePath, themeName) {
816
- const outputDir = path8__default.default.join(themePath, "dist");
817
- const bundleEntry = path8__default.default.join(themePath, "bundle-entry.ts");
818
- const indexEntry = path8__default.default.join(themePath, "index.ts");
818
+ const outputDir = path9__default.default.join(themePath, "dist");
819
+ const bundleEntry = path9__default.default.join(themePath, "bundle-entry.ts");
820
+ const indexEntry = path9__default.default.join(themePath, "index.ts");
819
821
  let entryPoint = indexEntry;
820
822
  try {
821
- await fs7__default.default.access(bundleEntry);
823
+ await fs8__default.default.access(bundleEntry);
822
824
  entryPoint = bundleEntry;
823
825
  } catch {
824
826
  }
825
- const shimPath = path8__default.default.join(outputDir, ".process-shim.js");
826
- await fs7__default.default.mkdir(outputDir, { recursive: true });
827
- await fs7__default.default.writeFile(shimPath, PROCESS_SHIM);
827
+ const shimPath = path9__default.default.join(outputDir, ".process-shim.js");
828
+ await fs8__default.default.mkdir(outputDir, { recursive: true });
829
+ await fs8__default.default.writeFile(shimPath, PROCESS_SHIM);
828
830
  const buildOptions = {
829
831
  entryPoints: [entryPoint],
830
832
  bundle: true,
@@ -877,18 +879,18 @@ async function compileStandaloneThemeDev(themePath, themeName) {
877
879
  return { context: context2, outputDir };
878
880
  }
879
881
  async function compilePreviewRuntime(themePath) {
880
- const outputDir = path8__default.default.join(themePath, "dist");
881
- await fs7__default.default.mkdir(outputDir, { recursive: true });
882
- const outputPath = path8__default.default.join(outputDir, "preview-runtime.js");
882
+ const outputDir = path9__default.default.join(themePath, "dist");
883
+ await fs8__default.default.mkdir(outputDir, { recursive: true });
884
+ const outputPath = path9__default.default.join(outputDir, "preview-runtime.js");
883
885
  const locations = [
884
- path8__default.default.join(__dirname, "..", "preview", "preview-app.tsx"),
885
- path8__default.default.join(__dirname, "preview", "preview-app.tsx"),
886
- path8__default.default.join(__dirname, "..", "..", "src", "preview", "preview-app.tsx")
886
+ path9__default.default.join(__dirname, "..", "preview", "preview-app.tsx"),
887
+ path9__default.default.join(__dirname, "preview", "preview-app.tsx"),
888
+ path9__default.default.join(__dirname, "..", "..", "src", "preview", "preview-app.tsx")
887
889
  ];
888
890
  let previewEntryPath = null;
889
891
  for (const loc of locations) {
890
892
  try {
891
- await fs7__default.default.access(loc);
893
+ await fs8__default.default.access(loc);
892
894
  previewEntryPath = loc;
893
895
  break;
894
896
  } catch {
@@ -971,10 +973,10 @@ ${locations.join("\n")}`
971
973
  if (!lucideScanned) {
972
974
  lucideScanned = true;
973
975
  const coreSrcCandidates = [
974
- path8__default.default.join(themePath, "node_modules", "@onexapis", "core", "src"),
975
- path8__default.default.join(themePath, "..", "..", "packages", "core", "src"),
976
+ path9__default.default.join(themePath, "node_modules", "@onexapis", "core", "src"),
977
+ path9__default.default.join(themePath, "..", "..", "packages", "core", "src"),
976
978
  // monorepo sibling
977
- path8__default.default.join(
979
+ path9__default.default.join(
978
980
  __dirname,
979
981
  "..",
980
982
  "..",
@@ -989,7 +991,7 @@ ${locations.join("\n")}`
989
991
  let coreSourceDir = null;
990
992
  for (const candidate of coreSrcCandidates) {
991
993
  try {
992
- await fs7__default.default.access(candidate);
994
+ await fs8__default.default.access(candidate);
993
995
  coreSourceDir = candidate;
994
996
  break;
995
997
  } catch {
@@ -1008,21 +1010,21 @@ ${locations.join("\n")}`
1008
1010
  }
1009
1011
  } else {
1010
1012
  const coreDistCandidates = [
1011
- path8__default.default.join(themePath, "node_modules", "@onexapis", "core", "dist")
1013
+ path9__default.default.join(themePath, "node_modules", "@onexapis", "core", "dist")
1012
1014
  ];
1013
1015
  const resolvedDist = await resolveNodeModulesFile(
1014
1016
  __dirname,
1015
- path8__default.default.join("@onexapis", "core", "dist")
1017
+ path9__default.default.join("@onexapis", "core", "dist")
1016
1018
  );
1017
1019
  if (resolvedDist) coreDistCandidates.push(resolvedDist);
1018
1020
  for (const candidate of coreDistCandidates) {
1019
1021
  try {
1020
- await fs7__default.default.access(candidate);
1022
+ await fs8__default.default.access(candidate);
1021
1023
  const mjsFiles = await glob.glob("*.mjs", { cwd: candidate });
1022
1024
  const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']lucide-react["']/g;
1023
1025
  for (const file of mjsFiles) {
1024
- const content = await fs7__default.default.readFile(
1025
- path8__default.default.join(candidate, file),
1026
+ const content = await fs8__default.default.readFile(
1027
+ path9__default.default.join(candidate, file),
1026
1028
  "utf-8"
1027
1029
  );
1028
1030
  for (const match of content.matchAll(importRegex)) {
@@ -1077,7 +1079,7 @@ export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true :
1077
1079
  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);
1078
1080
  const cjsPath = req.resolve("framer-motion");
1079
1081
  const pkgDir = cjsPath.replace(/[/\\]dist[/\\].*$/, "");
1080
- const esmEntry = path8__default.default.join(pkgDir, "dist", "es", "index.mjs");
1082
+ const esmEntry = path9__default.default.join(pkgDir, "dist", "es", "index.mjs");
1081
1083
  const { existsSync } = await import('fs');
1082
1084
  if (existsSync(esmEntry)) {
1083
1085
  return { path: esmEntry, namespace: "file" };
@@ -1176,8 +1178,8 @@ export function headers() { return new Headers(); }
1176
1178
  });
1177
1179
  }
1178
1180
  };
1179
- const shimPath = path8__default.default.join(outputDir, ".process-shim-preview.js");
1180
- await fs7__default.default.writeFile(shimPath, PROCESS_SHIM);
1181
+ const shimPath = path9__default.default.join(outputDir, ".process-shim-preview.js");
1182
+ await fs8__default.default.writeFile(shimPath, PROCESS_SHIM);
1181
1183
  await esbuild__namespace.build({
1182
1184
  entryPoints: [previewEntryPath],
1183
1185
  bundle: true,
@@ -1212,7 +1214,7 @@ export function headers() { return new Headers(); }
1212
1214
  }
1213
1215
  });
1214
1216
  try {
1215
- await fs7__default.default.unlink(shimPath);
1217
+ await fs8__default.default.unlink(shimPath);
1216
1218
  } catch {
1217
1219
  }
1218
1220
  return outputPath;
@@ -1345,18 +1347,18 @@ async function renderTemplate(templatePath, data) {
1345
1347
  return ejs__default.default.render(template, data);
1346
1348
  }
1347
1349
  async function writeFile(filePath, content) {
1348
- await fs__default.default.ensureDir(path8__default.default.dirname(filePath));
1350
+ await fs__default.default.ensureDir(path9__default.default.dirname(filePath));
1349
1351
  await fs__default.default.writeFile(filePath, content, "utf-8");
1350
1352
  }
1351
1353
  function getTemplatesDir() {
1352
1354
  const locations = [
1353
- path8__default.default.join(__dirname, "../../templates"),
1355
+ path9__default.default.join(__dirname, "../../templates"),
1354
1356
  // Development
1355
- path8__default.default.join(__dirname, "../templates"),
1357
+ path9__default.default.join(__dirname, "../templates"),
1356
1358
  // Production (dist/)
1357
- path8__default.default.join(process.cwd(), "templates"),
1359
+ path9__default.default.join(process.cwd(), "templates"),
1358
1360
  // Fallback
1359
- path8__default.default.join(process.cwd(), "packages/cli/templates")
1361
+ path9__default.default.join(process.cwd(), "packages/cli/templates")
1360
1362
  // Monorepo
1361
1363
  ];
1362
1364
  for (const location of locations) {
@@ -1368,7 +1370,7 @@ function getTemplatesDir() {
1368
1370
  }
1369
1371
  async function copyTemplate(templateName, targetDir, data) {
1370
1372
  const templatesDir = getTemplatesDir();
1371
- const templateDir = path8__default.default.join(templatesDir, templateName);
1373
+ const templateDir = path9__default.default.join(templatesDir, templateName);
1372
1374
  if (!fs__default.default.existsSync(templateDir)) {
1373
1375
  throw new Error(
1374
1376
  `Template "${templateName}" not found at ${templateDir}. Available templates: ${fs__default.default.readdirSync(templatesDir).join(", ")}`
@@ -1377,8 +1379,8 @@ async function copyTemplate(templateName, targetDir, data) {
1377
1379
  await fs__default.default.ensureDir(targetDir);
1378
1380
  const files = await fs__default.default.readdir(templateDir);
1379
1381
  for (const file of files) {
1380
- const templatePath = path8__default.default.join(templateDir, file);
1381
- const targetPath = path8__default.default.join(targetDir, file);
1382
+ const templatePath = path9__default.default.join(templateDir, file);
1383
+ const targetPath = path9__default.default.join(targetDir, file);
1382
1384
  const stat = await fs__default.default.stat(templatePath);
1383
1385
  if (stat.isDirectory()) {
1384
1386
  await copyTemplateDir(templatePath, targetPath, data);
@@ -1395,8 +1397,8 @@ async function copyTemplateDir(templateDir, targetDir, data) {
1395
1397
  await fs__default.default.ensureDir(targetDir);
1396
1398
  const files = await fs__default.default.readdir(templateDir);
1397
1399
  for (const file of files) {
1398
- const templatePath = path8__default.default.join(templateDir, file);
1399
- const targetPath = path8__default.default.join(targetDir, file);
1400
+ const templatePath = path9__default.default.join(templateDir, file);
1401
+ const targetPath = path9__default.default.join(targetDir, file);
1400
1402
  const stat = await fs__default.default.stat(templatePath);
1401
1403
  if (stat.isDirectory()) {
1402
1404
  await copyTemplateDir(templatePath, targetPath, data);
@@ -1411,32 +1413,32 @@ async function copyTemplateDir(templateDir, targetDir, data) {
1411
1413
  }
1412
1414
  function getProjectRoot() {
1413
1415
  let currentDir = process.cwd();
1414
- while (currentDir !== path8__default.default.parse(currentDir).root) {
1415
- const packageJsonPath = path8__default.default.join(currentDir, "package.json");
1416
+ while (currentDir !== path9__default.default.parse(currentDir).root) {
1417
+ const packageJsonPath = path9__default.default.join(currentDir, "package.json");
1416
1418
  if (fs__default.default.existsSync(packageJsonPath)) {
1417
1419
  const packageJson = fs__default.default.readJsonSync(packageJsonPath);
1418
- if (packageJson.workspaces || fs__default.default.existsSync(path8__default.default.join(currentDir, "src/themes")) || fs__default.default.existsSync(path8__default.default.join(currentDir, "themes"))) {
1420
+ if (packageJson.workspaces || fs__default.default.existsSync(path9__default.default.join(currentDir, "src/themes")) || fs__default.default.existsSync(path9__default.default.join(currentDir, "themes"))) {
1419
1421
  return currentDir;
1420
1422
  }
1421
1423
  }
1422
- currentDir = path8__default.default.dirname(currentDir);
1424
+ currentDir = path9__default.default.dirname(currentDir);
1423
1425
  }
1424
1426
  return process.cwd();
1425
1427
  }
1426
1428
  function getThemesDir() {
1427
1429
  const root = getProjectRoot();
1428
- if (fs__default.default.existsSync(path8__default.default.join(root, "themes")))
1429
- return path8__default.default.join(root, "themes");
1430
- if (fs__default.default.existsSync(path8__default.default.join(root, "src/themes")))
1431
- return path8__default.default.join(root, "src/themes");
1432
- return path8__default.default.dirname(root);
1430
+ if (fs__default.default.existsSync(path9__default.default.join(root, "themes")))
1431
+ return path9__default.default.join(root, "themes");
1432
+ if (fs__default.default.existsSync(path9__default.default.join(root, "src/themes")))
1433
+ return path9__default.default.join(root, "src/themes");
1434
+ return path9__default.default.dirname(root);
1433
1435
  }
1434
1436
  function getFeaturesDir() {
1435
- return path8__default.default.join(getProjectRoot(), "src/features");
1437
+ return path9__default.default.join(getProjectRoot(), "src/features");
1436
1438
  }
1437
1439
  function isOneXProject() {
1438
1440
  const root = getProjectRoot();
1439
- return fs__default.default.existsSync(path8__default.default.join(root, "themes")) || fs__default.default.existsSync(path8__default.default.join(root, "src/themes")) || fs__default.default.existsSync(path8__default.default.join(root, "theme.config.ts")) || fs__default.default.existsSync(path8__default.default.join(root, "bundle-entry.ts"));
1441
+ return fs__default.default.existsSync(path9__default.default.join(root, "themes")) || fs__default.default.existsSync(path9__default.default.join(root, "src/themes")) || fs__default.default.existsSync(path9__default.default.join(root, "theme.config.ts")) || fs__default.default.existsSync(path9__default.default.join(root, "bundle-entry.ts"));
1440
1442
  }
1441
1443
  function ensureOneXProject() {
1442
1444
  if (!isOneXProject()) {
@@ -1452,13 +1454,13 @@ function listThemes() {
1452
1454
  return [];
1453
1455
  }
1454
1456
  return fs__default.default.readdirSync(themesDir).filter((name) => {
1455
- const themePath = path8__default.default.join(themesDir, name);
1456
- return fs__default.default.statSync(themePath).isDirectory() && (fs__default.default.existsSync(path8__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path8__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path8__default.default.join(themePath, "manifest.ts")));
1457
+ const themePath = path9__default.default.join(themesDir, name);
1458
+ return fs__default.default.statSync(themePath).isDirectory() && (fs__default.default.existsSync(path9__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path9__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path9__default.default.join(themePath, "manifest.ts")));
1457
1459
  });
1458
1460
  }
1459
1461
  function themeExists(themeName) {
1460
- const themePath = path8__default.default.join(getThemesDir(), themeName);
1461
- return fs__default.default.existsSync(themePath) && (fs__default.default.existsSync(path8__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path8__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path8__default.default.join(themePath, "manifest.ts")));
1462
+ const themePath = path9__default.default.join(getThemesDir(), themeName);
1463
+ return fs__default.default.existsSync(themePath) && (fs__default.default.existsSync(path9__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path9__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path9__default.default.join(themePath, "manifest.ts")));
1462
1464
  }
1463
1465
  function detectPackageManager() {
1464
1466
  const userAgent = process.env.npm_config_user_agent || "";
@@ -1466,9 +1468,9 @@ function detectPackageManager() {
1466
1468
  if (userAgent.includes("yarn")) return "yarn";
1467
1469
  if (userAgent.includes("bun")) return "bun";
1468
1470
  const cwd = process.cwd();
1469
- if (fs__default.default.existsSync(path8__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
1470
- if (fs__default.default.existsSync(path8__default.default.join(cwd, "yarn.lock"))) return "yarn";
1471
- if (fs__default.default.existsSync(path8__default.default.join(cwd, "bun.lockb"))) return "bun";
1471
+ if (fs__default.default.existsSync(path9__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
1472
+ if (fs__default.default.existsSync(path9__default.default.join(cwd, "yarn.lock"))) return "yarn";
1473
+ if (fs__default.default.existsSync(path9__default.default.join(cwd, "bun.lockb"))) return "bun";
1472
1474
  return "npm";
1473
1475
  }
1474
1476
  async function installDependencies(projectPath, packageManager = "npm") {
@@ -1517,6 +1519,120 @@ function getValidCategories() {
1517
1519
  "contact"
1518
1520
  ];
1519
1521
  }
1522
+ var AUTH_DIR = path9__default.default.join(os__default.default.homedir(), ".onexthm");
1523
+ var AUTH_FILE = path9__default.default.join(AUTH_DIR, "auth.json");
1524
+ function getApiUrl() {
1525
+ return process.env.ONEXTHM_API_URL || process.env.NEXT_PUBLIC_API_URL || "https://platform-dev.onexeos.com";
1526
+ }
1527
+ async function saveAuthTokens(tokens) {
1528
+ await fs__default.default.ensureDir(AUTH_DIR);
1529
+ const key = getMachineKey();
1530
+ const data = JSON.stringify(tokens);
1531
+ const encrypted = encrypt(data, key);
1532
+ await fs__default.default.writeFile(AUTH_FILE, encrypted, "utf-8");
1533
+ }
1534
+ function loadAuthTokens() {
1535
+ try {
1536
+ if (!fs__default.default.existsSync(AUTH_FILE)) return null;
1537
+ const encrypted = fs__default.default.readFileSync(AUTH_FILE, "utf-8");
1538
+ const key = getMachineKey();
1539
+ const data = decrypt(encrypted, key);
1540
+ return JSON.parse(data);
1541
+ } catch {
1542
+ return null;
1543
+ }
1544
+ }
1545
+ async function clearAuthTokens() {
1546
+ try {
1547
+ await fs__default.default.remove(AUTH_FILE);
1548
+ } catch {
1549
+ }
1550
+ }
1551
+ function isTokenExpired(tokens) {
1552
+ return Date.now() / 1e3 > tokens.expiresAt - 60;
1553
+ }
1554
+ async function getValidTokens() {
1555
+ const tokens = loadAuthTokens();
1556
+ if (!tokens) return null;
1557
+ if (!isTokenExpired(tokens)) return tokens;
1558
+ try {
1559
+ const apiUrl = getApiUrl();
1560
+ const response = await fetch(`${apiUrl}/auth/refresh`, {
1561
+ method: "POST",
1562
+ headers: { "Content-Type": "application/json" },
1563
+ body: JSON.stringify({ refresh_token: tokens.refreshToken })
1564
+ });
1565
+ if (!response.ok) {
1566
+ await clearAuthTokens();
1567
+ return null;
1568
+ }
1569
+ const data = await response.json();
1570
+ const body = data.statusCode ? data.body : data;
1571
+ const refreshed = {
1572
+ ...tokens,
1573
+ accessToken: body.AccessToken || tokens.accessToken,
1574
+ idToken: body.IdToken || tokens.idToken,
1575
+ expiresAt: Math.floor(Date.now() / 1e3) + (body.ExpiresIn || 3600)
1576
+ };
1577
+ await saveAuthTokens(refreshed);
1578
+ return refreshed;
1579
+ } catch {
1580
+ await clearAuthTokens();
1581
+ return null;
1582
+ }
1583
+ }
1584
+ async function authenticatedFetch(url, init) {
1585
+ const tokens = await getValidTokens();
1586
+ if (!tokens) {
1587
+ throw new Error("Not logged in. Run: onexthm login");
1588
+ }
1589
+ const headers = new Headers(init?.headers);
1590
+ headers.set("Authorization", `Bearer ${tokens.idToken}`);
1591
+ headers.set("Content-Type", "application/json");
1592
+ return fetch(url, { ...init, headers });
1593
+ }
1594
+ function getMachineKey() {
1595
+ let seed;
1596
+ if (process.platform === "darwin") {
1597
+ seed = `onexthm:${os__default.default.hostname()}:${os__default.default.userInfo().username}`;
1598
+ } else if (process.platform === "linux") {
1599
+ try {
1600
+ seed = `onexthm:${fs__default.default.readFileSync("/etc/machine-id", "utf-8").trim()}`;
1601
+ } catch {
1602
+ seed = `onexthm:${os__default.default.hostname()}:${os__default.default.userInfo().username}`;
1603
+ }
1604
+ } else {
1605
+ seed = `onexthm:${os__default.default.hostname()}:${os__default.default.userInfo().username}`;
1606
+ }
1607
+ return crypto__default.default.createHash("sha256").update(seed).digest();
1608
+ }
1609
+ function encrypt(text, key) {
1610
+ const iv = crypto__default.default.randomBytes(16);
1611
+ const cipher = crypto__default.default.createCipheriv("aes-256-gcm", key, iv);
1612
+ let encrypted = cipher.update(text, "utf-8", "hex");
1613
+ encrypted += cipher.final("hex");
1614
+ const tag = cipher.getAuthTag();
1615
+ return `${iv.toString("hex")}:${tag.toString("hex")}:${encrypted}`;
1616
+ }
1617
+ function decrypt(text, key) {
1618
+ const [ivHex, tagHex, encrypted] = text.split(":");
1619
+ const iv = Buffer.from(ivHex, "hex");
1620
+ const tag = Buffer.from(tagHex, "hex");
1621
+ const decipher = crypto__default.default.createDecipheriv("aes-256-gcm", key, iv);
1622
+ decipher.setAuthTag(tag);
1623
+ let decrypted = decipher.update(encrypted, "hex", "utf-8");
1624
+ decrypted += decipher.final("utf-8");
1625
+ return decrypted;
1626
+ }
1627
+ function parseJwtClaims(idToken) {
1628
+ try {
1629
+ const payload = idToken.split(".")[1];
1630
+ const decoded = Buffer.from(payload, "base64url").toString("utf-8");
1631
+ return JSON.parse(decoded);
1632
+ } catch {
1633
+ return {};
1634
+ }
1635
+ }
1520
1636
 
1521
1637
  // src/commands/init.ts
1522
1638
  async function initCommand(projectName, options = {}) {
@@ -1534,7 +1650,7 @@ async function initCommand(projectName, options = {}) {
1534
1650
  if (!validateThemeName(kebabName)) {
1535
1651
  return "Invalid project name. Use lowercase letters, numbers, and hyphens only.";
1536
1652
  }
1537
- if (fs2__default.default.existsSync(path8__default.default.join(process.cwd(), kebabName))) {
1653
+ if (fs3__default.default.existsSync(path9__default.default.join(process.cwd(), kebabName))) {
1538
1654
  return `Directory "${kebabName}" already exists`;
1539
1655
  }
1540
1656
  return true;
@@ -1545,11 +1661,46 @@ async function initCommand(projectName, options = {}) {
1545
1661
  } else {
1546
1662
  name = toKebabCase(projectName);
1547
1663
  }
1548
- const projectPath = path8__default.default.join(process.cwd(), name);
1549
- if (fs2__default.default.existsSync(projectPath)) {
1664
+ const projectPath = path9__default.default.join(process.cwd(), name);
1665
+ if (fs3__default.default.existsSync(projectPath)) {
1550
1666
  logger.error(`Directory "${name}" already exists.`);
1551
1667
  process.exit(1);
1552
1668
  }
1669
+ if (!options.yes) {
1670
+ try {
1671
+ const apiUrl = getApiUrl();
1672
+ const controller = new AbortController();
1673
+ const timeout = setTimeout(() => controller.abort(), 3e3);
1674
+ const response = await fetch(
1675
+ `${apiUrl}/website-api/themes/${encodeURIComponent(name)}/exists`,
1676
+ { signal: controller.signal }
1677
+ );
1678
+ clearTimeout(timeout);
1679
+ if (response.ok) {
1680
+ const data2 = await response.json();
1681
+ const body = data2.statusCode ? data2.body : data2;
1682
+ if (body.exists && body.owner === "other") {
1683
+ logger.warning(
1684
+ `Theme ID "${name}" is already registered by another developer.
1685
+ You can still create this locally, but publishing will fail.
1686
+ Consider using a different name.`
1687
+ );
1688
+ const { proceed } = await inquirer__default.default.prompt([
1689
+ {
1690
+ type: "confirm",
1691
+ name: "proceed",
1692
+ message: "Continue anyway?",
1693
+ default: false
1694
+ }
1695
+ ]);
1696
+ if (!proceed) {
1697
+ process.exit(0);
1698
+ }
1699
+ }
1700
+ }
1701
+ } catch {
1702
+ }
1703
+ }
1553
1704
  let displayName;
1554
1705
  let description;
1555
1706
  let author;
@@ -1617,7 +1768,7 @@ async function initCommand(projectName, options = {}) {
1617
1768
  }
1618
1769
  logger.startSpinner("Creating project structure...");
1619
1770
  try {
1620
- fs2__default.default.mkdirSync(projectPath, { recursive: true });
1771
+ fs3__default.default.mkdirSync(projectPath, { recursive: true });
1621
1772
  await copyTemplate(template, projectPath, data);
1622
1773
  await renameThemeInFiles(
1623
1774
  projectPath,
@@ -1626,9 +1777,9 @@ async function initCommand(projectName, options = {}) {
1626
1777
  description,
1627
1778
  author
1628
1779
  );
1629
- const mcpJsonPath = path8__default.default.join(projectPath, ".mcp.json");
1630
- if (fs2__default.default.existsSync(mcpJsonPath)) {
1631
- let mcpContent = fs2__default.default.readFileSync(mcpJsonPath, "utf-8");
1780
+ const mcpJsonPath = path9__default.default.join(projectPath, ".mcp.json");
1781
+ if (fs3__default.default.existsSync(mcpJsonPath)) {
1782
+ let mcpContent = fs3__default.default.readFileSync(mcpJsonPath, "utf-8");
1632
1783
  if (figmaApiKey) {
1633
1784
  mcpContent = mcpContent.replace("__FIGMA_API_KEY__", figmaApiKey);
1634
1785
  } else {
@@ -1639,7 +1790,7 @@ async function initCommand(projectName, options = {}) {
1639
1790
  } catch {
1640
1791
  }
1641
1792
  }
1642
- fs2__default.default.writeFileSync(mcpJsonPath, mcpContent, "utf-8");
1793
+ fs3__default.default.writeFileSync(mcpJsonPath, mcpContent, "utf-8");
1643
1794
  }
1644
1795
  logger.stopSpinner(true, "Project structure created!");
1645
1796
  if (options.git) {
@@ -1699,16 +1850,16 @@ async function initCommand(projectName, options = {}) {
1699
1850
  logger.error(
1700
1851
  error instanceof Error ? error.message : "Unknown error occurred"
1701
1852
  );
1702
- if (fs2__default.default.existsSync(projectPath)) {
1703
- fs2__default.default.rmSync(projectPath, { recursive: true, force: true });
1853
+ if (fs3__default.default.existsSync(projectPath)) {
1854
+ fs3__default.default.rmSync(projectPath, { recursive: true, force: true });
1704
1855
  }
1705
1856
  process.exit(1);
1706
1857
  }
1707
1858
  }
1708
1859
  async function renameThemeInFiles(projectPath, themeName, displayName, description, author) {
1709
- const configPath = path8__default.default.join(projectPath, "theme.config.ts");
1710
- if (fs2__default.default.existsSync(configPath)) {
1711
- let content = fs2__default.default.readFileSync(configPath, "utf-8");
1860
+ const configPath = path9__default.default.join(projectPath, "theme.config.ts");
1861
+ if (fs3__default.default.existsSync(configPath)) {
1862
+ let content = fs3__default.default.readFileSync(configPath, "utf-8");
1712
1863
  content = content.replace(
1713
1864
  /name: "My Simple Theme"/,
1714
1865
  `name: "${displayName}"`
@@ -1717,11 +1868,11 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
1717
1868
  /description: ".*?"/,
1718
1869
  `description: "${description}"`
1719
1870
  );
1720
- fs2__default.default.writeFileSync(configPath, content, "utf-8");
1871
+ fs3__default.default.writeFileSync(configPath, content, "utf-8");
1721
1872
  }
1722
- const pkgPath = path8__default.default.join(projectPath, "package.json");
1723
- if (fs2__default.default.existsSync(pkgPath)) {
1724
- let content = fs2__default.default.readFileSync(pkgPath, "utf-8");
1873
+ const pkgPath = path9__default.default.join(projectPath, "package.json");
1874
+ if (fs3__default.default.existsSync(pkgPath)) {
1875
+ let content = fs3__default.default.readFileSync(pkgPath, "utf-8");
1725
1876
  content = content.replace(
1726
1877
  /@onex-themes\/my-simple/g,
1727
1878
  `@onex-themes/${themeName}`
@@ -1730,7 +1881,7 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
1730
1881
  /"description": ".*?"/,
1731
1882
  `"description": "${description}"`
1732
1883
  );
1733
- fs2__default.default.writeFileSync(pkgPath, content, "utf-8");
1884
+ fs3__default.default.writeFileSync(pkgPath, content, "utf-8");
1734
1885
  }
1735
1886
  }
1736
1887
 
@@ -1741,10 +1892,10 @@ async function createSectionCommand(name, options) {
1741
1892
  ensureOneXProject();
1742
1893
  if (!options.theme) {
1743
1894
  const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
1744
- (f) => fs__default.default.existsSync(path8__default.default.join(process.cwd(), f))
1895
+ (f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f))
1745
1896
  );
1746
1897
  if (isStandaloneTheme) {
1747
- options.theme = path8__default.default.basename(process.cwd());
1898
+ options.theme = path9__default.default.basename(process.cwd());
1748
1899
  }
1749
1900
  }
1750
1901
  const sectionName = toKebabCase(name);
@@ -1807,35 +1958,35 @@ async function createSectionCommand(name, options) {
1807
1958
  };
1808
1959
  logger.startSpinner("Creating section files...");
1809
1960
  try {
1810
- const themePath = path8__default.default.join(getThemesDir(), themeName);
1811
- const sectionPath = path8__default.default.join(themePath, "sections", sectionName);
1961
+ const themePath = path9__default.default.join(getThemesDir(), themeName);
1962
+ const sectionPath = path9__default.default.join(themePath, "sections", sectionName);
1812
1963
  const schemaContent = generateSectionSchema(data);
1813
1964
  await writeFile(
1814
- path8__default.default.join(sectionPath, `${sectionName}.schema.ts`),
1965
+ path9__default.default.join(sectionPath, `${sectionName}.schema.ts`),
1815
1966
  schemaContent
1816
1967
  );
1817
1968
  if (createTemplate) {
1818
1969
  const templateContent = generateSectionTemplate(data);
1819
1970
  await writeFile(
1820
- path8__default.default.join(sectionPath, `${sectionName}-default.tsx`),
1971
+ path9__default.default.join(sectionPath, `${sectionName}-default.tsx`),
1821
1972
  templateContent
1822
1973
  );
1823
1974
  }
1824
1975
  const indexContent = generateSectionIndex(data, createTemplate);
1825
- await writeFile(path8__default.default.join(sectionPath, "index.ts"), indexContent);
1976
+ await writeFile(path9__default.default.join(sectionPath, "index.ts"), indexContent);
1826
1977
  logger.stopSpinner(true, "Section files created successfully!");
1827
1978
  logger.newLine();
1828
1979
  logger.section("Next steps:");
1829
1980
  logger.log(
1830
- ` 1. Edit schema: ${path8__default.default.relative(process.cwd(), path8__default.default.join(sectionPath, `${sectionName}.schema.ts`))}`
1981
+ ` 1. Edit schema: ${path9__default.default.relative(process.cwd(), path9__default.default.join(sectionPath, `${sectionName}.schema.ts`))}`
1831
1982
  );
1832
1983
  if (createTemplate) {
1833
1984
  logger.log(
1834
- ` 2. Edit template: ${path8__default.default.relative(process.cwd(), path8__default.default.join(sectionPath, `${sectionName}-default.tsx`))}`
1985
+ ` 2. Edit template: ${path9__default.default.relative(process.cwd(), path9__default.default.join(sectionPath, `${sectionName}-default.tsx`))}`
1835
1986
  );
1836
1987
  }
1837
1988
  logger.log(
1838
- ` 3. Add to theme manifest: ${path8__default.default.relative(process.cwd(), path8__default.default.join(themePath, "manifest.ts"))}`
1989
+ ` 3. Add to theme manifest: ${path9__default.default.relative(process.cwd(), path9__default.default.join(themePath, "manifest.ts"))}`
1839
1990
  );
1840
1991
  logger.newLine();
1841
1992
  logger.success("Section created successfully!");
@@ -1983,10 +2134,10 @@ async function createBlockCommand(name, options) {
1983
2134
  ensureOneXProject();
1984
2135
  if (!options.theme) {
1985
2136
  const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
1986
- (f) => fs__default.default.existsSync(path8__default.default.join(process.cwd(), f))
2137
+ (f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f))
1987
2138
  );
1988
2139
  if (isStandaloneTheme) {
1989
- options.theme = path8__default.default.basename(process.cwd());
2140
+ options.theme = path9__default.default.basename(process.cwd());
1990
2141
  }
1991
2142
  }
1992
2143
  const blockName = toKebabCase(name);
@@ -2061,24 +2212,24 @@ async function createBlockCommand(name, options) {
2061
2212
  };
2062
2213
  logger.startSpinner("Creating block files...");
2063
2214
  try {
2064
- const blockPath = scope === "shared" ? path8__default.default.join(getFeaturesDir(), "blocks", blockName) : path8__default.default.join(getThemesDir(), themeName, "blocks", blockName);
2215
+ const blockPath = scope === "shared" ? path9__default.default.join(getFeaturesDir(), "blocks", blockName) : path9__default.default.join(getThemesDir(), themeName, "blocks", blockName);
2065
2216
  const schemaContent = generateBlockSchema(data);
2066
2217
  await writeFile(
2067
- path8__default.default.join(blockPath, `${blockName}.schema.ts`),
2218
+ path9__default.default.join(blockPath, `${blockName}.schema.ts`),
2068
2219
  schemaContent
2069
2220
  );
2070
2221
  const componentContent = generateBlockComponent(data);
2071
- await writeFile(path8__default.default.join(blockPath, `${blockName}.tsx`), componentContent);
2222
+ await writeFile(path9__default.default.join(blockPath, `${blockName}.tsx`), componentContent);
2072
2223
  const indexContent = generateBlockIndex(data);
2073
- await writeFile(path8__default.default.join(blockPath, "index.ts"), indexContent);
2224
+ await writeFile(path9__default.default.join(blockPath, "index.ts"), indexContent);
2074
2225
  logger.stopSpinner(true, "Block files created successfully!");
2075
2226
  logger.newLine();
2076
2227
  logger.section("Next steps:");
2077
2228
  logger.log(
2078
- ` 1. Edit schema: ${path8__default.default.relative(process.cwd(), path8__default.default.join(blockPath, `${blockName}.schema.ts`))}`
2229
+ ` 1. Edit schema: ${path9__default.default.relative(process.cwd(), path9__default.default.join(blockPath, `${blockName}.schema.ts`))}`
2079
2230
  );
2080
2231
  logger.log(
2081
- ` 2. Edit component: ${path8__default.default.relative(process.cwd(), path8__default.default.join(blockPath, `${blockName}.tsx`))}`
2232
+ ` 2. Edit component: ${path9__default.default.relative(process.cwd(), path9__default.default.join(blockPath, `${blockName}.tsx`))}`
2082
2233
  );
2083
2234
  logger.log(
2084
2235
  ` 3. Register in block registry: src/lib/registry/block-registry.ts`
@@ -2256,31 +2407,31 @@ async function createComponentCommand(name, options) {
2256
2407
  };
2257
2408
  logger.startSpinner("Creating component files...");
2258
2409
  try {
2259
- const componentPath = path8__default.default.join(
2410
+ const componentPath = path9__default.default.join(
2260
2411
  getFeaturesDir(),
2261
2412
  "components",
2262
2413
  componentName
2263
2414
  );
2264
2415
  const schemaContent = generateComponentSchema(data);
2265
2416
  await writeFile(
2266
- path8__default.default.join(componentPath, `${componentName}.schema.ts`),
2417
+ path9__default.default.join(componentPath, `${componentName}.schema.ts`),
2267
2418
  schemaContent
2268
2419
  );
2269
2420
  const componentContent = generateComponent(data);
2270
2421
  await writeFile(
2271
- path8__default.default.join(componentPath, `${componentName}.tsx`),
2422
+ path9__default.default.join(componentPath, `${componentName}.tsx`),
2272
2423
  componentContent
2273
2424
  );
2274
2425
  const indexContent = generateComponentIndex(data);
2275
- await writeFile(path8__default.default.join(componentPath, "index.ts"), indexContent);
2426
+ await writeFile(path9__default.default.join(componentPath, "index.ts"), indexContent);
2276
2427
  logger.stopSpinner(true, "Component files created successfully!");
2277
2428
  logger.newLine();
2278
2429
  logger.section("Next steps:");
2279
2430
  logger.log(
2280
- ` 1. Edit schema: ${path8__default.default.relative(process.cwd(), path8__default.default.join(componentPath, `${componentName}.schema.ts`))}`
2431
+ ` 1. Edit schema: ${path9__default.default.relative(process.cwd(), path9__default.default.join(componentPath, `${componentName}.schema.ts`))}`
2281
2432
  );
2282
2433
  logger.log(
2283
- ` 2. Edit component: ${path8__default.default.relative(process.cwd(), path8__default.default.join(componentPath, `${componentName}.tsx`))}`
2434
+ ` 2. Edit component: ${path9__default.default.relative(process.cwd(), path9__default.default.join(componentPath, `${componentName}.tsx`))}`
2284
2435
  );
2285
2436
  logger.log(
2286
2437
  ` 3. Register in component registry: src/lib/registry/component-registry.ts`
@@ -2437,13 +2588,13 @@ async function listSections(themeFilter) {
2437
2588
  return;
2438
2589
  }
2439
2590
  for (const theme of themes) {
2440
- const sectionsDir = path8__default.default.join(getThemesDir(), theme, "sections");
2591
+ const sectionsDir = path9__default.default.join(getThemesDir(), theme, "sections");
2441
2592
  if (!fs__default.default.existsSync(sectionsDir)) {
2442
2593
  continue;
2443
2594
  }
2444
2595
  const sections = fs__default.default.readdirSync(sectionsDir).filter((name) => {
2445
- const sectionPath = path8__default.default.join(sectionsDir, name);
2446
- return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(path8__default.default.join(sectionPath, "index.ts"));
2596
+ const sectionPath = path9__default.default.join(sectionsDir, name);
2597
+ return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(path9__default.default.join(sectionPath, "index.ts"));
2447
2598
  });
2448
2599
  if (sections.length > 0) {
2449
2600
  logger.log(chalk4__default.default.cyan(`
@@ -2457,11 +2608,11 @@ async function listSections(themeFilter) {
2457
2608
  }
2458
2609
  async function listBlocks(themeFilter) {
2459
2610
  logger.section("\u{1F9F1} Blocks");
2460
- const sharedBlocksDir = path8__default.default.join(getFeaturesDir(), "blocks");
2611
+ const sharedBlocksDir = path9__default.default.join(getFeaturesDir(), "blocks");
2461
2612
  if (fs__default.default.existsSync(sharedBlocksDir)) {
2462
2613
  const sharedBlocks = fs__default.default.readdirSync(sharedBlocksDir).filter((name) => {
2463
- const blockPath = path8__default.default.join(sharedBlocksDir, name);
2464
- return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path8__default.default.join(blockPath, "index.ts"));
2614
+ const blockPath = path9__default.default.join(sharedBlocksDir, name);
2615
+ return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path9__default.default.join(blockPath, "index.ts"));
2465
2616
  });
2466
2617
  if (sharedBlocks.length > 0) {
2467
2618
  logger.log(chalk4__default.default.cyan("\n Shared:"));
@@ -2472,13 +2623,13 @@ async function listBlocks(themeFilter) {
2472
2623
  }
2473
2624
  const themes = themeFilter ? [themeFilter] : listThemes();
2474
2625
  for (const theme of themes) {
2475
- const blocksDir = path8__default.default.join(getThemesDir(), theme, "blocks");
2626
+ const blocksDir = path9__default.default.join(getThemesDir(), theme, "blocks");
2476
2627
  if (!fs__default.default.existsSync(blocksDir)) {
2477
2628
  continue;
2478
2629
  }
2479
2630
  const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => {
2480
- const blockPath = path8__default.default.join(blocksDir, name);
2481
- return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path8__default.default.join(blockPath, "index.ts"));
2631
+ const blockPath = path9__default.default.join(blocksDir, name);
2632
+ return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path9__default.default.join(blockPath, "index.ts"));
2482
2633
  });
2483
2634
  if (blocks.length > 0) {
2484
2635
  logger.log(chalk4__default.default.cyan(`
@@ -2492,14 +2643,14 @@ async function listBlocks(themeFilter) {
2492
2643
  }
2493
2644
  async function listComponents() {
2494
2645
  logger.section("\u2699\uFE0F Components");
2495
- const componentsDir = path8__default.default.join(getFeaturesDir(), "components");
2646
+ const componentsDir = path9__default.default.join(getFeaturesDir(), "components");
2496
2647
  if (!fs__default.default.existsSync(componentsDir)) {
2497
2648
  logger.warning("No components directory found");
2498
2649
  return;
2499
2650
  }
2500
2651
  const components = fs__default.default.readdirSync(componentsDir).filter((name) => {
2501
- const componentPath = path8__default.default.join(componentsDir, name);
2502
- return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(path8__default.default.join(componentPath, "index.ts"));
2652
+ const componentPath = path9__default.default.join(componentsDir, name);
2653
+ return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(path9__default.default.join(componentPath, "index.ts"));
2503
2654
  });
2504
2655
  if (components.length === 0) {
2505
2656
  logger.warning("No components found");
@@ -2520,11 +2671,11 @@ async function listThemesInfo() {
2520
2671
  }
2521
2672
  logger.log("");
2522
2673
  for (const theme of themes) {
2523
- const themeDir = path8__default.default.join(getThemesDir(), theme);
2674
+ const themeDir = path9__default.default.join(getThemesDir(), theme);
2524
2675
  const candidates = ["theme.config.ts", "bundle-entry.ts", "manifest.ts"];
2525
2676
  let manifestContent = "";
2526
2677
  for (const candidate of candidates) {
2527
- const candidatePath = path8__default.default.join(themeDir, candidate);
2678
+ const candidatePath = path9__default.default.join(themeDir, candidate);
2528
2679
  if (fs__default.default.existsSync(candidatePath)) {
2529
2680
  manifestContent = fs__default.default.readFileSync(candidatePath, "utf-8");
2530
2681
  break;
@@ -2562,9 +2713,9 @@ async function validateCommand(options) {
2562
2713
  "theme.config.ts",
2563
2714
  "bundle-entry.ts",
2564
2715
  "manifest.ts"
2565
- ].some((f) => fs__default.default.existsSync(path8__default.default.join(process.cwd(), f)));
2716
+ ].some((f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f)));
2566
2717
  if (isThemeDir) {
2567
- themeToValidate = path8__default.default.basename(process.cwd());
2718
+ themeToValidate = path9__default.default.basename(process.cwd());
2568
2719
  logger.info(`Validating current theme: ${themeToValidate}`);
2569
2720
  } else {
2570
2721
  logger.error(
@@ -2573,11 +2724,11 @@ async function validateCommand(options) {
2573
2724
  process.exit(1);
2574
2725
  }
2575
2726
  }
2576
- const themePath = path8__default.default.join(getThemesDir(), themeToValidate);
2727
+ const themePath = path9__default.default.join(getThemesDir(), themeToValidate);
2577
2728
  logger.startSpinner("Running validation checks...");
2578
2729
  const entryFiles = ["manifest.ts", "theme.config.ts", "bundle-entry.ts"];
2579
2730
  const foundEntry = entryFiles.find(
2580
- (f) => fs__default.default.existsSync(path8__default.default.join(themePath, f))
2731
+ (f) => fs__default.default.existsSync(path9__default.default.join(themePath, f))
2581
2732
  );
2582
2733
  if (!foundEntry) {
2583
2734
  issues.push({
@@ -2587,7 +2738,7 @@ async function validateCommand(options) {
2587
2738
  });
2588
2739
  } else if (foundEntry === "manifest.ts") {
2589
2740
  const manifestContent = fs__default.default.readFileSync(
2590
- path8__default.default.join(themePath, foundEntry),
2741
+ path9__default.default.join(themePath, foundEntry),
2591
2742
  "utf-8"
2592
2743
  );
2593
2744
  if (!manifestContent.includes("export const") && !manifestContent.includes("export default") && !manifestContent.includes("export interface")) {
@@ -2598,7 +2749,7 @@ async function validateCommand(options) {
2598
2749
  });
2599
2750
  }
2600
2751
  }
2601
- const configPath = path8__default.default.join(themePath, "theme.config.ts");
2752
+ const configPath = path9__default.default.join(themePath, "theme.config.ts");
2602
2753
  if (!fs__default.default.existsSync(configPath)) {
2603
2754
  issues.push({
2604
2755
  type: "warning",
@@ -2606,7 +2757,7 @@ async function validateCommand(options) {
2606
2757
  message: "Theme config file not found (recommended)"
2607
2758
  });
2608
2759
  }
2609
- const indexPath = path8__default.default.join(themePath, "index.ts");
2760
+ const indexPath = path9__default.default.join(themePath, "index.ts");
2610
2761
  if (!fs__default.default.existsSync(indexPath)) {
2611
2762
  issues.push({
2612
2763
  type: "warning",
@@ -2614,7 +2765,7 @@ async function validateCommand(options) {
2614
2765
  message: "Index file not found (recommended)"
2615
2766
  });
2616
2767
  }
2617
- const sectionsDir = path8__default.default.join(themePath, "sections");
2768
+ const sectionsDir = path9__default.default.join(themePath, "sections");
2618
2769
  if (!fs__default.default.existsSync(sectionsDir)) {
2619
2770
  issues.push({
2620
2771
  type: "warning",
@@ -2623,16 +2774,16 @@ async function validateCommand(options) {
2623
2774
  });
2624
2775
  } else {
2625
2776
  const sections = fs__default.default.readdirSync(sectionsDir).filter(
2626
- (name) => fs__default.default.statSync(path8__default.default.join(sectionsDir, name)).isDirectory()
2777
+ (name) => fs__default.default.statSync(path9__default.default.join(sectionsDir, name)).isDirectory()
2627
2778
  );
2628
2779
  for (const sectionName of sections) {
2629
- const sectionPath = path8__default.default.join(sectionsDir, sectionName);
2630
- const schemaFile = path8__default.default.join(sectionPath, `${sectionName}.schema.ts`);
2631
- const defaultTemplate = path8__default.default.join(
2780
+ const sectionPath = path9__default.default.join(sectionsDir, sectionName);
2781
+ const schemaFile = path9__default.default.join(sectionPath, `${sectionName}.schema.ts`);
2782
+ const defaultTemplate = path9__default.default.join(
2632
2783
  sectionPath,
2633
2784
  `${sectionName}-default.tsx`
2634
2785
  );
2635
- const indexFile = path8__default.default.join(sectionPath, "index.ts");
2786
+ const indexFile = path9__default.default.join(sectionPath, "index.ts");
2636
2787
  if (!fs__default.default.existsSync(schemaFile)) {
2637
2788
  issues.push({
2638
2789
  type: "error",
@@ -2656,14 +2807,14 @@ async function validateCommand(options) {
2656
2807
  }
2657
2808
  }
2658
2809
  }
2659
- const blocksDir = path8__default.default.join(themePath, "blocks");
2810
+ const blocksDir = path9__default.default.join(themePath, "blocks");
2660
2811
  if (fs__default.default.existsSync(blocksDir)) {
2661
- const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => fs__default.default.statSync(path8__default.default.join(blocksDir, name)).isDirectory());
2812
+ const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => fs__default.default.statSync(path9__default.default.join(blocksDir, name)).isDirectory());
2662
2813
  for (const blockName of blocks) {
2663
- const blockPath = path8__default.default.join(blocksDir, blockName);
2664
- const schemaFile = path8__default.default.join(blockPath, `${blockName}.schema.ts`);
2665
- const componentFile = path8__default.default.join(blockPath, `${blockName}.tsx`);
2666
- const indexFile = path8__default.default.join(blockPath, "index.ts");
2814
+ const blockPath = path9__default.default.join(blocksDir, blockName);
2815
+ const schemaFile = path9__default.default.join(blockPath, `${blockName}.schema.ts`);
2816
+ const componentFile = path9__default.default.join(blockPath, `${blockName}.tsx`);
2817
+ const indexFile = path9__default.default.join(blockPath, "index.ts");
2667
2818
  if (!fs__default.default.existsSync(schemaFile)) {
2668
2819
  issues.push({
2669
2820
  type: "error",
@@ -2689,13 +2840,13 @@ async function validateCommand(options) {
2689
2840
  }
2690
2841
  if (fs__default.default.existsSync(sectionsDir)) {
2691
2842
  const sections = fs__default.default.readdirSync(sectionsDir).filter(
2692
- (name) => fs__default.default.statSync(path8__default.default.join(sectionsDir, name)).isDirectory()
2843
+ (name) => fs__default.default.statSync(path9__default.default.join(sectionsDir, name)).isDirectory()
2693
2844
  );
2694
2845
  for (const sectionName of sections) {
2695
- const sectionPath = path8__default.default.join(sectionsDir, sectionName);
2846
+ const sectionPath = path9__default.default.join(sectionsDir, sectionName);
2696
2847
  const tsxFiles = fs__default.default.readdirSync(sectionPath).filter((f) => f.endsWith(".tsx") && !f.endsWith(".schema.ts"));
2697
2848
  for (const tsxFile of tsxFiles) {
2698
- const filePath = path8__default.default.join(sectionPath, tsxFile);
2849
+ const filePath = path9__default.default.join(sectionPath, tsxFile);
2699
2850
  const content = fs__default.default.readFileSync(filePath, "utf-8");
2700
2851
  const relPath = `sections/${sectionName}/${tsxFile}`;
2701
2852
  if (!content.includes('"use client"') && !content.includes("'use client'")) {
@@ -2743,23 +2894,46 @@ async function validateCommand(options) {
2743
2894
  }
2744
2895
  }
2745
2896
  }
2746
- const registryPath = path8__default.default.join(themePath, "sections-registry.ts");
2747
- const bundleEntryPath = path8__default.default.join(themePath, "bundle-entry.ts");
2897
+ const registryPath = path9__default.default.join(themePath, "sections-registry.ts");
2898
+ const bundleEntryPath = path9__default.default.join(themePath, "bundle-entry.ts");
2748
2899
  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") : "";
2749
2900
  if (fs__default.default.existsSync(sectionsDir) && registryContent) {
2750
2901
  const sections = fs__default.default.readdirSync(sectionsDir).filter(
2751
- (name) => fs__default.default.statSync(path8__default.default.join(sectionsDir, name)).isDirectory()
2902
+ (name) => fs__default.default.statSync(path9__default.default.join(sectionsDir, name)).isDirectory()
2752
2903
  );
2753
2904
  for (const sectionName of sections) {
2754
2905
  if (!registryContent.includes(`sections/${sectionName}`) && !registryContent.includes(`"${sectionName}"`)) {
2755
2906
  issues.push({
2756
- type: "warning",
2907
+ type: "error",
2757
2908
  file: `sections/${sectionName}/`,
2758
- message: "Section not found in sections-registry.ts or bundle-entry.ts \u2014 may not be included in build"
2909
+ message: "Section not exported in sections-registry.ts or bundle-entry.ts \u2014 will not be included in build"
2759
2910
  });
2760
2911
  }
2761
2912
  }
2762
2913
  }
2914
+ if (fs__default.default.existsSync(sectionsDir)) {
2915
+ const schemaTypes = await loadSchemaTypes(themePath, sectionsDir);
2916
+ for (const { folderName, schemaType } of schemaTypes) {
2917
+ if (schemaType && schemaType !== folderName) {
2918
+ issues.push({
2919
+ type: "error",
2920
+ file: `sections/${folderName}/${folderName}.schema.ts`,
2921
+ message: `Schema type "${schemaType}" doesn't match folder name "${folderName}". Rename folder to "${schemaType}/" or change schema type to "${folderName}".`
2922
+ });
2923
+ }
2924
+ }
2925
+ const pagesDir = path9__default.default.join(themePath, "pages");
2926
+ if (fs__default.default.existsSync(pagesDir)) {
2927
+ const allSchemaTypeSet = new Set(
2928
+ schemaTypes.map((s) => s.schemaType || s.folderName)
2929
+ );
2930
+ const pageIssues = await validatePageSectionTypes(
2931
+ pagesDir,
2932
+ allSchemaTypeSet
2933
+ );
2934
+ issues.push(...pageIssues);
2935
+ }
2936
+ }
2763
2937
  logger.stopSpinner(true, "Validation complete");
2764
2938
  const errors = issues.filter((i) => i.type === "error");
2765
2939
  const warnings = issues.filter((i) => i.type === "warning");
@@ -2798,6 +2972,116 @@ async function validateCommand(options) {
2798
2972
  }
2799
2973
  }
2800
2974
  }
2975
+ async function loadSchemaTypes(themePath, sectionsDir) {
2976
+ const results = [];
2977
+ const sections = fs__default.default.readdirSync(sectionsDir).filter((name) => fs__default.default.statSync(path9__default.default.join(sectionsDir, name)).isDirectory());
2978
+ for (const sectionName of sections) {
2979
+ const schemaFile = path9__default.default.join(
2980
+ sectionsDir,
2981
+ sectionName,
2982
+ `${sectionName}.schema.ts`
2983
+ );
2984
+ if (!fs__default.default.existsSync(schemaFile)) {
2985
+ results.push({ folderName: sectionName, schemaType: null });
2986
+ continue;
2987
+ }
2988
+ const content = fs__default.default.readFileSync(schemaFile, "utf-8");
2989
+ let schemaType = null;
2990
+ const schemaExportMatch = content.match(
2991
+ /:\s*SectionSchema\s*=\s*\{[\s\S]*?\btype:\s*["']([^"']+)["']/
2992
+ );
2993
+ if (schemaExportMatch) {
2994
+ schemaType = schemaExportMatch[1];
2995
+ } else {
2996
+ const allTypeMatches = [
2997
+ ...content.matchAll(/\btype:\s*["']([^"']+)["']/g)
2998
+ ];
2999
+ for (const m of allTypeMatches) {
3000
+ if (!FIELD_TYPES.has(m[1])) {
3001
+ schemaType = m[1];
3002
+ break;
3003
+ }
3004
+ }
3005
+ }
3006
+ results.push({
3007
+ folderName: sectionName,
3008
+ schemaType
3009
+ });
3010
+ }
3011
+ return results;
3012
+ }
3013
+ async function validatePageSectionTypes(pagesDir, validTypes) {
3014
+ const issues = [];
3015
+ const files = fs__default.default.readdirSync(pagesDir).filter((f) => f.match(/\.(ts|js)$/));
3016
+ for (const file of files) {
3017
+ const content = fs__default.default.readFileSync(path9__default.default.join(pagesDir, file), "utf-8");
3018
+ const pageName = file.replace(/\.(ts|js)$/, "");
3019
+ const sectionsMatch = content.match(/\bsections:\s*\[/);
3020
+ if (!sectionsMatch || sectionsMatch.index === void 0) continue;
3021
+ const startIdx = sectionsMatch.index + sectionsMatch[0].length;
3022
+ let depth = 1;
3023
+ let endIdx = startIdx;
3024
+ for (let i = startIdx; i < content.length && depth > 0; i++) {
3025
+ if (content[i] === "[") depth++;
3026
+ else if (content[i] === "]") depth--;
3027
+ endIdx = i;
3028
+ }
3029
+ const sectionsBlock = content.slice(startIdx, endIdx);
3030
+ const typeMatches = sectionsBlock.matchAll(/\btype:\s*["']([^"']+)["']/g);
3031
+ for (const match of typeMatches) {
3032
+ const sectionType = match[1];
3033
+ if (!validTypes.has(sectionType)) {
3034
+ issues.push({
3035
+ type: "error",
3036
+ file: `pages/${file}`,
3037
+ message: `Page "${pageName}" uses section type "${sectionType}" which doesn't exist in sections/`
3038
+ });
3039
+ }
3040
+ }
3041
+ }
3042
+ return issues;
3043
+ }
3044
+ var FIELD_TYPES = /* @__PURE__ */ new Set([
3045
+ "text",
3046
+ "textarea",
3047
+ "richtext",
3048
+ "number",
3049
+ "range",
3050
+ "toggle",
3051
+ "switch",
3052
+ "select",
3053
+ "radio",
3054
+ "checkbox",
3055
+ "color",
3056
+ "image",
3057
+ "video",
3058
+ "url",
3059
+ "link",
3060
+ "icon",
3061
+ "date",
3062
+ "datetime",
3063
+ "collection",
3064
+ "product",
3065
+ "blog",
3066
+ "page",
3067
+ "html",
3068
+ "code",
3069
+ "json",
3070
+ "array",
3071
+ "object",
3072
+ "group",
3073
+ "section",
3074
+ "boolean",
3075
+ "color_token",
3076
+ "color_background",
3077
+ "image_picker",
3078
+ "video_url",
3079
+ "font",
3080
+ "font_picker",
3081
+ "text_alignment",
3082
+ "inline_richtext",
3083
+ "repeater"
3084
+ ]);
2801
3085
 
2802
3086
  // src/commands/build.ts
2803
3087
  init_logger();
@@ -2808,14 +3092,14 @@ async function buildCommand(options) {
2808
3092
  if (options.theme) {
2809
3093
  themeName = options.theme;
2810
3094
  try {
2811
- const workspaceThemePath = path8__default.default.join(getThemesDir(), themeName);
3095
+ const workspaceThemePath = path9__default.default.join(getThemesDir(), themeName);
2812
3096
  if (fs__default.default.existsSync(workspaceThemePath)) {
2813
3097
  themePath = workspaceThemePath;
2814
3098
  } else {
2815
- themePath = path8__default.default.join(process.cwd(), themeName);
3099
+ themePath = path9__default.default.join(process.cwd(), themeName);
2816
3100
  }
2817
3101
  } catch {
2818
- themePath = path8__default.default.join(process.cwd(), themeName);
3102
+ themePath = path9__default.default.join(process.cwd(), themeName);
2819
3103
  }
2820
3104
  if (!fs__default.default.existsSync(themePath)) {
2821
3105
  logger.error(`Theme "${themeName}" not found.`);
@@ -2826,10 +3110,10 @@ async function buildCommand(options) {
2826
3110
  "theme.config.ts",
2827
3111
  "bundle-entry.ts",
2828
3112
  "manifest.ts"
2829
- ].some((f) => fs__default.default.existsSync(path8__default.default.join(process.cwd(), f)));
3113
+ ].some((f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f)));
2830
3114
  if (isThemeDir) {
2831
3115
  themePath = process.cwd();
2832
- themeName = path8__default.default.basename(themePath);
3116
+ themeName = path9__default.default.basename(themePath);
2833
3117
  logger.info(`Building current theme: ${themeName}`);
2834
3118
  } else {
2835
3119
  logger.error(
@@ -2838,7 +3122,7 @@ async function buildCommand(options) {
2838
3122
  process.exit(1);
2839
3123
  }
2840
3124
  }
2841
- const packageJsonPath = path8__default.default.join(themePath, "package.json");
3125
+ const packageJsonPath = path9__default.default.join(themePath, "package.json");
2842
3126
  const hasPkgJson = fs__default.default.existsSync(packageJsonPath);
2843
3127
  if (!hasPkgJson) {
2844
3128
  logger.warning(
@@ -2894,9 +3178,9 @@ async function buildCommand(options) {
2894
3178
  logger.success("\u2713 Theme built successfully!");
2895
3179
  logger.newLine();
2896
3180
  logger.info(`Theme: ${themeName}`);
2897
- const distPath = path8__default.default.join(themePath, "dist");
3181
+ const distPath = path9__default.default.join(themePath, "dist");
2898
3182
  if (fs__default.default.existsSync(distPath)) {
2899
- logger.log(`Output: ${path8__default.default.relative(process.cwd(), distPath)}`);
3183
+ logger.log(`Output: ${path9__default.default.relative(process.cwd(), distPath)}`);
2900
3184
  const files = fs__default.default.readdirSync(distPath);
2901
3185
  logger.log(`Files: ${files.length}`);
2902
3186
  }
@@ -2952,7 +3236,7 @@ async function packageCommand(options) {
2952
3236
  let themeName;
2953
3237
  if (options.theme) {
2954
3238
  themeName = options.theme;
2955
- themePath = path8__default.default.join(getThemesDir(), themeName);
3239
+ themePath = path9__default.default.join(getThemesDir(), themeName);
2956
3240
  if (!fs__default.default.existsSync(themePath)) {
2957
3241
  logger.error(`Theme "${themeName}" not found.`);
2958
3242
  process.exit(1);
@@ -2962,10 +3246,10 @@ async function packageCommand(options) {
2962
3246
  "theme.config.ts",
2963
3247
  "bundle-entry.ts",
2964
3248
  "manifest.ts"
2965
- ].some((f) => fs__default.default.existsSync(path8__default.default.join(process.cwd(), f)));
3249
+ ].some((f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f)));
2966
3250
  if (isThemeDir) {
2967
3251
  themePath = process.cwd();
2968
- themeName = path8__default.default.basename(themePath);
3252
+ themeName = path9__default.default.basename(themePath);
2969
3253
  logger.info(`Packaging current theme: ${themeName}`);
2970
3254
  } else {
2971
3255
  logger.error(
@@ -2974,7 +3258,7 @@ async function packageCommand(options) {
2974
3258
  process.exit(1);
2975
3259
  }
2976
3260
  }
2977
- const packageJsonPath = path8__default.default.join(themePath, "package.json");
3261
+ const packageJsonPath = path9__default.default.join(themePath, "package.json");
2978
3262
  let version2 = "1.0.0";
2979
3263
  if (fs__default.default.existsSync(packageJsonPath)) {
2980
3264
  const packageJson = await fs__default.default.readJson(packageJsonPath);
@@ -2984,7 +3268,7 @@ async function packageCommand(options) {
2984
3268
  logger.info(`Theme: ${themeName}`);
2985
3269
  logger.info(`Version: ${version2}`);
2986
3270
  logger.newLine();
2987
- const compiledThemePath = path8__default.default.join(
3271
+ const compiledThemePath = path9__default.default.join(
2988
3272
  process.cwd(),
2989
3273
  "themes",
2990
3274
  themeName,
@@ -3018,8 +3302,8 @@ async function packageCommand(options) {
3018
3302
  logger.newLine();
3019
3303
  logger.section("Step 2: Create Package");
3020
3304
  const packageName = options.name || `${themeName}-${version2}`;
3021
- const outputDir = options.output || path8__default.default.join(process.cwd(), "dist");
3022
- const outputPath = path8__default.default.join(outputDir, `${packageName}.zip`);
3305
+ const outputDir = options.output || path9__default.default.join(process.cwd(), "dist");
3306
+ const outputPath = path9__default.default.join(outputDir, `${packageName}.zip`);
3023
3307
  await fs__default.default.ensureDir(outputDir);
3024
3308
  logger.startSpinner("Creating zip archive...");
3025
3309
  try {
@@ -3032,11 +3316,11 @@ async function packageCommand(options) {
3032
3316
  logger.newLine();
3033
3317
  logger.info(`Package: ${packageName}.zip`);
3034
3318
  logger.log(`Size: ${sizeMB} MB`);
3035
- logger.log(`Location: ${path8__default.default.relative(process.cwd(), outputPath)}`);
3319
+ logger.log(`Location: ${path9__default.default.relative(process.cwd(), outputPath)}`);
3036
3320
  logger.newLine();
3037
3321
  logger.section("Next steps:");
3038
3322
  logger.log(
3039
- ` onexthm deploy --package ${path8__default.default.relative(process.cwd(), outputPath)}`
3323
+ ` onexthm deploy --package ${path9__default.default.relative(process.cwd(), outputPath)}`
3040
3324
  );
3041
3325
  } catch (error) {
3042
3326
  logger.stopSpinner(false, "Failed to create package");
@@ -3094,9 +3378,9 @@ async function deployCommand(options) {
3094
3378
  ensureOneXProject();
3095
3379
  let packagePath;
3096
3380
  if (options.package) {
3097
- packagePath = path8__default.default.resolve(options.package);
3381
+ packagePath = path9__default.default.resolve(options.package);
3098
3382
  } else if (options.theme) {
3099
- const distDir = path8__default.default.join(process.cwd(), "dist");
3383
+ const distDir = path9__default.default.join(process.cwd(), "dist");
3100
3384
  if (!fs__default.default.existsSync(distDir)) {
3101
3385
  logger.error("No dist/ directory found. Run 'onexthm package' first.");
3102
3386
  process.exit(1);
@@ -3111,7 +3395,7 @@ async function deployCommand(options) {
3111
3395
  process.exit(1);
3112
3396
  }
3113
3397
  packageFiles.sort().reverse();
3114
- packagePath = path8__default.default.join(distDir, packageFiles[0]);
3398
+ packagePath = path9__default.default.join(distDir, packageFiles[0]);
3115
3399
  } else {
3116
3400
  logger.error("Either --package or --theme must be specified.");
3117
3401
  logger.info("Examples:");
@@ -3125,11 +3409,11 @@ async function deployCommand(options) {
3125
3409
  }
3126
3410
  const stats = await fs__default.default.stat(packagePath);
3127
3411
  const sizeMB = (stats.size / 1024 / 1024).toFixed(2);
3128
- const fileName = path8__default.default.basename(packagePath);
3412
+ const fileName = path9__default.default.basename(packagePath);
3129
3413
  logger.newLine();
3130
3414
  logger.info(`Package: ${fileName}`);
3131
3415
  logger.log(`Size: ${sizeMB} MB`);
3132
- logger.log(`Path: ${path8__default.default.relative(process.cwd(), packagePath)}`);
3416
+ logger.log(`Path: ${path9__default.default.relative(process.cwd(), packagePath)}`);
3133
3417
  logger.newLine();
3134
3418
  const apiUrl = options.apiUrl || process.env.ONEX_API_URL || "http://localhost:3001";
3135
3419
  const uploadEndpoint = `${apiUrl}/website-api/themes/upload`;
@@ -3233,11 +3517,11 @@ function getBucketName(env) {
3233
3517
  return environment === "production" ? "theme-s3-bucket" : "theme-s3-bucket";
3234
3518
  }
3235
3519
  async function findCompiledThemeDir(themeId, version2) {
3236
- const searchPaths = [path8__default.default.resolve(process.cwd(), "dist")];
3520
+ const searchPaths = [path9__default.default.resolve(process.cwd(), "dist")];
3237
3521
  for (const dir of searchPaths) {
3238
3522
  if (await fs__default.default.pathExists(dir)) {
3239
- const hasManifest = await fs__default.default.pathExists(path8__default.default.join(dir, "manifest.json"));
3240
- const hasThemeEntry = await fs__default.default.pathExists(path8__default.default.join(dir, "bundle-entry.js")) || await fs__default.default.pathExists(path8__default.default.join(dir, "theme.config.js")) || await fs__default.default.pathExists(path8__default.default.join(dir, "index.js"));
3523
+ const hasManifest = await fs__default.default.pathExists(path9__default.default.join(dir, "manifest.json"));
3524
+ const hasThemeEntry = await fs__default.default.pathExists(path9__default.default.join(dir, "bundle-entry.js")) || await fs__default.default.pathExists(path9__default.default.join(dir, "theme.config.js")) || await fs__default.default.pathExists(path9__default.default.join(dir, "index.js"));
3241
3525
  if (hasManifest || hasThemeEntry) {
3242
3526
  return dir;
3243
3527
  }
@@ -3246,7 +3530,7 @@ async function findCompiledThemeDir(themeId, version2) {
3246
3530
  return null;
3247
3531
  }
3248
3532
  async function readManifest() {
3249
- const manifestTsPath = path8__default.default.resolve(process.cwd(), "manifest.ts");
3533
+ const manifestTsPath = path9__default.default.resolve(process.cwd(), "manifest.ts");
3250
3534
  if (await fs__default.default.pathExists(manifestTsPath)) {
3251
3535
  try {
3252
3536
  const module = await import(manifestTsPath);
@@ -3255,7 +3539,7 @@ async function readManifest() {
3255
3539
  logger.warning("Failed to import manifest.ts, trying package.json");
3256
3540
  }
3257
3541
  }
3258
- const packageJsonPath = path8__default.default.resolve(process.cwd(), "package.json");
3542
+ const packageJsonPath = path9__default.default.resolve(process.cwd(), "package.json");
3259
3543
  if (await fs__default.default.pathExists(packageJsonPath)) {
3260
3544
  const pkg = await fs__default.default.readJson(packageJsonPath);
3261
3545
  return {
@@ -3289,13 +3573,13 @@ async function findSourceDir(themeId, explicitDir) {
3289
3573
  }
3290
3574
  const searchPaths = [
3291
3575
  process.cwd(),
3292
- path8__default.default.resolve(process.cwd(), `../../themes/${themeId}`),
3293
- path8__default.default.resolve(process.cwd(), `../themes/${themeId}`)
3576
+ path9__default.default.resolve(process.cwd(), `../../themes/${themeId}`),
3577
+ path9__default.default.resolve(process.cwd(), `../themes/${themeId}`)
3294
3578
  ];
3295
3579
  const markers = ["theme.config.ts", "bundle-entry.ts"];
3296
3580
  for (const dir of searchPaths) {
3297
3581
  for (const marker of markers) {
3298
- if (await fs__default.default.pathExists(path8__default.default.join(dir, marker))) {
3582
+ if (await fs__default.default.pathExists(path9__default.default.join(dir, marker))) {
3299
3583
  return dir;
3300
3584
  }
3301
3585
  }
@@ -3346,8 +3630,8 @@ async function uploadCommand(options) {
3346
3630
  }
3347
3631
  spinner.succeed(`Found compiled theme at: ${compiledDir}`);
3348
3632
  spinner.start("Creating bundle.zip...");
3349
- const tmpDir = os3__default.default.tmpdir();
3350
- const bundleZipPath = path8__default.default.join(tmpDir, `${themeId}-${version2}-bundle.zip`);
3633
+ const tmpDir = os__default.default.tmpdir();
3634
+ const bundleZipPath = path9__default.default.join(tmpDir, `${themeId}-${version2}-bundle.zip`);
3351
3635
  await createZipFromDir(compiledDir, bundleZipPath);
3352
3636
  const bundleZipBuffer = await fs__default.default.readFile(bundleZipPath);
3353
3637
  const bundleSizeMB = (bundleZipBuffer.length / 1024 / 1024).toFixed(2);
@@ -3401,7 +3685,7 @@ async function uploadCommand(options) {
3401
3685
  if (sourceDir) {
3402
3686
  spinner.succeed(`Found source at: ${sourceDir}`);
3403
3687
  spinner.start("Creating source.zip...");
3404
- const sourceZipPath = path8__default.default.join(
3688
+ const sourceZipPath = path9__default.default.join(
3405
3689
  tmpDir,
3406
3690
  `${themeId}-${version2}-source.zip`
3407
3691
  );
@@ -3535,8 +3819,8 @@ async function resolveLatestVersion(s3Client, bucket, themeId) {
3535
3819
  async function createCompatibilityFiles(outputDir, manifest) {
3536
3820
  const entryFile = manifest.output?.entry || "bundle-entry.js";
3537
3821
  if (entryFile !== "bundle-entry.js" && entryFile.startsWith("bundle-entry-")) {
3538
- const hashedPath = path8__default.default.join(outputDir, entryFile);
3539
- const stablePath = path8__default.default.join(outputDir, "bundle-entry.js");
3822
+ const hashedPath = path9__default.default.join(outputDir, entryFile);
3823
+ const stablePath = path9__default.default.join(outputDir, "bundle-entry.js");
3540
3824
  if (await fs__default.default.pathExists(hashedPath)) {
3541
3825
  await fs__default.default.copy(hashedPath, stablePath);
3542
3826
  const mapPath = hashedPath + ".map";
@@ -3545,13 +3829,13 @@ async function createCompatibilityFiles(outputDir, manifest) {
3545
3829
  }
3546
3830
  }
3547
3831
  }
3548
- const sectionsRegistryPath = path8__default.default.join(outputDir, "sections-registry.js");
3832
+ const sectionsRegistryPath = path9__default.default.join(outputDir, "sections-registry.js");
3549
3833
  const content = `// Re-export all sections from bundle-entry
3550
3834
  // This file exists to maintain compatibility with the import path
3551
3835
  export * from './bundle-entry.js';
3552
3836
  `;
3553
3837
  await fs__default.default.writeFile(sectionsRegistryPath, content, "utf-8");
3554
- const pkgJsonPath = path8__default.default.join(outputDir, "package.json");
3838
+ const pkgJsonPath = path9__default.default.join(outputDir, "package.json");
3555
3839
  await fs__default.default.writeFile(pkgJsonPath, '{\n "type": "module"\n}\n', "utf-8");
3556
3840
  }
3557
3841
  function showDownloadFailureHelp(themeId, bucket) {
@@ -3613,6 +3897,18 @@ async function downloadCommand(options) {
3613
3897
  spinner.succeed(
3614
3898
  `Resolved latest version: ${chalk4__default.default.cyan(resolvedVersion)}`
3615
3899
  );
3900
+ const isCI = !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.VERCEL);
3901
+ if (isCI) {
3902
+ console.log(
3903
+ chalk4__default.default.yellow(
3904
+ `
3905
+ Warning: Resolved "latest" to ${resolvedVersion} in CI environment.
3906
+ For production builds, pin to a specific version:
3907
+ THEME_VERSION=${resolvedVersion}
3908
+ `
3909
+ )
3910
+ );
3911
+ }
3616
3912
  }
3617
3913
  spinner.start(
3618
3914
  `Downloading bundle.zip for ${themeId}@${resolvedVersion}...`
@@ -3634,7 +3930,7 @@ async function downloadCommand(options) {
3634
3930
  zip.extractAllTo(outputDir, true);
3635
3931
  const entries = zip.getEntries().filter((e) => !e.isDirectory);
3636
3932
  spinner.succeed(`Extracted ${entries.length} files to ${outputDir}`);
3637
- const manifestPath = path8__default.default.join(outputDir, "manifest.json");
3933
+ const manifestPath = path9__default.default.join(outputDir, "manifest.json");
3638
3934
  const manifest = await fs__default.default.readJson(manifestPath);
3639
3935
  await createCompatibilityFiles(outputDir, manifest);
3640
3936
  console.log();
@@ -3768,7 +4064,7 @@ async function renameTheme(themeDir, oldName, newName) {
3768
4064
  const oldPrefix = `${oldName}-`;
3769
4065
  const newPrefix = `${newName}-`;
3770
4066
  const newDisplayName = newName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
3771
- const pkgPath = path8__default.default.join(themeDir, "package.json");
4067
+ const pkgPath = path9__default.default.join(themeDir, "package.json");
3772
4068
  if (await fs__default.default.pathExists(pkgPath)) {
3773
4069
  const pkg = await fs__default.default.readJson(pkgPath);
3774
4070
  pkg.name = `@onex-themes/${newName}`;
@@ -3784,7 +4080,7 @@ async function renameTheme(themeDir, oldName, newName) {
3784
4080
  }
3785
4081
  await fs__default.default.writeJson(pkgPath, pkg, { spaces: 2 });
3786
4082
  }
3787
- const configPath = path8__default.default.join(themeDir, "theme.config.ts");
4083
+ const configPath = path9__default.default.join(themeDir, "theme.config.ts");
3788
4084
  if (await fs__default.default.pathExists(configPath)) {
3789
4085
  let content = await fs__default.default.readFile(configPath, "utf-8");
3790
4086
  content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
@@ -3794,7 +4090,7 @@ async function renameTheme(themeDir, oldName, newName) {
3794
4090
  );
3795
4091
  await fs__default.default.writeFile(configPath, content);
3796
4092
  }
3797
- const layoutPath = path8__default.default.join(themeDir, "theme.layout.ts");
4093
+ const layoutPath = path9__default.default.join(themeDir, "theme.layout.ts");
3798
4094
  if (await fs__default.default.pathExists(layoutPath)) {
3799
4095
  let content = await fs__default.default.readFile(layoutPath, "utf-8");
3800
4096
  content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
@@ -3807,7 +4103,7 @@ async function renameTheme(themeDir, oldName, newName) {
3807
4103
  const oldDisplayName = oldName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
3808
4104
  const tsFiles = await glob.glob("**/*.ts", { cwd: themeDir, nodir: true });
3809
4105
  for (const file of tsFiles) {
3810
- const filePath = path8__default.default.join(themeDir, file);
4106
+ const filePath = path9__default.default.join(themeDir, file);
3811
4107
  let content = await fs__default.default.readFile(filePath, "utf-8");
3812
4108
  const original = content;
3813
4109
  content = content.replace(
@@ -3836,7 +4132,7 @@ async function cloneCommand(themeName, options) {
3836
4132
  const spinner = ora__default.default("Initializing clone...").start();
3837
4133
  try {
3838
4134
  const bucket = options.bucket || getBucketName3(options.environment);
3839
- const outputDir = options.output || path8__default.default.resolve(process.cwd(), newName);
4135
+ const outputDir = options.output || path9__default.default.resolve(process.cwd(), newName);
3840
4136
  const s3Client = getS3Client3();
3841
4137
  if (await fs__default.default.pathExists(outputDir)) {
3842
4138
  spinner.fail(chalk4__default.default.red(`Directory already exists: ${outputDir}`));
@@ -3891,7 +4187,7 @@ async function cloneCommand(themeName, options) {
3891
4187
  spinner.succeed(
3892
4188
  `Renamed theme: ${chalk4__default.default.gray(themeName)} \u2192 ${chalk4__default.default.cyan(newName)}`
3893
4189
  );
3894
- const envExamplePath = path8__default.default.join(outputDir, ".env.example");
4190
+ const envExamplePath = path9__default.default.join(outputDir, ".env.example");
3895
4191
  if (!await fs__default.default.pathExists(envExamplePath)) {
3896
4192
  await fs__default.default.writeFile(
3897
4193
  envExamplePath,
@@ -3904,7 +4200,7 @@ async function cloneCommand(themeName, options) {
3904
4200
  ].join("\n")
3905
4201
  );
3906
4202
  }
3907
- const mcpJsonPath = path8__default.default.join(outputDir, ".mcp.json");
4203
+ const mcpJsonPath = path9__default.default.join(outputDir, ".mcp.json");
3908
4204
  if (await fs__default.default.pathExists(mcpJsonPath)) {
3909
4205
  const { default: inquirerMod } = await import('inquirer');
3910
4206
  const { figmaApiKey } = await inquirerMod.prompt([
@@ -3929,7 +4225,7 @@ async function cloneCommand(themeName, options) {
3929
4225
  }
3930
4226
  if (options.install !== false) {
3931
4227
  const hasPkgJson = await fs__default.default.pathExists(
3932
- path8__default.default.join(outputDir, "package.json")
4228
+ path9__default.default.join(outputDir, "package.json")
3933
4229
  );
3934
4230
  if (hasPkgJson) {
3935
4231
  spinner.start("Installing dependencies...");
@@ -3956,7 +4252,7 @@ async function cloneCommand(themeName, options) {
3956
4252
  console.log(chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(entries.length));
3957
4253
  console.log();
3958
4254
  console.log(chalk4__default.default.cyan("Next steps:"));
3959
- console.log(chalk4__default.default.gray(` cd ${path8__default.default.relative(process.cwd(), outputDir)}`));
4255
+ console.log(chalk4__default.default.gray(` cd ${path9__default.default.relative(process.cwd(), outputDir)}`));
3960
4256
  console.log(
3961
4257
  chalk4__default.default.gray(" cp .env.example .env # then add your Company ID")
3962
4258
  );
@@ -3991,7 +4287,7 @@ var MIME_TYPES = {
3991
4287
  };
3992
4288
  function createDevServer(options) {
3993
4289
  const clients = /* @__PURE__ */ new Set();
3994
- const themeDataPath = path8__default.default.join(options.distDir, "theme-data.json");
4290
+ const themeDataPath = path9__default.default.join(options.distDir, "theme-data.json");
3995
4291
  const server = http__default.default.createServer((req, res) => {
3996
4292
  res.setHeader("Access-Control-Allow-Origin", "*");
3997
4293
  res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
@@ -4017,8 +4313,8 @@ function createDevServer(options) {
4017
4313
  if (pathname.startsWith("/_assets/")) {
4018
4314
  const parts = pathname.replace(/^\/_assets\//, "").split("/");
4019
4315
  const assetSubpath = parts.slice(1).join("/");
4020
- const assetPath = path8__default.default.join(options.themePath, "assets", assetSubpath);
4021
- if (!assetPath.startsWith(path8__default.default.join(options.themePath, "assets"))) {
4316
+ const assetPath = path9__default.default.join(options.themePath, "assets", assetSubpath);
4317
+ if (!assetPath.startsWith(path9__default.default.join(options.themePath, "assets"))) {
4022
4318
  res.writeHead(403);
4023
4319
  res.end("Forbidden");
4024
4320
  return;
@@ -4029,8 +4325,8 @@ function createDevServer(options) {
4029
4325
  if (pathname.startsWith("/themes/")) {
4030
4326
  const match = pathname.match(/^\/themes\/[^/]+\/assets\/(.+)/);
4031
4327
  if (match) {
4032
- const assetPath = path8__default.default.join(options.themePath, "assets", match[1]);
4033
- if (!assetPath.startsWith(path8__default.default.join(options.themePath, "assets"))) {
4328
+ const assetPath = path9__default.default.join(options.themePath, "assets", match[1]);
4329
+ if (!assetPath.startsWith(path9__default.default.join(options.themePath, "assets"))) {
4034
4330
  res.writeHead(403);
4035
4331
  res.end("Forbidden");
4036
4332
  return;
@@ -4044,26 +4340,26 @@ function createDevServer(options) {
4044
4340
  const segments = subpath.split("/");
4045
4341
  let assetPath;
4046
4342
  if (segments[0] === options.themeName || segments[0] === options.themeName.replace(/^my-/, "")) {
4047
- assetPath = path8__default.default.join(
4343
+ assetPath = path9__default.default.join(
4048
4344
  options.themePath,
4049
4345
  "assets",
4050
4346
  segments.slice(1).join("/")
4051
4347
  );
4052
4348
  } else {
4053
- assetPath = path8__default.default.join(options.themePath, "assets", subpath);
4349
+ assetPath = path9__default.default.join(options.themePath, "assets", subpath);
4054
4350
  }
4055
- if (assetPath.startsWith(path8__default.default.join(options.themePath, "assets")) && fs2__default.default.existsSync(assetPath)) {
4351
+ if (assetPath.startsWith(path9__default.default.join(options.themePath, "assets")) && fs3__default.default.existsSync(assetPath)) {
4056
4352
  serveFile(res, assetPath);
4057
4353
  return;
4058
4354
  }
4059
4355
  }
4060
- const filePath = path8__default.default.join(options.distDir, pathname);
4356
+ const filePath = path9__default.default.join(options.distDir, pathname);
4061
4357
  if (!filePath.startsWith(options.distDir)) {
4062
4358
  res.writeHead(403);
4063
4359
  res.end("Forbidden");
4064
4360
  return;
4065
4361
  }
4066
- if (fs2__default.default.existsSync(filePath) && fs2__default.default.statSync(filePath).isFile()) {
4362
+ if (fs3__default.default.existsSync(filePath) && fs3__default.default.statSync(filePath).isFile()) {
4067
4363
  serveFile(res, filePath);
4068
4364
  } else {
4069
4365
  res.writeHead(200, { "Content-Type": "text/html" });
@@ -4095,14 +4391,14 @@ function createDevServer(options) {
4095
4391
  }
4096
4392
  function serveFile(res, filePath) {
4097
4393
  try {
4098
- if (!fs2__default.default.existsSync(filePath)) {
4394
+ if (!fs3__default.default.existsSync(filePath)) {
4099
4395
  res.writeHead(404);
4100
4396
  res.end("Not Found");
4101
4397
  return;
4102
4398
  }
4103
- const ext = path8__default.default.extname(filePath);
4399
+ const ext = path9__default.default.extname(filePath);
4104
4400
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
4105
- const content = fs2__default.default.readFileSync(filePath);
4401
+ const content = fs3__default.default.readFileSync(filePath);
4106
4402
  res.writeHead(200, { "Content-Type": contentType });
4107
4403
  res.end(content);
4108
4404
  } catch {
@@ -4115,7 +4411,7 @@ function generatePreviewHTML(themeName, port, themeDataPath) {
4115
4411
  let fontVarsCSS = "";
4116
4412
  if (themeDataPath) {
4117
4413
  try {
4118
- const themeData = JSON.parse(fs2__default.default.readFileSync(themeDataPath, "utf-8"));
4414
+ const themeData = JSON.parse(fs3__default.default.readFileSync(themeDataPath, "utf-8"));
4119
4415
  const typography = (themeData?.themeConfig || themeData?.theme?.config)?.typography?.fontFamily;
4120
4416
  if (typography) {
4121
4417
  const fontFamilies = /* @__PURE__ */ new Set();
@@ -4203,14 +4499,14 @@ async function devCommand(options) {
4203
4499
  if (options.theme) {
4204
4500
  themeName = options.theme;
4205
4501
  try {
4206
- const workspaceThemePath = path8__default.default.join(getThemesDir(), themeName);
4502
+ const workspaceThemePath = path9__default.default.join(getThemesDir(), themeName);
4207
4503
  if (fs__default.default.existsSync(workspaceThemePath)) {
4208
4504
  themePath = workspaceThemePath;
4209
4505
  } else {
4210
- themePath = path8__default.default.join(process.cwd(), themeName);
4506
+ themePath = path9__default.default.join(process.cwd(), themeName);
4211
4507
  }
4212
4508
  } catch {
4213
- themePath = path8__default.default.join(process.cwd(), themeName);
4509
+ themePath = path9__default.default.join(process.cwd(), themeName);
4214
4510
  }
4215
4511
  if (!fs__default.default.existsSync(themePath)) {
4216
4512
  logger.error(`Theme "${themeName}" not found.`);
@@ -4221,10 +4517,10 @@ async function devCommand(options) {
4221
4517
  "theme.config.ts",
4222
4518
  "bundle-entry.ts",
4223
4519
  "manifest.ts"
4224
- ].some((f) => fs__default.default.existsSync(path8__default.default.join(process.cwd(), f)));
4520
+ ].some((f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f)));
4225
4521
  if (isThemeDir) {
4226
4522
  themePath = process.cwd();
4227
- themeName = path8__default.default.basename(themePath);
4523
+ themeName = path9__default.default.basename(themePath);
4228
4524
  } else {
4229
4525
  logger.error(
4230
4526
  "Not in a theme directory and no --theme specified. Run from theme root or use --theme flag."
@@ -4293,9 +4589,9 @@ async function devCommand(options) {
4293
4589
  watcher.close();
4294
4590
  await context2.dispose();
4295
4591
  server.close();
4296
- const shimPath = path8__default.default.join(outputDir, ".process-shim.js");
4592
+ const shimPath = path9__default.default.join(outputDir, ".process-shim.js");
4297
4593
  try {
4298
- await fs7__default.default.unlink(shimPath);
4594
+ await fs8__default.default.unlink(shimPath);
4299
4595
  } catch {
4300
4596
  }
4301
4597
  process.exit(0);
@@ -4304,8 +4600,8 @@ async function devCommand(options) {
4304
4600
 
4305
4601
  // src/commands/config.ts
4306
4602
  init_logger();
4307
- var CONFIG_DIR = path8__default.default.join(os3__default.default.homedir(), ".onexthm");
4308
- var CONFIG_FILE = path8__default.default.join(CONFIG_DIR, ".env");
4603
+ var CONFIG_DIR = path9__default.default.join(os__default.default.homedir(), ".onexthm");
4604
+ var CONFIG_FILE = path9__default.default.join(CONFIG_DIR, ".env");
4309
4605
  var CONFIG_ENTRIES = [
4310
4606
  {
4311
4607
  key: "AWS_ACCESS_KEY_ID",
@@ -4447,122 +4743,6 @@ async function configCommand() {
4447
4743
 
4448
4744
  // src/commands/login.ts
4449
4745
  init_logger();
4450
- var AUTH_DIR = path8__default.default.join(os3__default.default.homedir(), ".onexthm");
4451
- var AUTH_FILE = path8__default.default.join(AUTH_DIR, "auth.json");
4452
- function getApiUrl() {
4453
- return process.env.ONEXTHM_API_URL || process.env.NEXT_PUBLIC_API_URL || "https://platform-dev.onexeos.com";
4454
- }
4455
- async function saveAuthTokens(tokens) {
4456
- await fs__default.default.ensureDir(AUTH_DIR);
4457
- const key = getMachineKey();
4458
- const data = JSON.stringify(tokens);
4459
- const encrypted = encrypt(data, key);
4460
- await fs__default.default.writeFile(AUTH_FILE, encrypted, "utf-8");
4461
- }
4462
- function loadAuthTokens() {
4463
- try {
4464
- if (!fs__default.default.existsSync(AUTH_FILE)) return null;
4465
- const encrypted = fs__default.default.readFileSync(AUTH_FILE, "utf-8");
4466
- const key = getMachineKey();
4467
- const data = decrypt(encrypted, key);
4468
- return JSON.parse(data);
4469
- } catch {
4470
- return null;
4471
- }
4472
- }
4473
- async function clearAuthTokens() {
4474
- try {
4475
- await fs__default.default.remove(AUTH_FILE);
4476
- } catch {
4477
- }
4478
- }
4479
- function isTokenExpired(tokens) {
4480
- return Date.now() / 1e3 > tokens.expiresAt - 60;
4481
- }
4482
- async function getValidTokens() {
4483
- const tokens = loadAuthTokens();
4484
- if (!tokens) return null;
4485
- if (!isTokenExpired(tokens)) return tokens;
4486
- try {
4487
- const apiUrl = getApiUrl();
4488
- const response = await fetch(`${apiUrl}/auth/refresh`, {
4489
- method: "POST",
4490
- headers: { "Content-Type": "application/json" },
4491
- body: JSON.stringify({ refresh_token: tokens.refreshToken })
4492
- });
4493
- if (!response.ok) {
4494
- await clearAuthTokens();
4495
- return null;
4496
- }
4497
- const data = await response.json();
4498
- const body = data.statusCode ? data.body : data;
4499
- const refreshed = {
4500
- ...tokens,
4501
- accessToken: body.AccessToken || tokens.accessToken,
4502
- idToken: body.IdToken || tokens.idToken,
4503
- expiresAt: Math.floor(Date.now() / 1e3) + (body.ExpiresIn || 3600)
4504
- };
4505
- await saveAuthTokens(refreshed);
4506
- return refreshed;
4507
- } catch {
4508
- await clearAuthTokens();
4509
- return null;
4510
- }
4511
- }
4512
- async function authenticatedFetch(url, init) {
4513
- const tokens = await getValidTokens();
4514
- if (!tokens) {
4515
- throw new Error("Not logged in. Run: onexthm login");
4516
- }
4517
- const headers = new Headers(init?.headers);
4518
- headers.set("Authorization", `Bearer ${tokens.idToken}`);
4519
- headers.set("Content-Type", "application/json");
4520
- return fetch(url, { ...init, headers });
4521
- }
4522
- function getMachineKey() {
4523
- let seed;
4524
- if (process.platform === "darwin") {
4525
- seed = `onexthm:${os3__default.default.hostname()}:${os3__default.default.userInfo().username}`;
4526
- } else if (process.platform === "linux") {
4527
- try {
4528
- seed = `onexthm:${fs__default.default.readFileSync("/etc/machine-id", "utf-8").trim()}`;
4529
- } catch {
4530
- seed = `onexthm:${os3__default.default.hostname()}:${os3__default.default.userInfo().username}`;
4531
- }
4532
- } else {
4533
- seed = `onexthm:${os3__default.default.hostname()}:${os3__default.default.userInfo().username}`;
4534
- }
4535
- return crypto2__default.default.createHash("sha256").update(seed).digest();
4536
- }
4537
- function encrypt(text, key) {
4538
- const iv = crypto2__default.default.randomBytes(16);
4539
- const cipher = crypto2__default.default.createCipheriv("aes-256-gcm", key, iv);
4540
- let encrypted = cipher.update(text, "utf-8", "hex");
4541
- encrypted += cipher.final("hex");
4542
- const tag = cipher.getAuthTag();
4543
- return `${iv.toString("hex")}:${tag.toString("hex")}:${encrypted}`;
4544
- }
4545
- function decrypt(text, key) {
4546
- const [ivHex, tagHex, encrypted] = text.split(":");
4547
- const iv = Buffer.from(ivHex, "hex");
4548
- const tag = Buffer.from(tagHex, "hex");
4549
- const decipher = crypto2__default.default.createDecipheriv("aes-256-gcm", key, iv);
4550
- decipher.setAuthTag(tag);
4551
- let decrypted = decipher.update(encrypted, "hex", "utf-8");
4552
- decrypted += decipher.final("utf-8");
4553
- return decrypted;
4554
- }
4555
- function parseJwtClaims(idToken) {
4556
- try {
4557
- const payload = idToken.split(".")[1];
4558
- const decoded = Buffer.from(payload, "base64url").toString("utf-8");
4559
- return JSON.parse(decoded);
4560
- } catch {
4561
- return {};
4562
- }
4563
- }
4564
-
4565
- // src/commands/login.ts
4566
4746
  async function loginCommand() {
4567
4747
  logger.header("OneX Theme Developer Login");
4568
4748
  const existing = loadAuthTokens();
@@ -4688,13 +4868,13 @@ async function publishCommand(options) {
4688
4868
  logger.info(`Logged in as: ${tokens.user.email}`);
4689
4869
  let themePath;
4690
4870
  if (options.theme) {
4691
- themePath = path8__default.default.resolve(options.theme);
4871
+ themePath = path9__default.default.resolve(options.theme);
4692
4872
  } else {
4693
4873
  const isThemeDir = [
4694
4874
  "theme.config.ts",
4695
4875
  "bundle-entry.ts",
4696
4876
  "manifest.ts"
4697
- ].some((f) => fs__default.default.existsSync(path8__default.default.join(process.cwd(), f)));
4877
+ ].some((f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f)));
4698
4878
  if (isThemeDir) {
4699
4879
  themePath = process.cwd();
4700
4880
  } else {
@@ -4704,14 +4884,31 @@ async function publishCommand(options) {
4704
4884
  process.exit(1);
4705
4885
  }
4706
4886
  }
4707
- const pkgPath = path8__default.default.join(themePath, "package.json");
4887
+ const pkgPath = path9__default.default.join(themePath, "package.json");
4708
4888
  if (!fs__default.default.existsSync(pkgPath)) {
4709
4889
  logger.error("No package.json found in theme directory");
4710
4890
  process.exit(1);
4711
4891
  }
4712
4892
  const pkg = fs__default.default.readJsonSync(pkgPath);
4713
- const themeId = pkg.name?.replace("@onex-themes/", "") || path8__default.default.basename(themePath);
4893
+ const themeId = pkg.name?.replace("@onex-themes/", "") || path9__default.default.basename(themePath);
4894
+ if (options.bump) {
4895
+ const currentVersion = pkg.version || "1.0.0";
4896
+ const newVersion = semver__default.default.inc(currentVersion, options.bump);
4897
+ if (!newVersion) {
4898
+ logger.error(`Failed to bump version from ${currentVersion}`);
4899
+ process.exit(1);
4900
+ }
4901
+ pkg.version = newVersion;
4902
+ fs__default.default.writeJsonSync(pkgPath, pkg, { spaces: 2 });
4903
+ logger.info(`Bumped version: ${currentVersion} -> ${newVersion}`);
4904
+ }
4714
4905
  const version2 = pkg.version || "1.0.0";
4906
+ if (!semver__default.default.valid(version2)) {
4907
+ logger.error(
4908
+ `Invalid version "${version2}" in package.json. Must be valid semver (e.g., 1.0.0)`
4909
+ );
4910
+ process.exit(1);
4911
+ }
4715
4912
  logger.newLine();
4716
4913
  logger.info(`Theme: ${themeId}`);
4717
4914
  logger.info(`Version: ${version2}`);
@@ -4748,6 +4945,38 @@ async function publishCommand(options) {
4748
4945
  logger.error(error instanceof Error ? error.message : "Connection failed");
4749
4946
  process.exit(1);
4750
4947
  }
4948
+ logger.startSpinner("Checking version availability...");
4949
+ try {
4950
+ const checkResponse = await authenticatedFetch(
4951
+ `${apiUrl}/website-api/themes/${encodeURIComponent(themeId)}/versions/${encodeURIComponent(version2)}/exists`,
4952
+ { method: "GET" }
4953
+ );
4954
+ const checkData = await checkResponse.json();
4955
+ const checkBody = checkData.statusCode ? checkData.body : checkData;
4956
+ if (checkBody.exists) {
4957
+ logger.stopSpinner(false, "Version already published");
4958
+ const patchVer = semver__default.default.inc(version2, "patch") || "?";
4959
+ const minorVer = semver__default.default.inc(version2, "minor") || "?";
4960
+ const majorVer = semver__default.default.inc(version2, "major") || "?";
4961
+ logger.error(
4962
+ `
4963
+ Version ${version2} of "${themeId}" is already published and cannot be overwritten.
4964
+
4965
+ To publish a new version:
4966
+ 1. Bump version in package.json (e.g., ${version2} -> ${patchVer})
4967
+ 2. Run: onexthm publish
4968
+
4969
+ Or use the --bump flag:
4970
+ onexthm publish --bump patch (${version2} -> ${patchVer})
4971
+ onexthm publish --bump minor (${version2} -> ${minorVer})
4972
+ onexthm publish --bump major (${version2} -> ${majorVer})`
4973
+ );
4974
+ process.exit(1);
4975
+ }
4976
+ logger.stopSpinner(true, `Version ${version2} is available`);
4977
+ } catch (error) {
4978
+ logger.stopSpinner(true, "Version check skipped (endpoint not available)");
4979
+ }
4751
4980
  logger.startSpinner("Building theme...");
4752
4981
  try {
4753
4982
  const { compileStandaloneTheme: compileStandaloneTheme2 } = await Promise.resolve().then(() => (init_compile_theme(), compile_theme_exports));
@@ -4793,13 +5022,13 @@ async function publishCommand(options) {
4793
5022
  try {
4794
5023
  const archiver3 = await import('archiver');
4795
5024
  const { createWriteStream } = await import('fs');
4796
- const distDir = path8__default.default.join(themePath, "dist");
5025
+ const distDir = path9__default.default.join(themePath, "dist");
4797
5026
  if (!fs__default.default.existsSync(distDir)) {
4798
5027
  logger.stopSpinner(false, "No dist/ directory");
4799
5028
  logger.error("Build the theme first: onexthm build");
4800
5029
  process.exit(1);
4801
5030
  }
4802
- const bundleZipPath = path8__default.default.join(themePath, "dist", "bundle.zip");
5031
+ const bundleZipPath = path9__default.default.join(themePath, "dist", "bundle.zip");
4803
5032
  await createZip(distDir, bundleZipPath, [
4804
5033
  "bundle.zip",
4805
5034
  "source.zip",
@@ -4824,7 +5053,7 @@ async function publishCommand(options) {
4824
5053
  }
4825
5054
  logger.startSpinner("Uploading source...");
4826
5055
  try {
4827
- const sourceZipPath = path8__default.default.join(themePath, "dist", "source.zip");
5056
+ const sourceZipPath = path9__default.default.join(themePath, "dist", "source.zip");
4828
5057
  await createZip(themePath, sourceZipPath, [
4829
5058
  "node_modules",
4830
5059
  "dist",
@@ -4909,17 +5138,23 @@ async function createZip(sourceDir, outputPath, exclude) {
4909
5138
  }
4910
5139
 
4911
5140
  // src/cli.ts
5141
+ dotenv__default.default.config({
5142
+ path: path9__default.default.join(process.cwd(), ".env.local"),
5143
+ override: true
5144
+ });
5145
+ dotenv__default.default.config({ path: path9__default.default.join(process.cwd(), ".env") });
4912
5146
  try {
4913
5147
  const projectRoot = getProjectRoot();
4914
- dotenv__default.default.config({
4915
- path: path8__default.default.join(projectRoot, ".env.local"),
4916
- quiet: true
4917
- });
4918
- dotenv__default.default.config({ path: path8__default.default.join(projectRoot, ".env"), quiet: true });
5148
+ if (path9__default.default.resolve(projectRoot) !== path9__default.default.resolve(process.cwd())) {
5149
+ dotenv__default.default.config({
5150
+ path: path9__default.default.join(projectRoot, ".env.local")
5151
+ });
5152
+ dotenv__default.default.config({ path: path9__default.default.join(projectRoot, ".env") });
5153
+ }
4919
5154
  } catch {
4920
5155
  }
4921
5156
  dotenv__default.default.config({
4922
- path: path8__default.default.join(os3__default.default.homedir(), ".onexthm", ".env"),
5157
+ path: path9__default.default.join(os__default.default.homedir(), ".onexthm", ".env"),
4923
5158
  quiet: true
4924
5159
  });
4925
5160
  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)));
@@ -4979,7 +5214,10 @@ program.command("config").description("Configure OneX CLI credentials (AWS, API
4979
5214
  program.command("login").description("Login to OneX platform").action(loginCommand);
4980
5215
  program.command("logout").description("Logout from OneX platform").action(logoutCommand);
4981
5216
  program.command("whoami").description("Show current logged-in developer").action(whoamiCommand);
4982
- program.command("publish").description("Build, scan, and publish theme to marketplace (requires login)").option("-t, --theme <path>", "Theme directory path").action(publishCommand);
5217
+ program.command("publish").description("Build, scan, and publish theme to marketplace (requires login)").option("-t, --theme <path>", "Theme directory path").option(
5218
+ "--bump <type>",
5219
+ "Auto-bump version before publish (patch|minor|major)"
5220
+ ).action(publishCommand);
4983
5221
  program.configureOutput({
4984
5222
  writeErr: (str) => process.stderr.write(chalk4__default.default.red(str))
4985
5223
  });