@motion-proto/live-tokens 0.8.0 → 0.10.0

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 (61) hide show
  1. package/.claude/skills/live-tokens-add-component/SKILL.md +488 -0
  2. package/README.md +84 -29
  3. package/dist-plugin/index.cjs +177 -125
  4. package/dist-plugin/index.d.cts +3 -2
  5. package/dist-plugin/index.d.ts +3 -2
  6. package/dist-plugin/index.js +177 -125
  7. package/package.json +8 -2
  8. package/src/editor/component-editor/BadgeEditor.svelte +44 -42
  9. package/src/editor/component-editor/ButtonEditor.svelte +224 -0
  10. package/src/editor/component-editor/CollapsibleSectionEditor.svelte +1 -7
  11. package/src/editor/component-editor/CornerBadgeEditor.svelte +44 -34
  12. package/src/editor/component-editor/ImageLightboxEditor.svelte +58 -0
  13. package/src/editor/component-editor/InputEditor.svelte +272 -0
  14. package/src/editor/component-editor/NotificationEditor.svelte +44 -65
  15. package/src/editor/component-editor/ProgressBarEditor.svelte +71 -87
  16. package/src/editor/component-editor/SegmentedControlEditor.svelte +98 -37
  17. package/src/editor/component-editor/SideNavigationEditor.svelte +342 -0
  18. package/src/editor/component-editor/index.ts +16 -1
  19. package/src/editor/component-editor/registry.ts +138 -28
  20. package/src/editor/component-editor/scaffolding/ComponentFileManager.svelte +3 -2
  21. package/src/editor/component-editor/scaffolding/ComponentsTab.svelte +2 -2
  22. package/src/editor/component-editor/scaffolding/StateBlock.svelte +9 -10
  23. package/src/editor/component-editor/scaffolding/TokenLayout.svelte +60 -36
  24. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +38 -1
  25. package/src/editor/component-editor/scaffolding/buildTypeGroupTokens.ts +1 -1
  26. package/src/editor/component-editor/scaffolding/componentSources.ts +3 -3
  27. package/src/editor/component-editor/scaffolding/defaultSections.ts +15 -10
  28. package/src/editor/component-editor/scaffolding/siblings.ts +2 -2
  29. package/src/editor/component-editor/scaffolding/types.ts +2 -1
  30. package/src/editor/core/components/componentConfigKeys.ts +14 -3
  31. package/src/editor/core/components/componentConfigService.ts +7 -6
  32. package/src/editor/core/manifests/manifestService.ts +5 -4
  33. package/src/editor/core/storage/apiBase.ts +15 -0
  34. package/src/editor/core/storage/files/versionedFileResourceClient.ts +1 -1
  35. package/src/editor/core/themes/migrations/2026-05-24-collapsiblesection-drop-active-state.ts +28 -0
  36. package/src/editor/core/themes/migrations/2026-05-24-progressbar-collapse-variants.ts +41 -0
  37. package/src/editor/core/themes/migrations/2026-05-24-promote-state-shared-tokens.ts +59 -0
  38. package/src/editor/core/themes/migrations/2026-05-24-segmentedcontrol-divider-inset.ts +29 -0
  39. package/src/editor/core/themes/migrations/2026-05-25-cornerbadge-flatten-variants.ts +46 -0
  40. package/src/editor/core/themes/migrations/index.ts +10 -0
  41. package/src/editor/core/themes/slices/components.ts +9 -0
  42. package/src/editor/core/themes/themeInit.ts +3 -2
  43. package/src/editor/core/themes/themeService.ts +3 -2
  44. package/src/editor/index.ts +10 -1
  45. package/src/editor/pages/ComponentEditorPage.svelte +53 -3
  46. package/src/editor/pages/EditorShell.svelte +53 -3
  47. package/src/editor/ui/UIEasingSelector.svelte +240 -0
  48. package/src/editor/ui/variantScales.ts +34 -0
  49. package/src/system/components/Button.svelte +34 -85
  50. package/src/system/components/CollapsibleSection.svelte +1 -48
  51. package/src/system/components/CornerBadge.svelte +72 -138
  52. package/src/system/components/Dialog.svelte +24 -4
  53. package/src/system/components/ImageLightbox.svelte +578 -0
  54. package/src/system/components/Input.svelte +387 -0
  55. package/src/system/components/ProgressBar.svelte +62 -258
  56. package/src/system/components/SectionDivider.svelte +117 -43
  57. package/src/system/components/SegmentedControl.svelte +81 -15
  58. package/src/system/components/SideNavigation.svelte +777 -0
  59. package/src/system/styles/tokens.css +43 -0
  60. package/src/system/styles/tokens.generated.css +4 -183
  61. package/src/editor/component-editor/StandardButtonsEditor.svelte +0 -190
@@ -35,8 +35,8 @@ __export(index_exports, {
35
35
  module.exports = __toCommonJS(index_exports);
36
36
 
37
37
  // vite-plugin/themeFileApi.ts
38
- var import_fs2 = __toESM(require("fs"), 1);
39
- var import_path2 = __toESM(require("path"), 1);
38
+ var import_fs3 = __toESM(require("fs"), 1);
39
+ var import_path3 = __toESM(require("path"), 1);
40
40
 
41
41
  // src/editor/core/themes/parsers/globalRootBlock.ts
42
42
  function extractGlobalRootBody(source) {
@@ -556,19 +556,64 @@ function nextAvailableName(exists, baseName, maxAttempts = 1e3) {
556
556
  throw new Error(`Could not allocate a non-colliding name for "${baseName}"`);
557
557
  }
558
558
 
559
+ // vite-plugin/files/dataPaths.ts
560
+ var import_fs2 = __toESM(require("fs"), 1);
561
+ var import_path2 = __toESM(require("path"), 1);
562
+ var DEFAULT_DATA_DIR = "src/live-tokens/data";
563
+ var KNOWN_CONFIG_KEYS = /* @__PURE__ */ new Set([
564
+ "dataDir",
565
+ "themesDir",
566
+ "componentConfigsDir",
567
+ "manifestsDir"
568
+ ]);
569
+ var cached = null;
570
+ function readLiveTokensConfig() {
571
+ if (cached) return cached;
572
+ try {
573
+ const configPath = import_path2.default.resolve("live-tokens.config.json");
574
+ if (!import_fs2.default.existsSync(configPath)) return cached = {};
575
+ const parsed = JSON.parse(import_fs2.default.readFileSync(configPath, "utf-8"));
576
+ if (!parsed || typeof parsed !== "object") return cached = {};
577
+ const unknown = Object.keys(parsed).filter(
578
+ (k) => k !== "$schema" && !KNOWN_CONFIG_KEYS.has(k)
579
+ );
580
+ if (unknown.length > 0) {
581
+ console.warn(
582
+ `[live-tokens] Unknown key(s) in live-tokens.config.json: ${unknown.join(", ")}. Known keys: ${Array.from(KNOWN_CONFIG_KEYS).join(", ")}.`
583
+ );
584
+ }
585
+ cached = parsed;
586
+ return cached;
587
+ } catch {
588
+ return cached = {};
589
+ }
590
+ }
591
+ function resolveDataDirs(opts = {}) {
592
+ const fileConfig = readLiveTokensConfig();
593
+ const dataDirRaw = opts.dataDir ?? fileConfig.dataDir ?? DEFAULT_DATA_DIR;
594
+ const dataDir = import_path2.default.resolve(dataDirRaw);
595
+ const sub = (name) => import_path2.default.resolve(dataDir, name);
596
+ return {
597
+ dataDir,
598
+ themesDir: opts.themesDir ? import_path2.default.resolve(opts.themesDir) : fileConfig.themesDir ? import_path2.default.resolve(fileConfig.themesDir) : sub("themes"),
599
+ componentConfigsDir: opts.componentConfigsDir ? import_path2.default.resolve(opts.componentConfigsDir) : fileConfig.componentConfigsDir ? import_path2.default.resolve(fileConfig.componentConfigsDir) : sub("component-configs"),
600
+ manifestsDir: opts.manifestsDir ? import_path2.default.resolve(opts.manifestsDir) : fileConfig.manifestsDir ? import_path2.default.resolve(fileConfig.manifestsDir) : sub("manifests")
601
+ };
602
+ }
603
+
559
604
  // vite-plugin/themeFileApi.ts
560
605
  var import_node_url = require("url");
561
606
  var import_meta = {};
562
607
  var PKG_VERSION = (() => {
563
608
  try {
564
- let dir = import_path2.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
609
+ let dir = import_path3.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
565
610
  for (let i = 0; i < 4; i++) {
566
- const p = import_path2.default.join(dir, "package.json");
567
- if (import_fs2.default.existsSync(p)) {
568
- const json = JSON.parse(import_fs2.default.readFileSync(p, "utf-8"));
611
+ const p = import_path3.default.join(dir, "package.json");
612
+ if (import_fs3.default.existsSync(p)) {
613
+ const json = JSON.parse(import_fs3.default.readFileSync(p, "utf-8"));
569
614
  if (json?.name === "@motion-proto/live-tokens") return json.version ?? "";
570
615
  }
571
- const up = import_path2.default.dirname(dir);
616
+ const up = import_path3.default.dirname(dir);
572
617
  if (up === dir) break;
573
618
  dir = up;
574
619
  }
@@ -577,15 +622,21 @@ var PKG_VERSION = (() => {
577
622
  return "";
578
623
  })();
579
624
  function themeFileApi(opts) {
580
- const THEMES_DIR = import_path2.default.resolve(opts.themesDir);
581
- const CSS_PATH = import_path2.default.resolve(opts.tokensCssPath);
582
- const GENERATED_CSS_PATH = opts.tokensGeneratedCssPath ? import_path2.default.resolve(opts.tokensGeneratedCssPath) : import_path2.default.join(import_path2.default.dirname(CSS_PATH), "tokens.generated.css");
583
- const FONTS_CSS_PATH = opts.fontsCssPath ? import_path2.default.resolve(opts.fontsCssPath) : import_path2.default.join(import_path2.default.dirname(CSS_PATH), "fonts.css");
584
- const API_BASE = opts.apiBase ?? "/api";
585
- const COMPONENT_CONFIGS_DIR = opts.componentConfigsDir ? import_path2.default.resolve(opts.componentConfigsDir) : import_path2.default.resolve("component-configs");
586
- const COMPONENTS_SRC_DIR = opts.componentsSrcDir ? import_path2.default.resolve(opts.componentsSrcDir) : import_path2.default.resolve("src/system/components");
587
- const MANIFESTS_DIR = opts.manifestsDir ? import_path2.default.resolve(opts.manifestsDir) : import_path2.default.resolve("manifests");
588
- const LEGACY_PRESETS_DIR = import_path2.default.resolve("presets");
625
+ const dataDirs = resolveDataDirs({
626
+ dataDir: opts.dataDir,
627
+ themesDir: opts.themesDir,
628
+ componentConfigsDir: opts.componentConfigsDir,
629
+ manifestsDir: opts.manifestsDir
630
+ });
631
+ const THEMES_DIR = dataDirs.themesDir;
632
+ const COMPONENT_CONFIGS_DIR = dataDirs.componentConfigsDir;
633
+ const MANIFESTS_DIR = dataDirs.manifestsDir;
634
+ const CSS_PATH = import_path3.default.resolve(opts.tokensCssPath);
635
+ const GENERATED_CSS_PATH = opts.tokensGeneratedCssPath ? import_path3.default.resolve(opts.tokensGeneratedCssPath) : import_path3.default.join(import_path3.default.dirname(CSS_PATH), "tokens.generated.css");
636
+ const FONTS_CSS_PATH = opts.fontsCssPath ? import_path3.default.resolve(opts.fontsCssPath) : import_path3.default.join(import_path3.default.dirname(CSS_PATH), "fonts.css");
637
+ const API_BASE = opts.apiBase ?? "/api/live-tokens";
638
+ const COMPONENTS_SRC_DIR = opts.componentsSrcDir ? import_path3.default.resolve(opts.componentsSrcDir) : import_path3.default.resolve("src/system/components");
639
+ const LEGACY_PRESETS_DIR = import_path3.default.resolve("presets");
589
640
  const themesResource = versionedFileResourceServer({
590
641
  dir: THEMES_DIR
591
642
  });
@@ -593,7 +644,7 @@ function themeFileApi(opts) {
593
644
  function componentResource(comp) {
594
645
  let r = componentResourceCache.get(comp);
595
646
  if (!r) {
596
- r = versionedFileResourceServer({ dir: import_path2.default.join(COMPONENT_CONFIGS_DIR, comp) });
647
+ r = versionedFileResourceServer({ dir: import_path3.default.join(COMPONENT_CONFIGS_DIR, comp) });
597
648
  componentResourceCache.set(comp, r);
598
649
  }
599
650
  return r;
@@ -601,7 +652,7 @@ function themeFileApi(opts) {
601
652
  const manifestsResource = versionedFileResourceServer({ dir: MANIFESTS_DIR });
602
653
  function ensureThemesDir() {
603
654
  themesResource.ensureDir();
604
- if (!import_fs2.default.existsSync(import_path2.default.join(THEMES_DIR, "default.json"))) {
655
+ if (!import_fs3.default.existsSync(import_path3.default.join(THEMES_DIR, "default.json"))) {
605
656
  const defaultTheme = {
606
657
  name: "Default Theme",
607
658
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -609,7 +660,7 @@ function themeFileApi(opts) {
609
660
  editorConfigs: {},
610
661
  cssVariables: {}
611
662
  };
612
- import_fs2.default.writeFileSync(import_path2.default.join(THEMES_DIR, "default.json"), JSON.stringify(defaultTheme, null, 2));
663
+ import_fs3.default.writeFileSync(import_path3.default.join(THEMES_DIR, "default.json"), JSON.stringify(defaultTheme, null, 2));
613
664
  }
614
665
  themesResource.ensureMeta();
615
666
  }
@@ -674,10 +725,10 @@ function themeFileApi(opts) {
674
725
  lines.push("/* tokens.css holds developer-authored defaults; this file holds editor overrides. */");
675
726
  lines.push("");
676
727
  const productionThemeName = themesResource.getProductionName();
677
- const themePath = import_path2.default.join(THEMES_DIR, `${productionThemeName}.json`);
728
+ const themePath = import_path3.default.join(THEMES_DIR, `${productionThemeName}.json`);
678
729
  let themeVarCount = 0;
679
- if (import_fs2.default.existsSync(themePath)) {
680
- const themeData = JSON.parse(import_fs2.default.readFileSync(themePath, "utf-8"));
730
+ if (import_fs3.default.existsSync(themePath)) {
731
+ const themeData = JSON.parse(import_fs3.default.readFileSync(themePath, "utf-8"));
681
732
  const cssVars = { ...themeData.cssVariables || {} };
682
733
  Object.assign(cssVars, palettesToVars(themeData.editorConfigs ?? {}));
683
734
  const resolvedFontVars = resolveFontStacks(themeData);
@@ -696,7 +747,7 @@ function themeFileApi(opts) {
696
747
  }
697
748
  }
698
749
  let componentOverrideCount = 0;
699
- if (import_fs2.default.existsSync(COMPONENT_CONFIGS_DIR)) {
750
+ if (import_fs3.default.existsSync(COMPONENT_CONFIGS_DIR)) {
700
751
  const blocks = [];
701
752
  for (const comp of listComponentNames()) {
702
753
  const prod = componentResource(comp).getProductionName();
@@ -730,21 +781,21 @@ function themeFileApi(opts) {
730
781
  lines.push("");
731
782
  }
732
783
  }
733
- if (!import_fs2.default.existsSync(import_path2.default.dirname(GENERATED_CSS_PATH))) {
734
- import_fs2.default.mkdirSync(import_path2.default.dirname(GENERATED_CSS_PATH), { recursive: true });
784
+ if (!import_fs3.default.existsSync(import_path3.default.dirname(GENERATED_CSS_PATH))) {
785
+ import_fs3.default.mkdirSync(import_path3.default.dirname(GENERATED_CSS_PATH), { recursive: true });
735
786
  }
736
- import_fs2.default.writeFileSync(GENERATED_CSS_PATH, lines.join("\n"));
787
+ import_fs3.default.writeFileSync(GENERATED_CSS_PATH, lines.join("\n"));
737
788
  console.log(
738
- `[regenerateTokensCss] Wrote ${import_path2.default.basename(GENERATED_CSS_PATH)} (${themeVarCount} theme vars, ${componentOverrideCount} component overrides)`
789
+ `[regenerateTokensCss] Wrote ${import_path3.default.basename(GENERATED_CSS_PATH)} (${themeVarCount} theme vars, ${componentOverrideCount} component overrides)`
739
790
  );
740
791
  }
741
792
  function syncTokensToCss(_fileName) {
742
793
  regenerateTokensCss();
743
794
  }
744
795
  function syncFontsToCss(fileName) {
745
- const themePath = import_path2.default.join(THEMES_DIR, `${fileName}.json`);
746
- if (!import_fs2.default.existsSync(themePath)) return;
747
- const themeData = JSON.parse(import_fs2.default.readFileSync(themePath, "utf-8"));
796
+ const themePath = import_path3.default.join(THEMES_DIR, `${fileName}.json`);
797
+ if (!import_fs3.default.existsSync(themePath)) return;
798
+ const themeData = JSON.parse(import_fs3.default.readFileSync(themePath, "utf-8"));
748
799
  const sources = themeData.fontSources;
749
800
  if (!sources) return;
750
801
  const lines = [];
@@ -768,11 +819,11 @@ function themeFileApi(opts) {
768
819
  lines.push("");
769
820
  }
770
821
  const content = lines.join("\n");
771
- if (!import_fs2.default.existsSync(import_path2.default.dirname(FONTS_CSS_PATH))) {
772
- import_fs2.default.mkdirSync(import_path2.default.dirname(FONTS_CSS_PATH), { recursive: true });
822
+ if (!import_fs3.default.existsSync(import_path3.default.dirname(FONTS_CSS_PATH))) {
823
+ import_fs3.default.mkdirSync(import_path3.default.dirname(FONTS_CSS_PATH), { recursive: true });
773
824
  }
774
- import_fs2.default.writeFileSync(FONTS_CSS_PATH, content);
775
- console.log(`[syncFontsToCss] Wrote ${sources.length} source(s) into ${import_path2.default.basename(FONTS_CSS_PATH)}`);
825
+ import_fs3.default.writeFileSync(FONTS_CSS_PATH, content);
826
+ console.log(`[syncFontsToCss] Wrote ${sources.length} source(s) into ${import_path3.default.basename(FONTS_CSS_PATH)}`);
776
827
  }
777
828
  function extractAliasDeclarations(body) {
778
829
  const aliases = {};
@@ -782,35 +833,35 @@ function themeFileApi(opts) {
782
833
  return aliases;
783
834
  }
784
835
  function componentNameFromFile(filePath) {
785
- return import_path2.default.basename(filePath, ".svelte").toLowerCase();
836
+ return import_path3.default.basename(filePath, ".svelte").toLowerCase();
786
837
  }
787
838
  function listComponentSourcePaths() {
788
- if (!import_fs2.default.existsSync(COMPONENTS_SRC_DIR)) return [];
789
- return import_fs2.default.readdirSync(COMPONENTS_SRC_DIR).filter((f) => f.endsWith(".svelte")).map((f) => import_path2.default.join(COMPONENTS_SRC_DIR, f));
839
+ if (!import_fs3.default.existsSync(COMPONENTS_SRC_DIR)) return [];
840
+ return import_fs3.default.readdirSync(COMPONENTS_SRC_DIR).filter((f) => f.endsWith(".svelte")).map((f) => import_path3.default.join(COMPONENTS_SRC_DIR, f));
790
841
  }
791
842
  function listComponentNames() {
792
843
  return listComponentSourcePaths().map(componentNameFromFile);
793
844
  }
794
845
  function generateDefaultConfig(comp, sourcePath) {
795
- if (!import_fs2.default.existsSync(sourcePath)) return;
846
+ if (!import_fs3.default.existsSync(sourcePath)) return;
796
847
  const r = componentResource(comp);
797
848
  r.ensureDir();
798
849
  const defaultPath = r.filePath("default");
799
- const sourceStat = import_fs2.default.statSync(sourcePath);
800
- if (import_fs2.default.existsSync(defaultPath)) {
801
- const defaultStat = import_fs2.default.statSync(defaultPath);
850
+ const sourceStat = import_fs3.default.statSync(sourcePath);
851
+ if (import_fs3.default.existsSync(defaultPath)) {
852
+ const defaultStat = import_fs3.default.statSync(defaultPath);
802
853
  if (defaultStat.mtimeMs >= sourceStat.mtimeMs) return;
803
854
  }
804
- const source = import_fs2.default.readFileSync(sourcePath, "utf-8");
855
+ const source = import_fs3.default.readFileSync(sourcePath, "utf-8");
805
856
  const body = extractGlobalRootBody(source);
806
857
  const aliases = extractAliasDeclarations(body);
807
858
  const now = (/* @__PURE__ */ new Date()).toISOString();
808
859
  let createdAt = now;
809
860
  let existingUpdatedAt;
810
861
  let existingAliases;
811
- if (import_fs2.default.existsSync(defaultPath)) {
862
+ if (import_fs3.default.existsSync(defaultPath)) {
812
863
  try {
813
- const existing = JSON.parse(import_fs2.default.readFileSync(defaultPath, "utf-8"));
864
+ const existing = JSON.parse(import_fs3.default.readFileSync(defaultPath, "utf-8"));
814
865
  if (existing.createdAt) createdAt = existing.createdAt;
815
866
  if (typeof existing.updatedAt === "string") existingUpdatedAt = existing.updatedAt;
816
867
  if (existing.aliases && typeof existing.aliases === "object") {
@@ -829,14 +880,14 @@ function themeFileApi(opts) {
829
880
  };
830
881
  if (aliasesUnchanged && existingUpdatedAt) {
831
882
  const t = /* @__PURE__ */ new Date();
832
- import_fs2.default.utimesSync(defaultPath, t, t);
883
+ import_fs3.default.utimesSync(defaultPath, t, t);
833
884
  return;
834
885
  }
835
- import_fs2.default.writeFileSync(defaultPath, JSON.stringify(defaultConfig, null, 2));
886
+ import_fs3.default.writeFileSync(defaultPath, JSON.stringify(defaultConfig, null, 2));
836
887
  }
837
888
  function ensureComponentConfigsDir() {
838
- if (!import_fs2.default.existsSync(COMPONENT_CONFIGS_DIR)) {
839
- import_fs2.default.mkdirSync(COMPONENT_CONFIGS_DIR, { recursive: true });
889
+ if (!import_fs3.default.existsSync(COMPONENT_CONFIGS_DIR)) {
890
+ import_fs3.default.mkdirSync(COMPONENT_CONFIGS_DIR, { recursive: true });
840
891
  }
841
892
  for (const sourcePath of listComponentSourcePaths()) {
842
893
  const comp = componentNameFromFile(sourcePath);
@@ -847,14 +898,14 @@ function themeFileApi(opts) {
847
898
  }
848
899
  }
849
900
  function ensureManifestsDir() {
850
- if (!import_fs2.default.existsSync(MANIFESTS_DIR) && import_fs2.default.existsSync(LEGACY_PRESETS_DIR)) {
851
- import_fs2.default.renameSync(LEGACY_PRESETS_DIR, MANIFESTS_DIR);
852
- const legacyProd = import_path2.default.join(MANIFESTS_DIR, "_production.json");
853
- if (import_fs2.default.existsSync(legacyProd)) import_fs2.default.unlinkSync(legacyProd);
901
+ if (!import_fs3.default.existsSync(MANIFESTS_DIR) && import_fs3.default.existsSync(LEGACY_PRESETS_DIR)) {
902
+ import_fs3.default.renameSync(LEGACY_PRESETS_DIR, MANIFESTS_DIR);
903
+ const legacyProd = import_path3.default.join(MANIFESTS_DIR, "_production.json");
904
+ if (import_fs3.default.existsSync(legacyProd)) import_fs3.default.unlinkSync(legacyProd);
854
905
  }
855
906
  manifestsResource.ensureDir();
856
- const defaultPath = import_path2.default.join(MANIFESTS_DIR, "default.json");
857
- if (!import_fs2.default.existsSync(defaultPath)) {
907
+ const defaultPath = import_path3.default.join(MANIFESTS_DIR, "default.json");
908
+ if (!import_fs3.default.existsSync(defaultPath)) {
858
909
  const componentConfigs = {};
859
910
  for (const comp of listComponentNames()) {
860
911
  componentConfigs[comp] = componentResource(comp).getActiveName();
@@ -867,30 +918,30 @@ function themeFileApi(opts) {
867
918
  theme: themesResource.getActiveName(),
868
919
  componentConfigs
869
920
  };
870
- import_fs2.default.writeFileSync(defaultPath, JSON.stringify(defaultManifest, null, 2));
921
+ import_fs3.default.writeFileSync(defaultPath, JSON.stringify(defaultManifest, null, 2));
871
922
  }
872
- if (!import_fs2.default.existsSync(manifestsResource.activePath)) {
873
- import_fs2.default.writeFileSync(
923
+ if (!import_fs3.default.existsSync(manifestsResource.activePath)) {
924
+ import_fs3.default.writeFileSync(
874
925
  manifestsResource.activePath,
875
926
  JSON.stringify({ activeFile: "default" })
876
927
  );
877
928
  } else {
878
929
  const activeName = manifestsResource.getActiveName();
879
- if (!import_fs2.default.existsSync(manifestsResource.filePath(activeName))) {
930
+ if (!import_fs3.default.existsSync(manifestsResource.filePath(activeName))) {
880
931
  manifestsResource.setActiveName("default");
881
932
  }
882
933
  }
883
- const stragglerProd = import_path2.default.join(MANIFESTS_DIR, "_production.json");
884
- if (import_fs2.default.existsSync(stragglerProd)) import_fs2.default.unlinkSync(stragglerProd);
934
+ const stragglerProd = import_path3.default.join(MANIFESTS_DIR, "_production.json");
935
+ if (import_fs3.default.existsSync(stragglerProd)) import_fs3.default.unlinkSync(stragglerProd);
885
936
  }
886
937
  function patchActiveManifest(field, comp, fileName) {
887
938
  const activeFile = manifestsResource.getActiveName();
888
939
  if (activeFile === "default") return false;
889
940
  const manifestPath = manifestsResource.filePath(activeFile);
890
- if (!import_fs2.default.existsSync(manifestPath)) return false;
941
+ if (!import_fs3.default.existsSync(manifestPath)) return false;
891
942
  let manifest;
892
943
  try {
893
- manifest = JSON.parse(import_fs2.default.readFileSync(manifestPath, "utf-8"));
944
+ manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
894
945
  } catch {
895
946
  return false;
896
947
  }
@@ -901,7 +952,7 @@ function themeFileApi(opts) {
901
952
  manifest.componentConfigs[comp] = fileName;
902
953
  }
903
954
  manifest.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
904
- import_fs2.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
955
+ import_fs3.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
905
956
  return true;
906
957
  }
907
958
  function formatAliasGradient(v) {
@@ -933,9 +984,9 @@ function themeFileApi(opts) {
933
984
  }
934
985
  function readComponentConfig(comp, name) {
935
986
  const filePath = componentResource(comp).filePath(name);
936
- if (!import_fs2.default.existsSync(filePath)) return null;
987
+ if (!import_fs3.default.existsSync(filePath)) return null;
937
988
  try {
938
- return JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8"));
989
+ return JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
939
990
  } catch {
940
991
  return null;
941
992
  }
@@ -961,9 +1012,9 @@ function themeFileApi(opts) {
961
1012
  const MANIFEST_BY_NAME_REGEX = new RegExp(`^${escapedBase}/manifests/([a-z0-9\\-_]+)$`);
962
1013
  async function handleListThemes(_ctx) {
963
1014
  const activeFile = themesResource.getActiveName();
964
- const files = import_fs2.default.readdirSync(THEMES_DIR).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
965
- const filePath = import_path2.default.join(THEMES_DIR, f);
966
- const data = JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8"));
1015
+ const files = import_fs3.default.readdirSync(THEMES_DIR).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
1016
+ const filePath = import_path3.default.join(THEMES_DIR, f);
1017
+ const data = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
967
1018
  const fileName = f.replace(".json", "");
968
1019
  return {
969
1020
  name: data.name || fileName,
@@ -977,18 +1028,18 @@ function themeFileApi(opts) {
977
1028
  async function handleGetActiveTheme({ res }) {
978
1029
  const activeFile = themesResource.getActiveName();
979
1030
  const filePath = themesResource.filePath(activeFile);
980
- if (!import_fs2.default.existsSync(filePath)) {
1031
+ if (!import_fs3.default.existsSync(filePath)) {
981
1032
  jsonResponse(res, 404, { error: "Active theme not found" });
982
1033
  return;
983
1034
  }
984
- const data = normalizeTheme(JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8")));
1035
+ const data = normalizeTheme(JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8")));
985
1036
  data._fileName = activeFile;
986
1037
  jsonResponse(res, 200, data);
987
1038
  }
988
1039
  async function handleSetActiveTheme({ req, res }) {
989
1040
  const body = JSON.parse(await readBody(req));
990
1041
  const fileName = sanitizeFileName(body.name || "default");
991
- if (!import_fs2.default.existsSync(themesResource.filePath(fileName))) {
1042
+ if (!import_fs3.default.existsSync(themesResource.filePath(fileName))) {
992
1043
  jsonResponse(res, 404, { error: "Theme not found" });
993
1044
  return;
994
1045
  }
@@ -998,11 +1049,11 @@ function themeFileApi(opts) {
998
1049
  async function handleGetProductionTheme({ res }) {
999
1050
  const prodFile = themesResource.getProductionName();
1000
1051
  const filePath = themesResource.filePath(prodFile);
1001
- if (!import_fs2.default.existsSync(filePath)) {
1052
+ if (!import_fs3.default.existsSync(filePath)) {
1002
1053
  jsonResponse(res, 200, { fileName: prodFile, name: prodFile, cssVariables: {} });
1003
1054
  return;
1004
1055
  }
1005
- const data = normalizeTheme(JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8")));
1056
+ const data = normalizeTheme(JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8")));
1006
1057
  jsonResponse(res, 200, {
1007
1058
  fileName: prodFile,
1008
1059
  name: data.name || prodFile,
@@ -1013,7 +1064,7 @@ function themeFileApi(opts) {
1013
1064
  async function handleSetProductionTheme({ req, res }) {
1014
1065
  const body = JSON.parse(await readBody(req));
1015
1066
  const fileName = sanitizeFileName(body.name || "default");
1016
- if (!import_fs2.default.existsSync(themesResource.filePath(fileName))) {
1067
+ if (!import_fs3.default.existsSync(themesResource.filePath(fileName))) {
1017
1068
  jsonResponse(res, 404, { error: "Theme not found" });
1018
1069
  return;
1019
1070
  }
@@ -1029,7 +1080,7 @@ function themeFileApi(opts) {
1029
1080
  syncFontsToCss(fileName);
1030
1081
  syncComponentsToCss();
1031
1082
  patchActiveManifest("theme", null, fileName);
1032
- const data = JSON.parse(import_fs2.default.readFileSync(themesResource.filePath(fileName), "utf-8"));
1083
+ const data = JSON.parse(import_fs3.default.readFileSync(themesResource.filePath(fileName), "utf-8"));
1033
1084
  jsonResponse(res, 200, {
1034
1085
  ok: true,
1035
1086
  fileName,
@@ -1041,11 +1092,11 @@ function themeFileApi(opts) {
1041
1092
  const [fileName] = params;
1042
1093
  const filePath = themesResource.filePath(fileName);
1043
1094
  if (req.method === "GET") {
1044
- if (!import_fs2.default.existsSync(filePath)) {
1095
+ if (!import_fs3.default.existsSync(filePath)) {
1045
1096
  jsonResponse(res, 404, { error: "Not found" });
1046
1097
  return;
1047
1098
  }
1048
- const data = normalizeTheme(JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8")));
1099
+ const data = normalizeTheme(JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8")));
1049
1100
  data._fileName = fileName;
1050
1101
  jsonResponse(res, 200, data);
1051
1102
  return;
@@ -1053,15 +1104,15 @@ function themeFileApi(opts) {
1053
1104
  if (req.method === "PUT") {
1054
1105
  const body = JSON.parse(await readBody(req));
1055
1106
  body.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1056
- if (import_fs2.default.existsSync(filePath)) {
1107
+ if (import_fs3.default.existsSync(filePath)) {
1057
1108
  try {
1058
- const existing = JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8"));
1109
+ const existing = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
1059
1110
  if (existing.createdAt) body.createdAt = existing.createdAt;
1060
1111
  } catch {
1061
1112
  }
1062
1113
  }
1063
1114
  if (!body.createdAt) body.createdAt = body.updatedAt;
1064
- import_fs2.default.writeFileSync(filePath, JSON.stringify(body, null, 2));
1115
+ import_fs3.default.writeFileSync(filePath, JSON.stringify(body, null, 2));
1065
1116
  if (fileName === themesResource.getProductionName()) {
1066
1117
  syncTokensToCss(fileName);
1067
1118
  syncFontsToCss(fileName);
@@ -1082,8 +1133,8 @@ function themeFileApi(opts) {
1082
1133
  });
1083
1134
  return;
1084
1135
  }
1085
- if (import_fs2.default.existsSync(filePath)) {
1086
- import_fs2.default.unlinkSync(filePath);
1136
+ if (import_fs3.default.existsSync(filePath)) {
1137
+ import_fs3.default.unlinkSync(filePath);
1087
1138
  if (themesResource.getActiveName() === fileName) {
1088
1139
  themesResource.setActiveName("default");
1089
1140
  }
@@ -1120,7 +1171,7 @@ function themeFileApi(opts) {
1120
1171
  const fileName = sanitizeFileName(body.name || "default");
1121
1172
  const r = componentResource(comp);
1122
1173
  const configPath = r.filePath(fileName);
1123
- if (!import_fs2.default.existsSync(configPath)) {
1174
+ if (!import_fs3.default.existsSync(configPath)) {
1124
1175
  jsonResponse(res, 404, { error: "Config not found" });
1125
1176
  return;
1126
1177
  }
@@ -1145,7 +1196,7 @@ function themeFileApi(opts) {
1145
1196
  const fileName = sanitizeFileName(body.name || "default");
1146
1197
  const r = componentResource(comp);
1147
1198
  const configPath = r.filePath(fileName);
1148
- if (!import_fs2.default.existsSync(configPath)) {
1199
+ if (!import_fs3.default.existsSync(configPath)) {
1149
1200
  jsonResponse(res, 404, { error: "Config not found" });
1150
1201
  return;
1151
1202
  }
@@ -1173,11 +1224,11 @@ function themeFileApi(opts) {
1173
1224
  const r = componentResource(comp);
1174
1225
  const configPath = r.filePath(name);
1175
1226
  if (req.method === "GET") {
1176
- if (!import_fs2.default.existsSync(configPath)) {
1227
+ if (!import_fs3.default.existsSync(configPath)) {
1177
1228
  jsonResponse(res, 404, { error: "Not found" });
1178
1229
  return;
1179
1230
  }
1180
- const data = JSON.parse(import_fs2.default.readFileSync(configPath, "utf-8"));
1231
+ const data = JSON.parse(import_fs3.default.readFileSync(configPath, "utf-8"));
1181
1232
  data._fileName = name;
1182
1233
  jsonResponse(res, 200, data);
1183
1234
  return;
@@ -1191,16 +1242,16 @@ function themeFileApi(opts) {
1191
1242
  body.component = comp;
1192
1243
  body.name = body.name || name;
1193
1244
  body.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1194
- if (import_fs2.default.existsSync(configPath)) {
1245
+ if (import_fs3.default.existsSync(configPath)) {
1195
1246
  try {
1196
- const existing = JSON.parse(import_fs2.default.readFileSync(configPath, "utf-8"));
1247
+ const existing = JSON.parse(import_fs3.default.readFileSync(configPath, "utf-8"));
1197
1248
  if (existing.createdAt) body.createdAt = existing.createdAt;
1198
1249
  } catch {
1199
1250
  }
1200
1251
  }
1201
1252
  if (!body.createdAt) body.createdAt = body.updatedAt;
1202
1253
  r.ensureDir();
1203
- import_fs2.default.writeFileSync(configPath, JSON.stringify(body, null, 2));
1254
+ import_fs3.default.writeFileSync(configPath, JSON.stringify(body, null, 2));
1204
1255
  if (r.getProductionName() === name) {
1205
1256
  syncComponentsToCss();
1206
1257
  }
@@ -1212,8 +1263,8 @@ function themeFileApi(opts) {
1212
1263
  jsonResponse(res, 403, { error: "Cannot delete default config" });
1213
1264
  return;
1214
1265
  }
1215
- if (import_fs2.default.existsSync(configPath)) {
1216
- import_fs2.default.unlinkSync(configPath);
1266
+ if (import_fs3.default.existsSync(configPath)) {
1267
+ import_fs3.default.unlinkSync(configPath);
1217
1268
  if (r.getActiveName() === name) {
1218
1269
  r.setActiveName("default");
1219
1270
  }
@@ -1229,15 +1280,15 @@ function themeFileApi(opts) {
1229
1280
  async function handleListComponentConfigs({ params, res }) {
1230
1281
  const [comp] = params;
1231
1282
  const r = componentResource(comp);
1232
- if (!import_fs2.default.existsSync(r.dir)) {
1283
+ if (!import_fs3.default.existsSync(r.dir)) {
1233
1284
  jsonResponse(res, 404, { error: "Component not found" });
1234
1285
  return;
1235
1286
  }
1236
1287
  const activeFile = r.getActiveName();
1237
1288
  const productionFile = r.getProductionName();
1238
- const files = import_fs2.default.readdirSync(r.dir).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
1239
- const filePath = import_path2.default.join(r.dir, f);
1240
- const data = JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8"));
1289
+ const files = import_fs3.default.readdirSync(r.dir).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
1290
+ const filePath = import_path3.default.join(r.dir, f);
1291
+ const data = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
1241
1292
  const fileName = f.replace(".json", "");
1242
1293
  return {
1243
1294
  name: data.name || fileName,
@@ -1251,9 +1302,9 @@ function themeFileApi(opts) {
1251
1302
  }
1252
1303
  async function handleListManifests({ res }) {
1253
1304
  const activeFile = manifestsResource.getActiveName();
1254
- const files = import_fs2.default.readdirSync(MANIFESTS_DIR).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
1255
- const filePath = import_path2.default.join(MANIFESTS_DIR, f);
1256
- const data = JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8"));
1305
+ const files = import_fs3.default.readdirSync(MANIFESTS_DIR).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
1306
+ const filePath = import_path3.default.join(MANIFESTS_DIR, f);
1307
+ const data = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
1257
1308
  const fileName = f.replace(".json", "");
1258
1309
  return {
1259
1310
  name: data.name || fileName,
@@ -1268,18 +1319,18 @@ function themeFileApi(opts) {
1268
1319
  async function handleGetActiveManifest({ res }) {
1269
1320
  const activeFile = manifestsResource.getActiveName();
1270
1321
  const filePath = manifestsResource.filePath(activeFile);
1271
- if (!import_fs2.default.existsSync(filePath)) {
1322
+ if (!import_fs3.default.existsSync(filePath)) {
1272
1323
  jsonResponse(res, 404, { error: "Active manifest not found" });
1273
1324
  return;
1274
1325
  }
1275
- const data = JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8"));
1326
+ const data = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
1276
1327
  data._fileName = activeFile;
1277
1328
  jsonResponse(res, 200, data);
1278
1329
  }
1279
1330
  async function handleSetActiveManifest({ req, res }) {
1280
1331
  const body = JSON.parse(await readBody(req));
1281
1332
  const fileName = sanitizeFileName(body.name || "default");
1282
- if (!import_fs2.default.existsSync(manifestsResource.filePath(fileName))) {
1333
+ if (!import_fs3.default.existsSync(manifestsResource.filePath(fileName))) {
1283
1334
  jsonResponse(res, 404, { error: "Manifest not found" });
1284
1335
  return;
1285
1336
  }
@@ -1290,11 +1341,11 @@ function themeFileApi(opts) {
1290
1341
  const [fileName] = params;
1291
1342
  const filePath = manifestsResource.filePath(fileName);
1292
1343
  if (req.method === "GET") {
1293
- if (!import_fs2.default.existsSync(filePath)) {
1344
+ if (!import_fs3.default.existsSync(filePath)) {
1294
1345
  jsonResponse(res, 404, { error: "Not found" });
1295
1346
  return;
1296
1347
  }
1297
- const data = JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8"));
1348
+ const data = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
1298
1349
  data._fileName = fileName;
1299
1350
  jsonResponse(res, 200, data);
1300
1351
  return;
@@ -1306,15 +1357,15 @@ function themeFileApi(opts) {
1306
1357
  }
1307
1358
  const body = JSON.parse(await readBody(req));
1308
1359
  body.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1309
- if (import_fs2.default.existsSync(filePath)) {
1360
+ if (import_fs3.default.existsSync(filePath)) {
1310
1361
  try {
1311
- const existing = JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8"));
1362
+ const existing = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
1312
1363
  if (existing.createdAt) body.createdAt = existing.createdAt;
1313
1364
  } catch {
1314
1365
  }
1315
1366
  }
1316
1367
  if (!body.createdAt) body.createdAt = body.updatedAt;
1317
- import_fs2.default.writeFileSync(filePath, JSON.stringify(body, null, 2));
1368
+ import_fs3.default.writeFileSync(filePath, JSON.stringify(body, null, 2));
1318
1369
  jsonResponse(res, 200, { ok: true, fileName });
1319
1370
  return;
1320
1371
  }
@@ -1323,8 +1374,8 @@ function themeFileApi(opts) {
1323
1374
  jsonResponse(res, 403, { error: "Cannot delete the default manifest" });
1324
1375
  return;
1325
1376
  }
1326
- if (import_fs2.default.existsSync(filePath)) {
1327
- import_fs2.default.unlinkSync(filePath);
1377
+ if (import_fs3.default.existsSync(filePath)) {
1378
+ import_fs3.default.unlinkSync(filePath);
1328
1379
  if (manifestsResource.getActiveName() === fileName) {
1329
1380
  manifestsResource.setActiveName("default");
1330
1381
  }
@@ -1336,14 +1387,14 @@ function themeFileApi(opts) {
1336
1387
  async function handleApplyManifest({ params, res }) {
1337
1388
  const [fileName] = params;
1338
1389
  const manifestPath = manifestsResource.filePath(fileName);
1339
- if (!import_fs2.default.existsSync(manifestPath)) {
1390
+ if (!import_fs3.default.existsSync(manifestPath)) {
1340
1391
  jsonResponse(res, 404, { error: "Manifest not found" });
1341
1392
  return;
1342
1393
  }
1343
- const manifest = JSON.parse(import_fs2.default.readFileSync(manifestPath, "utf-8"));
1394
+ const manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
1344
1395
  const themeName = sanitizeFileName(manifest.theme || "default");
1345
1396
  const themePath = themesResource.filePath(themeName);
1346
- if (!import_fs2.default.existsSync(themePath)) {
1397
+ if (!import_fs3.default.existsSync(themePath)) {
1347
1398
  jsonResponse(res, 422, { error: `Manifest references missing theme: ${themeName}` });
1348
1399
  return;
1349
1400
  }
@@ -1356,7 +1407,7 @@ function themeFileApi(opts) {
1356
1407
  const sanitized = sanitizeFileName(String(configFile) || "default");
1357
1408
  const r = componentResource(comp);
1358
1409
  const cfgPath = r.filePath(sanitized);
1359
- if (!import_fs2.default.existsSync(cfgPath)) {
1410
+ if (!import_fs3.default.existsSync(cfgPath)) {
1360
1411
  jsonResponse(res, 422, {
1361
1412
  error: `Manifest references missing config: ${comp}/${sanitized}`
1362
1413
  });
@@ -1368,7 +1419,7 @@ function themeFileApi(opts) {
1368
1419
  themesResource.setProductionName(themeName);
1369
1420
  syncTokensToCss(themeName);
1370
1421
  syncFontsToCss(themeName);
1371
- const themeData = normalizeTheme(JSON.parse(import_fs2.default.readFileSync(themePath, "utf-8")));
1422
+ const themeData = normalizeTheme(JSON.parse(import_fs3.default.readFileSync(themePath, "utf-8")));
1372
1423
  themeData._fileName = themeName;
1373
1424
  for (const [comp, configFile] of apply) {
1374
1425
  const r = componentResource(comp);
@@ -1395,18 +1446,18 @@ function themeFileApi(opts) {
1395
1446
  async function handleExportManifest({ params, res }) {
1396
1447
  const [fileName] = params;
1397
1448
  const manifestPath = manifestsResource.filePath(fileName);
1398
- if (!import_fs2.default.existsSync(manifestPath)) {
1449
+ if (!import_fs3.default.existsSync(manifestPath)) {
1399
1450
  jsonResponse(res, 404, { error: "Manifest not found" });
1400
1451
  return;
1401
1452
  }
1402
- const manifest = JSON.parse(import_fs2.default.readFileSync(manifestPath, "utf-8"));
1453
+ const manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
1403
1454
  const themeName = sanitizeFileName(manifest.theme || "default");
1404
1455
  const themePath = themesResource.filePath(themeName);
1405
- if (!import_fs2.default.existsSync(themePath)) {
1456
+ if (!import_fs3.default.existsSync(themePath)) {
1406
1457
  jsonResponse(res, 422, { error: `Manifest references missing theme: ${themeName}` });
1407
1458
  return;
1408
1459
  }
1409
- const theme = JSON.parse(import_fs2.default.readFileSync(themePath, "utf-8"));
1460
+ const theme = JSON.parse(import_fs3.default.readFileSync(themePath, "utf-8"));
1410
1461
  const knownComponents = new Set(listComponentNames());
1411
1462
  const componentConfigs = {};
1412
1463
  for (const [comp, configFile] of Object.entries(manifest.componentConfigs ?? {})) {
@@ -1414,13 +1465,13 @@ function themeFileApi(opts) {
1414
1465
  const sanitized = sanitizeFileName(String(configFile) || "default");
1415
1466
  if (sanitized === "default") continue;
1416
1467
  const cfgPath = componentResource(comp).filePath(sanitized);
1417
- if (!import_fs2.default.existsSync(cfgPath)) {
1468
+ if (!import_fs3.default.existsSync(cfgPath)) {
1418
1469
  jsonResponse(res, 422, {
1419
1470
  error: `Manifest references missing config: ${comp}/${sanitized}`
1420
1471
  });
1421
1472
  return;
1422
1473
  }
1423
- const cfg = JSON.parse(import_fs2.default.readFileSync(cfgPath, "utf-8"));
1474
+ const cfg = JSON.parse(import_fs3.default.readFileSync(cfgPath, "utf-8"));
1424
1475
  componentConfigs[`${comp}/${sanitized}`] = cfg;
1425
1476
  }
1426
1477
  const bundle = {
@@ -1442,7 +1493,7 @@ function themeFileApi(opts) {
1442
1493
  }
1443
1494
  function nextAvailableName2(resourceFilePath, baseName) {
1444
1495
  return nextAvailableName(
1445
- (n) => import_fs2.default.existsSync(resourceFilePath(n)),
1496
+ (n) => import_fs3.default.existsSync(resourceFilePath(n)),
1446
1497
  sanitizeFileName(baseName)
1447
1498
  );
1448
1499
  }
@@ -1484,7 +1535,7 @@ function themeFileApi(opts) {
1484
1535
  themeBody.updatedAt = now;
1485
1536
  if (!themeBody.createdAt) themeBody.createdAt = now;
1486
1537
  themesResource.ensureDir();
1487
- import_fs2.default.writeFileSync(themesResource.filePath(finalThemeName), JSON.stringify(themeBody, null, 2));
1538
+ import_fs3.default.writeFileSync(themesResource.filePath(finalThemeName), JSON.stringify(themeBody, null, 2));
1488
1539
  const knownComponents = new Set(listComponentNames());
1489
1540
  const componentRenames = {};
1490
1541
  for (const [key, cfgValue] of Object.entries(bundle.componentConfigs)) {
@@ -1506,7 +1557,7 @@ function themeFileApi(opts) {
1506
1557
  cfgBody.updatedAt = now;
1507
1558
  if (!cfgBody.createdAt) cfgBody.createdAt = now;
1508
1559
  r.ensureDir();
1509
- import_fs2.default.writeFileSync(r.filePath(finalName), JSON.stringify(cfgBody, null, 2));
1560
+ import_fs3.default.writeFileSync(r.filePath(finalName), JSON.stringify(cfgBody, null, 2));
1510
1561
  }
1511
1562
  const rewrittenManifest = {
1512
1563
  ...bundle.manifest,
@@ -1533,7 +1584,7 @@ function themeFileApi(opts) {
1533
1584
  renames[`manifest:${originalManifestName}`] = finalManifestName;
1534
1585
  }
1535
1586
  manifestsResource.ensureDir();
1536
- import_fs2.default.writeFileSync(
1587
+ import_fs3.default.writeFileSync(
1537
1588
  manifestsResource.filePath(finalManifestName),
1538
1589
  JSON.stringify(rewrittenManifest, null, 2)
1539
1590
  );
@@ -1606,7 +1657,8 @@ function themeFileApi(opts) {
1606
1657
  return {
1607
1658
  define: {
1608
1659
  __PROJECT_ROOT__: JSON.stringify(process.cwd()),
1609
- __APP_VERSION__: JSON.stringify(PKG_VERSION)
1660
+ __APP_VERSION__: JSON.stringify(PKG_VERSION),
1661
+ __LIVE_TOKENS_API_BASE__: JSON.stringify(API_BASE)
1610
1662
  }
1611
1663
  };
1612
1664
  },
@@ -1621,7 +1673,7 @@ function themeFileApi(opts) {
1621
1673
  });
1622
1674
  },
1623
1675
  handleHotUpdate(ctx) {
1624
- const normalized = import_path2.default.resolve(ctx.file);
1676
+ const normalized = import_path3.default.resolve(ctx.file);
1625
1677
  if (!normalized.startsWith(COMPONENTS_SRC_DIR)) return;
1626
1678
  if (!normalized.endsWith(".svelte")) return;
1627
1679
  const comp = componentNameFromFile(normalized);