inventive-ui 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import path25 from "path";
4
+ import path27 from "path";
5
5
  import { Command } from "commander";
6
6
 
7
7
  // src/utils/ui.ts
@@ -190,7 +190,7 @@ var BANNER_COMPACT = [
190
190
  var FULL_BANNER_WIDTH = 101;
191
191
  function resolveCliVersion() {
192
192
  try {
193
- return true ? "0.0.2" : "1.0.0";
193
+ return true ? "0.0.4" : "1.0.0";
194
194
  } catch {
195
195
  return "1.0.0";
196
196
  }
@@ -373,8 +373,8 @@ function resolveApiBaseUrl() {
373
373
  );
374
374
  }
375
375
  if (parsed.pathname && parsed.pathname !== "/" && parsed.pathname !== "") {
376
- const path26 = parsed.pathname.replace(/\/+$/, "");
377
- if (path26 && !/^\/[a-zA-Z0-9._/-]+$/.test(path26)) {
376
+ const path28 = parsed.pathname.replace(/\/+$/, "");
377
+ if (path28 && !/^\/[a-zA-Z0-9._/-]+$/.test(path28)) {
378
378
  throw new CLIError(
379
379
  "IUI_API_URL path contains invalid characters.",
380
380
  "Use a simple path prefix such as /v1"
@@ -633,7 +633,7 @@ var ASSET_CATEGORY_LABELS = {
633
633
  };
634
634
 
635
635
  // src/utils/filesystem.ts
636
- import path9 from "path";
636
+ import path10 from "path";
637
637
  import { fileURLToPath as fileURLToPath2 } from "url";
638
638
  import os3 from "os";
639
639
  import fs8 from "fs-extra";
@@ -1046,8 +1046,8 @@ function listIuiInitializedPackages(startCwd) {
1046
1046
  );
1047
1047
  if (initialized.length > 0) return initialized;
1048
1048
  }
1049
- const iuiRoot = findIuiProjectRoot(startCwd);
1050
- return iuiRoot ? [iuiRoot] : [];
1049
+ const iuiRoot2 = findIuiProjectRoot(startCwd);
1050
+ return iuiRoot2 ? [iuiRoot2] : [];
1051
1051
  }
1052
1052
  function resolveSetupDoctorTargets(cwd) {
1053
1053
  const resolved = path5.resolve(cwd);
@@ -2558,6 +2558,19 @@ var ComponentConfigEntrySchema = z2.object({
2558
2558
  presets: z2.record(z2.unknown()).optional()
2559
2559
  }).catchall(z2.unknown());
2560
2560
  var ComponentConfigSchema = z2.record(ComponentConfigEntrySchema);
2561
+ var ProjectMetaSchema = z2.object({
2562
+ projectId: z2.string().min(1),
2563
+ repoUrl: z2.string().min(1),
2564
+ createdAt: z2.string().min(1),
2565
+ initScope: z2.enum(["package", "workspace"]).optional(),
2566
+ configs: z2.object({
2567
+ theme: z2.string().min(1),
2568
+ assets: z2.string().min(1),
2569
+ components: z2.string().min(1)
2570
+ }).strict().optional()
2571
+ }).strict().refine((data) => !("theme" in data) && !("assets" in data), {
2572
+ message: "project.json must not contain config values \u2014 use configs paths only"
2573
+ });
2561
2574
  function formatZodIssues(error) {
2562
2575
  return error.issues.slice(0, 8).map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
2563
2576
  }
@@ -2726,12 +2739,59 @@ function checkComponentConfigTierBleed(cwd = process.cwd()) {
2726
2739
  };
2727
2740
  }
2728
2741
 
2742
+ // src/services/iui-paths.ts
2743
+ import path9 from "path";
2744
+ var IUI_CACHE_SEGMENT = "cache";
2745
+ var IUI_CACHE_FILES = {
2746
+ scan: "scan.cache.json",
2747
+ styles: "styles.css",
2748
+ manifest: "manifest.js",
2749
+ stylesInject: "styles.inject.js",
2750
+ stylesInline: "styles.inline.js",
2751
+ slotState: "slot-state.json",
2752
+ slotLock: "slot.lock",
2753
+ utilities: "utilities.css",
2754
+ manifestJson: "manifest.json",
2755
+ slotWarmup: "slot-warmup.mjs"
2756
+ };
2757
+ function iuiProjectRoot(cwd = process.cwd()) {
2758
+ return resolveIuiProjectRoot(cwd);
2759
+ }
2760
+ function iuiRoot(cwd = process.cwd()) {
2761
+ return path9.join(iuiProjectRoot(cwd), IUI_DIR);
2762
+ }
2763
+ function iuiCacheDir(cwd = process.cwd()) {
2764
+ return path9.join(iuiRoot(cwd), IUI_CACHE_SEGMENT);
2765
+ }
2766
+ function iuiCacheFile(cwd, name) {
2767
+ return path9.join(iuiCacheDir(cwd), IUI_CACHE_FILES[name]);
2768
+ }
2769
+ var IUI_CACHE_GITIGNORE_LINES = [
2770
+ "",
2771
+ "# IUI disposable cache (.iui/generated/ stays committed)",
2772
+ `${IUI_DIR}/${IUI_CACHE_SEGMENT}/`,
2773
+ `${IUI_DIR}/slot-registration-state.json`,
2774
+ `${IUI_DIR}/slot-registration.lock`,
2775
+ `${IUI_DIR}/classes.cache.json`,
2776
+ `${IUI_DIR}/utilities.css`,
2777
+ `${IUI_DIR}/build-styles.generated.css`,
2778
+ `${IUI_DIR}/build-styles.generated.js`,
2779
+ `${IUI_DIR}/build-manifest.generated.js`,
2780
+ `${IUI_DIR}/build-css-inline.js`,
2781
+ `${IUI_DIR}/build-manifest.json`,
2782
+ `${IUI_DIR}/slot-warmup.generated.mjs`,
2783
+ ".iui-bootstrap-client.js",
2784
+ ".iui-bootstrap-server.js",
2785
+ ".iui-bootstrap.js",
2786
+ "public/iui/"
2787
+ ];
2788
+
2729
2789
  // src/utils/filesystem.ts
2730
2790
  function globalConfigPath() {
2731
- return path9.join(os3.homedir(), GLOBAL_CONFIG_DIR, "config.json");
2791
+ return path10.join(os3.homedir(), GLOBAL_CONFIG_DIR, "config.json");
2732
2792
  }
2733
2793
  function globalSecretsPath() {
2734
- return path9.join(os3.homedir(), GLOBAL_CONFIG_DIR, "secrets.json");
2794
+ return path10.join(os3.homedir(), GLOBAL_CONFIG_DIR, "secrets.json");
2735
2795
  }
2736
2796
  function readSecretsFile() {
2737
2797
  const p = globalSecretsPath();
@@ -2786,10 +2846,10 @@ function removeGlobalConfig() {
2786
2846
  if (fs8.existsSync(s)) fs8.removeSync(s);
2787
2847
  }
2788
2848
  function iuiDir(cwd = process.cwd()) {
2789
- return path9.join(resolveIuiProjectRoot(cwd), IUI_DIR);
2849
+ return path10.join(resolveIuiProjectRoot(cwd), IUI_DIR);
2790
2850
  }
2791
2851
  function metaPath(file, cwd) {
2792
- return path9.join(iuiDir(cwd ?? process.cwd()), file);
2852
+ return path10.join(iuiDir(cwd ?? process.cwd()), file);
2793
2853
  }
2794
2854
  function projectMetaPath(cwd) {
2795
2855
  return metaPath("project.json", cwd);
@@ -2849,10 +2909,10 @@ function writePackageManifest(manifest, cwd) {
2849
2909
  writeJson(packageManifestPath(cwd), manifest);
2850
2910
  }
2851
2911
  function getCliTemplatesDir() {
2852
- return path9.join(path9.dirname(fileURLToPath2(import.meta.url)), "..", "templates");
2912
+ return path10.join(path10.dirname(fileURLToPath2(import.meta.url)), "..", "templates");
2853
2913
  }
2854
2914
  function loadAssetsConfigTemplate() {
2855
- const templatePath = path9.join(getCliTemplatesDir(), "assets.config.defaults.json");
2915
+ const templatePath = path10.join(getCliTemplatesDir(), "assets.config.defaults.json");
2856
2916
  if (!fs8.existsSync(templatePath)) return {};
2857
2917
  try {
2858
2918
  return fs8.readJsonSync(templatePath);
@@ -2861,7 +2921,7 @@ function loadAssetsConfigTemplate() {
2861
2921
  }
2862
2922
  }
2863
2923
  function loadComponentConfigPresetsTemplate() {
2864
- const templatePath = path9.join(getCliTemplatesDir(), "component.config.presets.json");
2924
+ const templatePath = path10.join(getCliTemplatesDir(), "component.config.presets.json");
2865
2925
  if (!fs8.existsSync(templatePath)) return {};
2866
2926
  try {
2867
2927
  return fs8.readJsonSync(templatePath);
@@ -2918,7 +2978,7 @@ function seedAssetsOutputFromTemplate(output) {
2918
2978
  }
2919
2979
  }
2920
2980
  function assetsConfigPath(cwd) {
2921
- return path9.join(resolveIuiProjectRoot(cwd ?? process.cwd()), ASSETS_CONFIG_FILE);
2981
+ return path10.join(resolveIuiProjectRoot(cwd ?? process.cwd()), ASSETS_CONFIG_FILE);
2922
2982
  }
2923
2983
  function readExistingAssetsConfigRaw(cwd) {
2924
2984
  const p = assetsConfigPath(cwd);
@@ -3081,7 +3141,7 @@ function writeAssetsConfig(cwd = process.cwd()) {
3081
3141
  seedAssetsOutputFromTemplate(output);
3082
3142
  writeJson(assetsConfigPath(cwd), output);
3083
3143
  try {
3084
- const legacyIconDefaults = path9.join(cwd ?? process.cwd(), IUI_DIR, "icon-defaults.json");
3144
+ const legacyIconDefaults = path10.join(cwd ?? process.cwd(), IUI_DIR, "icon-defaults.json");
3085
3145
  if (fs8.existsSync(legacyIconDefaults)) fs8.removeSync(legacyIconDefaults);
3086
3146
  } catch {
3087
3147
  }
@@ -3097,7 +3157,7 @@ function writeSlotManifest(manifest, cwd) {
3097
3157
  function readComponentPackageManifest(cwd = process.cwd()) {
3098
3158
  const pkgDir = resolvePackageDir("@inventive-ui/components", cwd);
3099
3159
  if (!pkgDir) return null;
3100
- const p = path9.join(pkgDir, "iui-manifest.json");
3160
+ const p = path10.join(pkgDir, "iui-manifest.json");
3101
3161
  if (!fs8.existsSync(p)) return null;
3102
3162
  try {
3103
3163
  const raw = fs8.readJsonSync(p);
@@ -3113,7 +3173,7 @@ function readComponentPackageManifest(cwd = process.cwd()) {
3113
3173
  function getInstalledPackageVersion(packageName, cwd = process.cwd()) {
3114
3174
  const pkgDir = resolvePackageDir(packageName, cwd);
3115
3175
  if (!pkgDir) return null;
3116
- const pkgPath = path9.join(pkgDir, "package.json");
3176
+ const pkgPath = path10.join(pkgDir, "package.json");
3117
3177
  if (!fs8.existsSync(pkgPath)) return null;
3118
3178
  try {
3119
3179
  const pkg = fs8.readJsonSync(pkgPath);
@@ -3131,11 +3191,11 @@ function registryItemsMap(manifest) {
3131
3191
  return map;
3132
3192
  }
3133
3193
  function writeProjectConfig(cwd = process.cwd()) {
3134
- const configPath = path9.join(cwd, PROJECT_CONFIG_FILE);
3194
+ const configPath = path10.join(cwd, PROJECT_CONFIG_FILE);
3135
3195
  atomicWriteFile(configPath, buildProjectConfigSource(cwd));
3136
3196
  }
3137
3197
  function ensureProjectConfigBuildBlock(cwd = process.cwd()) {
3138
- const configPath = path9.join(resolveIuiProjectRoot(cwd), PROJECT_CONFIG_FILE);
3198
+ const configPath = path10.join(resolveIuiProjectRoot(cwd), PROJECT_CONFIG_FILE);
3139
3199
  if (!fs8.existsSync(configPath)) return false;
3140
3200
  const before = fs8.readFileSync(configPath, "utf-8");
3141
3201
  const result = patchProjectConfigBuildBlock(before);
@@ -3145,7 +3205,7 @@ function ensureProjectConfigBuildBlock(cwd = process.cwd()) {
3145
3205
  }
3146
3206
  function ensureProjectConfig(cwd = process.cwd()) {
3147
3207
  const root = resolveIuiProjectRoot(cwd);
3148
- const configPath = path9.join(root, PROJECT_CONFIG_FILE);
3208
+ const configPath = path10.join(root, PROJECT_CONFIG_FILE);
3149
3209
  if (!fs8.existsSync(configPath)) {
3150
3210
  writeProjectConfig(root);
3151
3211
  return "scaffolded";
@@ -3173,7 +3233,7 @@ function isIuiManagedOrMinimalScaffold(content) {
3173
3233
  function removeStaleIuiViteConfig(cwd = process.cwd()) {
3174
3234
  if (projectHasViteTooling(cwd)) return false;
3175
3235
  let removed = false;
3176
- const configPath = path9.join(cwd, "vite.config.ts");
3236
+ const configPath = path10.join(cwd, "vite.config.ts");
3177
3237
  if (fs8.existsSync(configPath)) {
3178
3238
  const existing = fs8.readFileSync(configPath, "utf-8");
3179
3239
  if (isIuiManagedOrMinimalScaffold(existing)) {
@@ -3181,7 +3241,7 @@ function removeStaleIuiViteConfig(cwd = process.cwd()) {
3181
3241
  removed = true;
3182
3242
  }
3183
3243
  }
3184
- const nodeTsPath = path9.join(cwd, "tsconfig.node.json");
3244
+ const nodeTsPath = path10.join(cwd, "tsconfig.node.json");
3185
3245
  if (fs8.existsSync(nodeTsPath)) {
3186
3246
  try {
3187
3247
  const nodeTs = fs8.readJsonSync(nodeTsPath);
@@ -3196,7 +3256,7 @@ function removeStaleIuiViteConfig(cwd = process.cwd()) {
3196
3256
  return removed;
3197
3257
  }
3198
3258
  function writeTsConfigNode(cwd = process.cwd()) {
3199
- const nodeTsPath = path9.join(cwd, "tsconfig.node.json");
3259
+ const nodeTsPath = path10.join(cwd, "tsconfig.node.json");
3200
3260
  const content = {
3201
3261
  compilerOptions: {
3202
3262
  target: "ES2022",
@@ -3216,7 +3276,7 @@ function writeTsConfigNode(cwd = process.cwd()) {
3216
3276
  atomicWriteJson(nodeTsPath, content);
3217
3277
  }
3218
3278
  function writeTsConfig(framework, cwd = process.cwd()) {
3219
- const tsconfigPath = path9.join(cwd, "tsconfig.json");
3279
+ const tsconfigPath = path10.join(cwd, "tsconfig.json");
3220
3280
  let existing = {};
3221
3281
  if (fs8.existsSync(tsconfigPath)) {
3222
3282
  try {
@@ -3284,7 +3344,7 @@ function writeTsConfig(framework, cwd = process.cwd()) {
3284
3344
  atomicWriteJson(tsconfigPath, output);
3285
3345
  }
3286
3346
  function writeComponentConfig(manifest, cwd = process.cwd()) {
3287
- const configPath = path9.join(cwd, COMPONENT_CONFIG_FILE);
3347
+ const configPath = path10.join(cwd, COMPONENT_CONFIG_FILE);
3288
3348
  let entries = "";
3289
3349
  const typedEntries = [];
3290
3350
  const typeImports = [];
@@ -3337,7 +3397,7 @@ ${entries}};
3337
3397
  atomicWriteFile(configPath, content);
3338
3398
  }
3339
3399
  function ensureComponentConfig(manifest, cwd = process.cwd(), options = {}) {
3340
- const configPath = path9.join(cwd, COMPONENT_CONFIG_FILE);
3400
+ const configPath = path10.join(cwd, COMPONENT_CONFIG_FILE);
3341
3401
  if (options.force || !fs8.existsSync(configPath)) {
3342
3402
  const existed = fs8.existsSync(configPath);
3343
3403
  writeComponentConfig(manifest, cwd);
@@ -3354,7 +3414,7 @@ function isInsideProject(cwd = process.cwd()) {
3354
3414
  }
3355
3415
  function detectRepoUrl(cwd = process.cwd()) {
3356
3416
  try {
3357
- const gitConfigPath = path9.join(cwd, ".git", "config");
3417
+ const gitConfigPath = path10.join(cwd, ".git", "config");
3358
3418
  if (!fs8.existsSync(gitConfigPath)) return cwd;
3359
3419
  const gitConfig = fs8.readFileSync(gitConfigPath, "utf-8");
3360
3420
  const match = gitConfig.match(/url\s*=\s*(.+)/);
@@ -3364,11 +3424,11 @@ function detectRepoUrl(cwd = process.cwd()) {
3364
3424
  }
3365
3425
  }
3366
3426
  function hasPackageJson(cwd = process.cwd()) {
3367
- return fs8.existsSync(path9.join(cwd, "package.json"));
3427
+ return fs8.existsSync(path10.join(cwd, "package.json"));
3368
3428
  }
3369
3429
  function cleanupLegacyFrameworkMeta(cwd = process.cwd()) {
3370
3430
  try {
3371
- const legacyPath = path9.join(cwd, IUI_DIR, "framework.json");
3431
+ const legacyPath = path10.join(cwd, IUI_DIR, "framework.json");
3372
3432
  if (fs8.existsSync(legacyPath)) fs8.removeSync(legacyPath);
3373
3433
  } catch {
3374
3434
  }
@@ -3385,7 +3445,7 @@ var LOCKFILES = [
3385
3445
  ];
3386
3446
  var PM_PRIORITY = ["bun", "pnpm", "yarn", "npm"];
3387
3447
  function readPackageManagerField(cwd) {
3388
- const pkgPath = path9.join(cwd, "package.json");
3448
+ const pkgPath = path10.join(cwd, "package.json");
3389
3449
  if (!fs8.existsSync(pkgPath)) return null;
3390
3450
  try {
3391
3451
  const pkg = fs8.readJsonSync(pkgPath);
@@ -3401,11 +3461,11 @@ function readPackageManagerField(cwd) {
3401
3461
  }
3402
3462
  function detectPackageManagerWithMeta(cwd = process.cwd()) {
3403
3463
  const warnings = [];
3404
- const root = findWorkspaceRoot(cwd) ?? path9.resolve(cwd);
3464
+ const root = findWorkspaceRoot(cwd) ?? path10.resolve(cwd);
3405
3465
  const declared = readPackageManagerField(root);
3406
3466
  const presentLockPms = [
3407
3467
  ...new Set(
3408
- LOCKFILES.filter(({ file }) => fs8.existsSync(path9.join(root, file))).map(
3468
+ LOCKFILES.filter(({ file }) => fs8.existsSync(path10.join(root, file))).map(
3409
3469
  ({ pm }) => pm
3410
3470
  )
3411
3471
  )
@@ -3449,7 +3509,7 @@ function installCmd(pm, pkg, cwd) {
3449
3509
  if (cwd) {
3450
3510
  const { commandCwd, workspaceName } = resolveWorkspaceInstallRouting(cwd);
3451
3511
  if (workspaceName) {
3452
- const fromRoot = path9.resolve(commandCwd) !== path9.resolve(cwd) ? ` (run from ${commandCwd})` : "";
3512
+ const fromRoot = path10.resolve(commandCwd) !== path10.resolve(cwd) ? ` (run from ${commandCwd})` : "";
3453
3513
  switch (pm) {
3454
3514
  case "yarn":
3455
3515
  return `yarn workspace ${workspaceName} add ${pkg}${fromRoot}`;
@@ -3486,7 +3546,7 @@ function installDevCmd(pm, pkg) {
3486
3546
  }
3487
3547
  }
3488
3548
  function runTarballInstall(pm, tarballPath, cwd) {
3489
- const resolvedTarball = path9.resolve(tarballPath);
3549
+ const resolvedTarball = path10.resolve(tarballPath);
3490
3550
  if (!fs8.existsSync(resolvedTarball)) {
3491
3551
  throw new CLIError(`Tarball not found: ${resolvedTarball}`);
3492
3552
  }
@@ -3501,7 +3561,7 @@ function runSyncInstall2(pm, cwd) {
3501
3561
  runSyncInstall(pm, resolveDependencyInstallRoot(cwd));
3502
3562
  }
3503
3563
  function fixTarballDep(packageName, version, cwd = process.cwd()) {
3504
- const pkgPath = path9.join(cwd, "package.json");
3564
+ const pkgPath = path10.join(cwd, "package.json");
3505
3565
  if (!fs8.existsSync(pkgPath)) return;
3506
3566
  try {
3507
3567
  const pkg = fs8.readJsonSync(pkgPath);
@@ -3523,7 +3583,7 @@ function npmrcAuthLine(token) {
3523
3583
  }
3524
3584
  function ensureProjectNpmrc(cwd = process.cwd()) {
3525
3585
  const configRoot = resolveProjectConfigRoot(cwd);
3526
- const npmrcPath = path9.join(configRoot, ".npmrc");
3586
+ const npmrcPath = path10.join(configRoot, ".npmrc");
3527
3587
  let content = "";
3528
3588
  if (fs8.existsSync(npmrcPath)) {
3529
3589
  content = fs8.readFileSync(npmrcPath, "utf-8");
@@ -3542,7 +3602,7 @@ function ensureProjectNpmrc(cwd = process.cwd()) {
3542
3602
  atomicWriteFile(npmrcPath, result);
3543
3603
  }
3544
3604
  function writeGlobalNpmrcAuth(token) {
3545
- const globalNpmrc = path9.join(os3.homedir(), ".npmrc");
3605
+ const globalNpmrc = path10.join(os3.homedir(), ".npmrc");
3546
3606
  let content = "";
3547
3607
  if (fs8.existsSync(globalNpmrc)) {
3548
3608
  content = fs8.readFileSync(globalNpmrc, "utf-8");
@@ -3558,7 +3618,7 @@ function writeGlobalNpmrcAuth(token) {
3558
3618
  writeFileRestricted(globalNpmrc, result);
3559
3619
  }
3560
3620
  function removeGlobalNpmrcAuth() {
3561
- const globalNpmrc = path9.join(os3.homedir(), ".npmrc");
3621
+ const globalNpmrc = path10.join(os3.homedir(), ".npmrc");
3562
3622
  if (!fs8.existsSync(globalNpmrc)) return;
3563
3623
  const content = fs8.readFileSync(globalNpmrc, "utf-8");
3564
3624
  const url = new URL(`${API_BASE_URL}/registry/npm`);
@@ -3576,7 +3636,7 @@ function removeGlobalNpmrcAuth() {
3576
3636
  }
3577
3637
  function ensureGitignoreHasNpmrc(cwd = process.cwd()) {
3578
3638
  const configRoot = resolveProjectConfigRoot(cwd);
3579
- const giPath = path9.join(configRoot, ".gitignore");
3639
+ const giPath = path10.join(configRoot, ".gitignore");
3580
3640
  if (!fs8.existsSync(giPath)) return;
3581
3641
  const content = fs8.readFileSync(giPath, "utf-8");
3582
3642
  if (content.split("\n").some((l) => l.trim() === ".npmrc")) return;
@@ -3585,25 +3645,10 @@ function ensureGitignoreHasNpmrc(cwd = process.cwd()) {
3585
3645
  .npmrc
3586
3646
  `);
3587
3647
  }
3588
- var IUI_BUILD_CACHE_GITIGNORE_LINES = [
3589
- "",
3590
- "# IUI compile-first build cache (generated slot files under .iui/generated/ stay committed)",
3591
- ".iui/slot-registration-state.json",
3592
- ".iui/slot-registration.lock",
3593
- ".iui/classes.cache.json",
3594
- ".iui/utilities.css",
3595
- ".iui/build-styles.generated.css",
3596
- ".iui/build-styles.generated.js",
3597
- ".iui/build-manifest.generated.js",
3598
- ".iui/build-css-inline.js",
3599
- ".iui/build-manifest.json",
3600
- ".iui-bootstrap-client.js",
3601
- ".iui-bootstrap-server.js",
3602
- "public/iui/"
3603
- ];
3648
+ var IUI_BUILD_CACHE_GITIGNORE_LINES = IUI_CACHE_GITIGNORE_LINES;
3604
3649
  function ensureGitignoreHasIuiBuildCache(cwd = process.cwd()) {
3605
3650
  const configRoot = resolveProjectConfigRoot(cwd);
3606
- const giPath = path9.join(configRoot, ".gitignore");
3651
+ const giPath = path10.join(configRoot, ".gitignore");
3607
3652
  if (!fs8.existsSync(giPath)) return;
3608
3653
  const content = fs8.readFileSync(giPath, "utf-8");
3609
3654
  const lines = content.split("\n");
@@ -3617,7 +3662,7 @@ function ensureGitignoreHasIuiBuildCache(cwd = process.cwd()) {
3617
3662
  `);
3618
3663
  }
3619
3664
  function detectReactVersion(cwd = process.cwd()) {
3620
- const pkgPath = path9.join(cwd, "package.json");
3665
+ const pkgPath = path10.join(cwd, "package.json");
3621
3666
  if (!fs8.existsSync(pkgPath)) return { status: "not-installed" };
3622
3667
  try {
3623
3668
  const pkg = fs8.readJsonSync(pkgPath);
@@ -3635,7 +3680,7 @@ function detectReactVersion(cwd = process.cwd()) {
3635
3680
  }
3636
3681
  function getInstalledReactVersion(cwd) {
3637
3682
  try {
3638
- const reactPkgPath = path9.join(cwd, "node_modules", "react", "package.json");
3683
+ const reactPkgPath = path10.join(cwd, "node_modules", "react", "package.json");
3639
3684
  if (!fs8.existsSync(reactPkgPath)) return null;
3640
3685
  const reactPkg = fs8.readJsonSync(reactPkgPath);
3641
3686
  return reactPkg.version ?? null;
@@ -3649,7 +3694,7 @@ function isReact19(version) {
3649
3694
  return major === 19;
3650
3695
  }
3651
3696
  function detectReactDomVersion(cwd = process.cwd()) {
3652
- const pkgPath = path9.join(cwd, "package.json");
3697
+ const pkgPath = path10.join(cwd, "package.json");
3653
3698
  if (!fs8.existsSync(pkgPath)) return { status: "not-installed" };
3654
3699
  try {
3655
3700
  const pkg = fs8.readJsonSync(pkgPath);
@@ -3667,7 +3712,7 @@ function detectReactDomVersion(cwd = process.cwd()) {
3667
3712
  }
3668
3713
  function getInstalledReactDomVersion(cwd) {
3669
3714
  try {
3670
- const reactDomPkgPath = path9.join(cwd, "node_modules", "react-dom", "package.json");
3715
+ const reactDomPkgPath = path10.join(cwd, "node_modules", "react-dom", "package.json");
3671
3716
  if (!fs8.existsSync(reactDomPkgPath)) return null;
3672
3717
  const reactDomPkg = fs8.readJsonSync(reactDomPkgPath);
3673
3718
  return reactDomPkg.version ?? null;
@@ -3676,7 +3721,7 @@ function getInstalledReactDomVersion(cwd) {
3676
3721
  }
3677
3722
  }
3678
3723
  function detectViteVersion(cwd = process.cwd()) {
3679
- const pkgPath = path9.join(cwd, "package.json");
3724
+ const pkgPath = path10.join(cwd, "package.json");
3680
3725
  if (!fs8.existsSync(pkgPath)) return { status: "not-installed" };
3681
3726
  try {
3682
3727
  const pkg = fs8.readJsonSync(pkgPath);
@@ -3694,7 +3739,7 @@ function detectViteVersion(cwd = process.cwd()) {
3694
3739
  }
3695
3740
  function getInstalledViteVersion(cwd) {
3696
3741
  try {
3697
- const vitePkgPath = path9.join(cwd, "node_modules", "vite", "package.json");
3742
+ const vitePkgPath = path10.join(cwd, "node_modules", "vite", "package.json");
3698
3743
  if (!fs8.existsSync(vitePkgPath)) return null;
3699
3744
  const vitePkg = fs8.readJsonSync(vitePkgPath);
3700
3745
  return vitePkg.version ?? null;
@@ -3717,7 +3762,7 @@ function isViteSupported(version) {
3717
3762
  }
3718
3763
  function ensureInventiveUiViteConfig(cwd = process.cwd()) {
3719
3764
  if (!projectHasViteTooling(cwd)) return "skipped";
3720
- const configPath = path9.join(cwd, "vite.config.ts");
3765
+ const configPath = path10.join(cwd, "vite.config.ts");
3721
3766
  if (!fs8.existsSync(configPath)) {
3722
3767
  atomicWriteFile(configPath, MINIMAL_VITE_SCAFFOLD);
3723
3768
  return "scaffolded";
@@ -3731,13 +3776,13 @@ function ensureInventiveUiViteConfig(cwd = process.cwd()) {
3731
3776
  }
3732
3777
 
3733
3778
  // src/services/auth.ts
3734
- async function api(path26, opts) {
3735
- const res = await fetch(`${API_BASE_URL}${path26}`, {
3779
+ async function api(path28, opts) {
3780
+ const res = await fetch(`${API_BASE_URL}${path28}`, {
3736
3781
  ...opts,
3737
3782
  signal: opts?.signal ?? AbortSignal.timeout(API_REQUEST_TIMEOUT_MS),
3738
3783
  headers: { "Content-Type": "application/json", ...opts?.headers }
3739
3784
  });
3740
- throwIfRateLimited(res, `calling ${path26}`);
3785
+ throwIfRateLimited(res, `calling ${path28}`);
3741
3786
  if (!res.ok) {
3742
3787
  const body = await res.text().catch(() => "");
3743
3788
  throw new CLIError(`API error ${res.status}: ${body || res.statusText}`);
@@ -4185,7 +4230,7 @@ async function promptText(title, hint2, placeholder, validate) {
4185
4230
  }
4186
4231
 
4187
4232
  // src/commands/init.ts
4188
- import path21 from "path";
4233
+ import path23 from "path";
4189
4234
  import ora3 from "ora";
4190
4235
 
4191
4236
  // src/services/license.ts
@@ -4523,7 +4568,7 @@ async function fetchLatestCliVersion(token) {
4523
4568
  }
4524
4569
 
4525
4570
  // src/services/framework.ts
4526
- import path12 from "path";
4571
+ import path13 from "path";
4527
4572
  import fs10 from "fs-extra";
4528
4573
  import ora from "ora";
4529
4574
 
@@ -4532,7 +4577,7 @@ import { createWriteStream, mkdtempSync, unlinkSync, rmSync } from "fs";
4532
4577
  import { pipeline } from "stream/promises";
4533
4578
  import { Readable, Transform } from "stream";
4534
4579
  import os4 from "os";
4535
- import path10 from "path";
4580
+ import path11 from "path";
4536
4581
  var MAX_TARBALL_BYTES = 250 * 1024 * 1024;
4537
4582
  async function downloadPackageTarball(token, packageShortName) {
4538
4583
  if (!/^[a-z0-9][a-z0-9._-]*$/.test(packageShortName)) {
@@ -4576,8 +4621,8 @@ async function downloadPackageTarball(token, packageShortName) {
4576
4621
  );
4577
4622
  }
4578
4623
  }
4579
- const tmpDir = mkdtempSync(path10.join(os4.tmpdir(), "iui-dl-"));
4580
- const tempPath = path10.join(tmpDir, `${packageShortName}.tgz`);
4624
+ const tmpDir = mkdtempSync(path11.join(os4.tmpdir(), "iui-dl-"));
4625
+ const tempPath = path11.join(tmpDir, `${packageShortName}.tgz`);
4581
4626
  const fileStream = createWriteStream(tempPath, { flags: "wx" });
4582
4627
  let bytesWritten = 0;
4583
4628
  const limiter = new Transform({
@@ -4607,7 +4652,7 @@ async function downloadPackageTarball(token, packageShortName) {
4607
4652
  return { path: tempPath, version };
4608
4653
  }
4609
4654
  function cleanupTempFile(filePath) {
4610
- const parent = path10.dirname(filePath);
4655
+ const parent = path11.dirname(filePath);
4611
4656
  try {
4612
4657
  unlinkSync(filePath);
4613
4658
  } catch {
@@ -4621,7 +4666,7 @@ function cleanupTempFile(filePath) {
4621
4666
  }
4622
4667
 
4623
4668
  // src/utils/declared-deps.ts
4624
- import path11 from "path";
4669
+ import path12 from "path";
4625
4670
  import fs9 from "fs-extra";
4626
4671
  function shouldSyncDeclaredDependency(declared, installed) {
4627
4672
  const desired = `^${installed}`;
@@ -4639,7 +4684,7 @@ function readDepField(pkg, packageName) {
4639
4684
  return { field, declared };
4640
4685
  }
4641
4686
  function syncDeclaredDependencyVersion(packageName, cwd = process.cwd()) {
4642
- const pkgPath = path11.join(cwd, "package.json");
4687
+ const pkgPath = path12.join(cwd, "package.json");
4643
4688
  if (!fs9.existsSync(pkgPath)) return false;
4644
4689
  const installed = getInstalledPackageVersion(packageName, cwd);
4645
4690
  if (!installed) return false;
@@ -4660,7 +4705,7 @@ function getDirectDeclaredVersionFloor(packageName, cwd = process.cwd()) {
4660
4705
  return floor || null;
4661
4706
  }
4662
4707
  function syncInventiveUiDeclaredDependencies(cwd = process.cwd()) {
4663
- const pkgPath = path11.join(cwd, "package.json");
4708
+ const pkgPath = path12.join(cwd, "package.json");
4664
4709
  if (!fs9.existsSync(pkgPath)) return [];
4665
4710
  const pkg = fs9.readJsonSync(pkgPath);
4666
4711
  const names = /* @__PURE__ */ new Set();
@@ -4827,7 +4872,7 @@ async function notifyIfUpdateAvailable(token, shortName, currentVersion, label)
4827
4872
  // src/services/framework.ts
4828
4873
  var FRAMEWORK_PACKAGE2 = "@inventive-ui/framework";
4829
4874
  function hasYarnPnP(cwd) {
4830
- return fs10.existsSync(path12.join(cwd, ".pnp.cjs")) || fs10.existsSync(path12.join(cwd, ".pnp.js"));
4875
+ return fs10.existsSync(path13.join(cwd, ".pnp.cjs")) || fs10.existsSync(path13.join(cwd, ".pnp.js"));
4831
4876
  }
4832
4877
  function getFrameworkUpdateBaselineVersion(cwd = process.cwd()) {
4833
4878
  return getDirectDeclaredVersionFloor(FRAMEWORK_PACKAGE2, cwd) ?? getInstalledPackageVersion(FRAMEWORK_PACKAGE2, cwd);
@@ -5044,7 +5089,7 @@ function normalizeFrameworkChoice(choice) {
5044
5089
  return null;
5045
5090
  }
5046
5091
  function hasViteConfig(cwd) {
5047
- return fs10.existsSync(path12.join(cwd, "vite.config.ts")) || fs10.existsSync(path12.join(cwd, "vite.config.mts")) || fs10.existsSync(path12.join(cwd, "vite.config.js")) || fs10.existsSync(path12.join(cwd, "vite.config.mjs")) || fs10.existsSync(path12.join(cwd, "vite.config.cjs"));
5092
+ return fs10.existsSync(path13.join(cwd, "vite.config.ts")) || fs10.existsSync(path13.join(cwd, "vite.config.mts")) || fs10.existsSync(path13.join(cwd, "vite.config.js")) || fs10.existsSync(path13.join(cwd, "vite.config.mjs")) || fs10.existsSync(path13.join(cwd, "vite.config.cjs"));
5048
5093
  }
5049
5094
  async function ensureReactRuntime(pm, cwd, autoApprove, react, reactDom) {
5050
5095
  if (react.status === "ok" && reactDom.status === "ok") {
@@ -5152,12 +5197,12 @@ function getMajorFromVersion(version) {
5152
5197
  import ora2 from "ora";
5153
5198
 
5154
5199
  // src/services/slot-registry.ts
5155
- import fs17 from "fs-extra";
5156
- import path20 from "path";
5200
+ import fs18 from "fs-extra";
5201
+ import path22 from "path";
5157
5202
 
5158
5203
  // src/services/registry-lock.ts
5159
5204
  import fs11 from "fs";
5160
- import path13 from "path";
5205
+ import path14 from "path";
5161
5206
  var LOCK_STALE_MS = 2 * 60 * 1e3;
5162
5207
  var LOCK_RETRY_MS = 80;
5163
5208
  var LOCK_TIMEOUT_MS = 1e4;
@@ -5165,7 +5210,7 @@ function sleep(ms) {
5165
5210
  return new Promise((resolve) => setTimeout(resolve, ms));
5166
5211
  }
5167
5212
  function lockPath(cwd) {
5168
- return path13.join(cwd, IUI_DIR, "slot-registration.lock");
5213
+ return iuiCacheFile(cwd, "slotLock");
5169
5214
  }
5170
5215
  function readLockAge(filePath) {
5171
5216
  try {
@@ -5185,7 +5230,7 @@ function removeStaleLock(filePath) {
5185
5230
  }
5186
5231
  async function acquireRegistryLock(cwd) {
5187
5232
  const filePath = lockPath(cwd);
5188
- fs11.mkdirSync(path13.dirname(filePath), { recursive: true });
5233
+ fs11.mkdirSync(path14.dirname(filePath), { recursive: true });
5189
5234
  const started = Date.now();
5190
5235
  while (Date.now() - started < LOCK_TIMEOUT_MS) {
5191
5236
  removeStaleLock(filePath);
@@ -5241,16 +5286,16 @@ async function withRegistryLock(cwd, operation) {
5241
5286
 
5242
5287
  // src/services/slots.ts
5243
5288
  import fs15 from "fs-extra";
5244
- import path18 from "path";
5289
+ import path19 from "path";
5245
5290
 
5246
5291
  // src/utils/public-slot-contract.ts
5247
- import path14 from "path";
5292
+ import path15 from "path";
5248
5293
  import fs12 from "fs-extra";
5249
5294
  var CONTRACT_FILENAME = "public-slot-contract.json";
5250
5295
  function loadPublicSlotContract(cwd = process.cwd()) {
5251
5296
  const pkgRoot = resolvePackageDir("@inventive-ui/components", cwd);
5252
5297
  if (!pkgRoot) return null;
5253
- const contractPath = path14.join(pkgRoot, CONTRACT_FILENAME);
5298
+ const contractPath = path15.join(pkgRoot, CONTRACT_FILENAME);
5254
5299
  if (!fs12.existsSync(contractPath)) return null;
5255
5300
  try {
5256
5301
  return fs12.readJsonSync(contractPath);
@@ -5328,7 +5373,7 @@ function collectInstalledSlotEmitters(items, installedSlugs, cwd = process.cwd()
5328
5373
 
5329
5374
  // src/utils/security/fsSafe.ts
5330
5375
  import fs13 from "fs";
5331
- import path15 from "path";
5376
+ import path16 from "path";
5332
5377
  function assertNotSymlink(filePath, label) {
5333
5378
  try {
5334
5379
  const stat = fs13.lstatSync(filePath);
@@ -5342,11 +5387,11 @@ function assertNotSymlink(filePath, label) {
5342
5387
  }
5343
5388
  }
5344
5389
  function safeWriteFile(filePath, content) {
5345
- const dir = path15.dirname(filePath);
5390
+ const dir = path16.dirname(filePath);
5346
5391
  if (fs13.existsSync(dir)) {
5347
5392
  assertNotSymlink(dir, "directory");
5348
5393
  }
5349
- const parent = path15.dirname(filePath);
5394
+ const parent = path16.dirname(filePath);
5350
5395
  fs13.mkdirSync(parent, { recursive: true });
5351
5396
  if (fs13.existsSync(filePath)) {
5352
5397
  assertNotSymlink(filePath, "file");
@@ -5356,22 +5401,22 @@ function safeWriteFile(filePath, content) {
5356
5401
 
5357
5402
  // src/services/asset-bound.ts
5358
5403
  import fs14 from "fs-extra";
5359
- import path17 from "path";
5404
+ import path18 from "path";
5360
5405
  import { pathToFileURL } from "url";
5361
5406
 
5362
5407
  // src/services/generated-paths.ts
5363
- import path16 from "path";
5364
- function iuiProjectRoot(cwd) {
5408
+ import path17 from "path";
5409
+ function iuiProjectRoot2(cwd) {
5365
5410
  return resolveIuiProjectRoot(cwd);
5366
5411
  }
5367
5412
  function generatedIuiDir(cwd) {
5368
- return path16.join(iuiProjectRoot(cwd), ".iui", "generated");
5413
+ return path17.join(iuiProjectRoot2(cwd), ".iui", "generated");
5369
5414
  }
5370
5415
  function generatedSlotsDir(cwd) {
5371
- return path16.join(generatedIuiDir(cwd), "slots");
5416
+ return path17.join(generatedIuiDir(cwd), "slots");
5372
5417
  }
5373
5418
  function generatedAssetsDir(cwd) {
5374
- return path16.join(generatedIuiDir(cwd), "assets");
5419
+ return path17.join(generatedIuiDir(cwd), "assets");
5375
5420
  }
5376
5421
 
5377
5422
  // src/services/asset-bound.ts
@@ -5468,21 +5513,21 @@ function resolveFrameworkModule(cwd, relativePath) {
5468
5513
  const searchRoots = /* @__PURE__ */ new Set();
5469
5514
  for (const candidate of [
5470
5515
  resolveDependencyInstallRoot(cwd),
5471
- path17.resolve(cwd),
5472
- iuiProjectRoot(cwd)
5516
+ path18.resolve(cwd),
5517
+ iuiProjectRoot2(cwd)
5473
5518
  ]) {
5474
- searchRoots.add(path17.resolve(candidate));
5519
+ searchRoots.add(path18.resolve(candidate));
5475
5520
  }
5476
5521
  for (const start of searchRoots) {
5477
5522
  const frameworkDir = resolvePackageDir("@inventive-ui/framework", start);
5478
5523
  if (!frameworkDir) continue;
5479
- const installed = path17.join(frameworkDir, relativePath);
5524
+ const installed = path18.join(frameworkDir, relativePath);
5480
5525
  if (fs14.existsSync(installed)) return installed;
5481
5526
  }
5482
- const root = iuiProjectRoot(cwd);
5527
+ const root = iuiProjectRoot2(cwd);
5483
5528
  for (const candidate of [
5484
- path17.join(root, "..", "Framework", relativePath),
5485
- path17.join(root, "..", "..", "Framework", relativePath)
5529
+ path18.join(root, "..", "Framework", relativePath),
5530
+ path18.join(root, "..", "..", "Framework", relativePath)
5486
5531
  ]) {
5487
5532
  if (fs14.existsSync(candidate)) return candidate;
5488
5533
  }
@@ -5560,7 +5605,7 @@ function cleanupAssetBoundFiles(cwd) {
5560
5605
  if (!fs14.existsSync(assetsDir)) return;
5561
5606
  for (const file of fs14.readdirSync(assetsDir)) {
5562
5607
  if (file.endsWith(".bound.ts") || file === "register-bound.ts") {
5563
- fs14.removeSync(path17.join(assetsDir, file));
5608
+ fs14.removeSync(path18.join(assetsDir, file));
5564
5609
  }
5565
5610
  }
5566
5611
  const remaining = fs14.readdirSync(assetsDir);
@@ -5569,10 +5614,10 @@ function cleanupAssetBoundFiles(cwd) {
5569
5614
  }
5570
5615
  }
5571
5616
  function hasAssetBoundRegistration(cwd) {
5572
- return fs14.existsSync(path17.join(generatedAssetsDir(cwd), "register-bound.ts"));
5617
+ return fs14.existsSync(path18.join(generatedAssetsDir(cwd), "register-bound.ts"));
5573
5618
  }
5574
5619
  async function writeAssetBoundFiles(cwd = process.cwd()) {
5575
- const root = iuiProjectRoot(cwd);
5620
+ const root = iuiProjectRoot2(cwd);
5576
5621
  const scanUtils = await loadScanUtils(cwd);
5577
5622
  const activeSpecs = BOUND_SPECS.filter(
5578
5623
  (spec) => scanUtils.isScannedAssetBindingEnabled(root, spec.slotType)
@@ -5628,7 +5673,7 @@ async function writeAssetBoundFiles(cwd = process.cwd()) {
5628
5673
  const existing = fs14.existsSync(assetsDir) ? fs14.readdirSync(assetsDir).filter((f) => f.endsWith(".bound.ts")) : [];
5629
5674
  for (const file of existing) {
5630
5675
  if (!generatedFiles.has(file)) {
5631
- fs14.removeSync(path17.join(assetsDir, file));
5676
+ fs14.removeSync(path18.join(assetsDir, file));
5632
5677
  }
5633
5678
  }
5634
5679
  if (registrationSpecs.length === 0) {
@@ -5663,27 +5708,27 @@ function assetModuleCandidates(pkgRoot, moduleId) {
5663
5708
  const pkgId = pkgName.replace("@inventive-ui/", "");
5664
5709
  if (!subpath || subpath.includes("..")) return [];
5665
5710
  if (pkgId === "loaders") {
5666
- return [path17.join(pkgRoot, "dist", "loaders", `${subpath}.js`)];
5711
+ return [path18.join(pkgRoot, "dist", "loaders", `${subpath}.js`)];
5667
5712
  }
5668
5713
  if (pkgId === "illustrations") {
5669
5714
  const [family, scene] = subpath.split("/");
5670
5715
  if (family && scene) {
5671
- return [path17.join(pkgRoot, "dist", family, `${scene}.js`)];
5716
+ return [path18.join(pkgRoot, "dist", family, `${scene}.js`)];
5672
5717
  }
5673
- return [path17.join(pkgRoot, "dist", `${subpath}.js`)];
5718
+ return [path18.join(pkgRoot, "dist", `${subpath}.js`)];
5674
5719
  }
5675
5720
  const prefix = PKG_LOOKUP_PREFIX[pkgId];
5676
5721
  if (prefix) {
5677
5722
  const dir = prefix.replace(/\/$/, "");
5678
5723
  return [
5679
- path17.join(pkgRoot, "dist", dir, `${subpath}.js`),
5680
- path17.join(pkgRoot, "dist", `${subpath}.js`),
5681
- path17.join(pkgRoot, "dist", subpath, "index.js")
5724
+ path18.join(pkgRoot, "dist", dir, `${subpath}.js`),
5725
+ path18.join(pkgRoot, "dist", `${subpath}.js`),
5726
+ path18.join(pkgRoot, "dist", subpath, "index.js")
5682
5727
  ];
5683
5728
  }
5684
5729
  return [
5685
- path17.join(pkgRoot, "dist", `${subpath}.js`),
5686
- path17.join(pkgRoot, "dist", subpath, "index.js")
5730
+ path18.join(pkgRoot, "dist", `${subpath}.js`),
5731
+ path18.join(pkgRoot, "dist", subpath, "index.js")
5687
5732
  ];
5688
5733
  }
5689
5734
  function validateGeneratedAssetBoundImports(cwd = process.cwd()) {
@@ -5692,7 +5737,7 @@ function validateGeneratedAssetBoundImports(cwd = process.cwd()) {
5692
5737
  const issues = [];
5693
5738
  const boundFiles = fs14.readdirSync(assetsDir).filter((file) => file.endsWith(".bound.ts"));
5694
5739
  for (const file of boundFiles) {
5695
- const content = fs14.readFileSync(path17.join(assetsDir, file), "utf8");
5740
+ const content = fs14.readFileSync(path18.join(assetsDir, file), "utf8");
5696
5741
  const importRe = /from\s+["'](@inventive-ui\/[^"']+)["']/g;
5697
5742
  let match;
5698
5743
  while ((match = importRe.exec(content)) !== null) {
@@ -5716,16 +5761,16 @@ function validateGeneratedAssetBoundImports(cwd = process.cwd()) {
5716
5761
  var SLOT_GROUP_CORE_FILE = "slot-core.generated.tsx";
5717
5762
  var SLOT_GROUP_OPTIONAL_FILE = "slot-optional.generated.tsx";
5718
5763
  function bridgeSlotFilePath(cwd) {
5719
- return path18.join(cwd, "src", "iui", "slot.tsx");
5764
+ return path19.join(cwd, "src", "iui", "slot.tsx");
5720
5765
  }
5721
5766
  function cleanupLegacySourceSlotFiles(cwd) {
5722
- const legacySlotsDir = path18.join(cwd, "src", "iui", "slots");
5767
+ const legacySlotsDir = path19.join(cwd, "src", "iui", "slots");
5723
5768
  if (!fs15.existsSync(legacySlotsDir)) return;
5724
5769
  try {
5725
5770
  const files = fs15.readdirSync(legacySlotsDir);
5726
5771
  for (const file of files) {
5727
5772
  if (file.endsWith(".slot.tsx")) {
5728
- fs15.removeSync(path18.join(legacySlotsDir, file));
5773
+ fs15.removeSync(path19.join(legacySlotsDir, file));
5729
5774
  }
5730
5775
  }
5731
5776
  const remaining = fs15.readdirSync(legacySlotsDir);
@@ -5793,7 +5838,7 @@ function writeComponentSlotFiles(cwd = process.cwd()) {
5793
5838
  const existingSlots2 = fs15.readdirSync(slotsDir).filter((f) => f.endsWith(".slot.tsx"));
5794
5839
  for (const file of existingSlots2) {
5795
5840
  try {
5796
- fs15.removeSync(path18.join(slotsDir, file));
5841
+ fs15.removeSync(path19.join(slotsDir, file));
5797
5842
  } catch {
5798
5843
  }
5799
5844
  }
@@ -5823,7 +5868,7 @@ function writeComponentSlotFiles(cwd = process.cwd()) {
5823
5868
  if (policy === "core") coreEmitters.push(emitter);
5824
5869
  else optionalEmitters.push(emitter);
5825
5870
  }
5826
- const root = iuiProjectRoot(cwd);
5871
+ const root = iuiProjectRoot2(cwd);
5827
5872
  const renderedGroups = [
5828
5873
  { fileName: SLOT_GROUP_CORE_FILE, emitters: coreEmitters },
5829
5874
  { fileName: SLOT_GROUP_OPTIONAL_FILE, emitters: optionalEmitters }
@@ -5834,21 +5879,26 @@ function writeComponentSlotFiles(cwd = process.cwd()) {
5834
5879
  if (fs15.existsSync(outPath)) fs15.removeSync(outPath);
5835
5880
  continue;
5836
5881
  }
5837
- safeWriteFile(outPath, renderGroupedSlotFileContent(group.emitters));
5882
+ safeWriteFile(
5883
+ outPath,
5884
+ renderGroupedSlotFileContent(group.emitters, {
5885
+ prefetch: group.fileName === SLOT_GROUP_CORE_FILE
5886
+ })
5887
+ );
5838
5888
  }
5839
5889
  const existingSlots = fs15.existsSync(slotsDir) ? fs15.readdirSync(slotsDir).filter((f) => f.endsWith(".slot.tsx") || f.endsWith(".generated.tsx")) : [];
5840
5890
  for (const file of existingSlots) {
5841
5891
  if (file === SLOT_GROUP_CORE_FILE || file === SLOT_GROUP_OPTIONAL_FILE) continue;
5842
5892
  if (file.endsWith(".slot.tsx")) {
5843
5893
  try {
5844
- fs15.removeSync(path18.join(slotsDir, file));
5894
+ fs15.removeSync(path19.join(slotsDir, file));
5845
5895
  } catch {
5846
5896
  }
5847
5897
  continue;
5848
5898
  }
5849
5899
  if (file.endsWith(".generated.tsx")) {
5850
5900
  try {
5851
- fs15.removeSync(path18.join(slotsDir, file));
5901
+ fs15.removeSync(path19.join(slotsDir, file));
5852
5902
  } catch {
5853
5903
  }
5854
5904
  }
@@ -5863,7 +5913,7 @@ function writeComponentSlotFiles(cwd = process.cwd()) {
5863
5913
  );
5864
5914
  }
5865
5915
  }
5866
- function renderGroupedSlotFileContent(emitters) {
5916
+ function renderGroupedSlotFileContent(emitters, options = {}) {
5867
5917
  const needsComponentProps = emitters.some((emitter) => emitter.propsName === "Props");
5868
5918
  const lines = [
5869
5919
  "// Managed by iui. Do not edit manually.",
@@ -5911,6 +5961,9 @@ function renderGroupedSlotFileContent(emitters) {
5911
5961
  lines.push(`const ${renderer} = createEagerComponent<${alias}SlotProps>(`);
5912
5962
  lines.push(` () => import(${escapeTsStringLiteral(emitter.lazyImportSpecifier)}),`);
5913
5963
  lines.push(` (mod) => ${renderGetComponentExpr(emitter)} as React.ComponentType<${alias}SlotProps>,`);
5964
+ if (options.prefetch) {
5965
+ lines.push(" { prefetch: true },");
5966
+ }
5914
5967
  lines.push(");", "");
5915
5968
  lines.push(`registerSlot(${escapeTsStringLiteral(emitter.type)}, (slot) => {`);
5916
5969
  lines.push(" const { type, ...props } = slot;");
@@ -5949,15 +6002,15 @@ function writeSlotHelperFile(cwd = process.cwd()) {
5949
6002
  }
5950
6003
  const typesArray = Array.from(slotTypes).sort();
5951
6004
  const slotImports = [];
5952
- const coreSlotsPath = path18.join(generatedSlotsDir(cwd), SLOT_GROUP_CORE_FILE);
5953
- const optionalSlotsPath = path18.join(generatedSlotsDir(cwd), SLOT_GROUP_OPTIONAL_FILE);
6005
+ const coreSlotsPath = path19.join(generatedSlotsDir(cwd), SLOT_GROUP_CORE_FILE);
6006
+ const optionalSlotsPath = path19.join(generatedSlotsDir(cwd), SLOT_GROUP_OPTIONAL_FILE);
5954
6007
  if (fs15.existsSync(coreSlotsPath)) slotImports.push(`import "./slots/${SLOT_GROUP_CORE_FILE.replace(/\.tsx$/, "")}";`);
5955
6008
  if (fs15.existsSync(optionalSlotsPath)) slotImports.push(`import "./slots/${SLOT_GROUP_OPTIONAL_FILE.replace(/\.tsx$/, "")}";`);
5956
6009
  const componentSlotImports = slotImports.join("\n");
5957
6010
  const includeAssetBindings = hasAssetBoundRegistration(cwd);
5958
6011
  const outDir = generatedIuiDir(cwd);
5959
6012
  fs15.ensureDirSync(outDir);
5960
- const outPath = path18.join(outDir, "slot.generated.tsx");
6013
+ const outPath = path19.join(outDir, "slot.generated.tsx");
5961
6014
  const sections = [
5962
6015
  `// Managed by iui. Do not edit manually.`,
5963
6016
  `// Rebuilt automatically when the CLI validates the project.`
@@ -5990,11 +6043,11 @@ ${typesArray.map((t) => ` | "${t}"`).join("\n")};` : `export type IUISlotType =
5990
6043
  const content = sections.join("\n");
5991
6044
  safeWriteFile(outPath, content);
5992
6045
  }
5993
- function writeSlotBridge(packageDir, iuiRoot) {
6046
+ function writeSlotBridge(packageDir, iuiRoot2) {
5994
6047
  const bridgePath = bridgeSlotFilePath(packageDir);
5995
- const generatedFile = path18.join(iuiRoot, ".iui", "generated", "slot.generated.tsx");
5996
- const importBase = relativeImportPath(path18.dirname(bridgePath), generatedFile);
5997
- fs15.ensureDirSync(path18.dirname(bridgePath));
6048
+ const generatedFile = path19.join(iuiRoot2, ".iui", "generated", "slot.generated.tsx");
6049
+ const importBase = relativeImportPath(path19.dirname(bridgePath), generatedFile);
6050
+ fs15.ensureDirSync(path19.dirname(bridgePath));
5998
6051
  if (fs15.existsSync(bridgePath)) {
5999
6052
  const existing = fs15.readFileSync(bridgePath, "utf-8");
6000
6053
  if (existing.length > 0 && !/@iui-managed/.test(existing)) {
@@ -6013,19 +6066,158 @@ export type { IUISlotType } from "${importBase}";
6013
6066
  }
6014
6067
 
6015
6068
  // src/services/workspace-bootstrap.ts
6016
- import path19 from "path";
6069
+ import path21 from "path";
6070
+ import fs17 from "fs-extra";
6071
+
6072
+ // src/services/bootstrap.ts
6017
6073
  import fs16 from "fs-extra";
6018
- function workspaceManifestPath(iuiRoot) {
6019
- return path19.join(iuiRoot, IUI_DIR, "workspace.json");
6074
+ import path20 from "path";
6075
+ var BOOTSTRAP_GENERATED_FILE = "bootstrap.generated.tsx";
6076
+ function bridgeBootstrapFilePath(cwd) {
6077
+ return path20.join(cwd, "src", "iui", "bootstrap.ts");
6078
+ }
6079
+ function bootstrapGeneratedPath(cwd = process.cwd()) {
6080
+ return path20.join(generatedIuiDir(cwd), BOOTSTRAP_GENERATED_FILE);
6081
+ }
6082
+ function resolveProjectConfigPaths(cwd) {
6083
+ const meta = readProjectMeta(cwd);
6084
+ const configs = meta?.configs;
6085
+ if (configs?.theme && configs?.assets && configs?.components) {
6086
+ return configs;
6087
+ }
6088
+ return {
6089
+ theme: PROJECT_CONFIG_FILE,
6090
+ assets: ASSETS_CONFIG_FILE,
6091
+ components: COMPONENT_CONFIG_FILE
6092
+ };
6093
+ }
6094
+ function configImportFromGenerated(cwd, configRel) {
6095
+ const generatedDir = path20.dirname(bootstrapGeneratedPath(cwd));
6096
+ const abs = path20.resolve(cwd, configRel.replace(/^\.\//, ""));
6097
+ return relativeImportPath(generatedDir, abs);
6098
+ }
6099
+ function expectedBootstrapImportPaths(cwd) {
6100
+ const configs = resolveProjectConfigPaths(cwd);
6101
+ return {
6102
+ theme: configImportFromGenerated(cwd, configs.theme),
6103
+ assets: configImportFromGenerated(cwd, configs.assets),
6104
+ components: configImportFromGenerated(cwd, configs.components)
6105
+ };
6106
+ }
6107
+ function writeBootstrapGenerated(cwd = process.cwd()) {
6108
+ const outPath = bootstrapGeneratedPath(cwd);
6109
+ fs16.ensureDirSync(path20.dirname(outPath));
6110
+ const imports = expectedBootstrapImportPaths(cwd);
6111
+ const content = `// @iui-managed
6112
+
6113
+ // Generated by iui CLI \u2014 do not edit manually.
6114
+
6115
+ // Connects iui.config.ts + assets.config.json + component.config.ts for standard bootstrap.
6116
+
6117
+
6118
+
6119
+ import theme from "${imports.theme}";
6120
+
6121
+ import assets from "${imports.assets}";
6122
+
6123
+ import { componentConfig as projectComponentConfig } from "${imports.components}";
6124
+
6125
+ import {
6126
+
6127
+ mergeProjectConfig,
6128
+
6129
+ initFramework,
6130
+
6131
+ registerBootstrapState,
6132
+
6133
+ } from "@inventive-ui/framework";
6134
+
6135
+ import { initConfig as initSlotsConfig } from "@inventive-ui/framework/slots";
6136
+
6137
+ import type { IUIAssetsConfig } from "@inventive-ui/framework/config";
6138
+
6139
+
6140
+
6141
+ import "./slot.generated";
6142
+
6143
+
6144
+
6145
+ const themeConfig = (theme as { default?: typeof theme }).default ?? theme;
6146
+
6147
+
6148
+
6149
+ export const frameworkConfig = mergeProjectConfig(
6150
+
6151
+ themeConfig,
6152
+
6153
+ assets as IUIAssetsConfig,
6154
+
6155
+ );
6156
+
6157
+
6158
+
6159
+ registerBootstrapState({
6160
+
6161
+ frameworkConfig,
6162
+
6163
+ componentConfig: projectComponentConfig,
6164
+
6165
+ });
6166
+
6167
+
6168
+
6169
+ initFramework(frameworkConfig);
6170
+
6171
+ initSlotsConfig(frameworkConfig);
6172
+
6173
+
6174
+
6175
+ export { projectComponentConfig as componentConfig };
6176
+
6177
+ `;
6178
+ safeWriteFile(outPath, content);
6020
6179
  }
6021
- function readWorkspaceManifest(iuiRoot) {
6022
- const p = workspaceManifestPath(iuiRoot);
6023
- if (!fs16.existsSync(p)) return null;
6180
+ function writeBootstrapBridge(packageDir, iuiRoot2) {
6181
+ const bridgePath = bridgeBootstrapFilePath(packageDir);
6182
+ const generatedFile = bootstrapGeneratedPath(iuiRoot2);
6183
+ const importBase = relativeImportPath(path20.dirname(bridgePath), generatedFile);
6184
+ fs16.ensureDirSync(path20.dirname(bridgePath));
6185
+ if (fs16.existsSync(bridgePath)) {
6186
+ const existing = fs16.readFileSync(bridgePath, "utf-8");
6187
+ if (existing.length > 0 && !/@iui-managed/.test(existing)) {
6188
+ return;
6189
+ }
6190
+ }
6191
+ const bridgeContent = `// Managed by iui. Do not edit manually.
6192
+
6193
+ // @iui-managed
6194
+
6195
+ // Standard bootstrap: wires theme + assets + component configs before IUIProvider.
6196
+
6197
+
6198
+
6199
+ import "${importBase}";
6200
+
6201
+ `;
6202
+ safeWriteFile(bridgePath, bridgeContent);
6203
+ }
6204
+ function writeProjectBootstrapArtifacts(packageDir, iuiRoot2) {
6205
+ writeBootstrapGenerated(iuiRoot2);
6206
+ writeBootstrapBridge(packageDir, iuiRoot2);
6207
+ }
6208
+
6209
+ // src/services/workspace-bootstrap.ts
6210
+ function workspaceManifestPath(iuiRoot2) {
6211
+ return path21.join(iuiRoot2, IUI_DIR, "workspace.json");
6212
+ }
6213
+ function readWorkspaceManifest(iuiRoot2) {
6214
+ const p = workspaceManifestPath(iuiRoot2);
6215
+ if (!fs17.existsSync(p)) return null;
6024
6216
  try {
6025
- const raw = fs16.readJsonSync(p);
6217
+ const raw = fs17.readJsonSync(p);
6026
6218
  if (!Array.isArray(raw.packages)) return null;
6027
6219
  return {
6028
- iuiRoot: raw.iuiRoot ?? iuiRoot,
6220
+ iuiRoot: raw.iuiRoot ?? iuiRoot2,
6029
6221
  packages: raw.packages.map(String),
6030
6222
  updatedAt: raw.updatedAt ?? ""
6031
6223
  };
@@ -6033,63 +6225,64 @@ function readWorkspaceManifest(iuiRoot) {
6033
6225
  return null;
6034
6226
  }
6035
6227
  }
6036
- function writeWorkspaceManifest(iuiRoot, packageDirs) {
6037
- const unique = [...new Set(packageDirs.map((dir) => path19.resolve(dir)))];
6038
- atomicWriteJson(workspaceManifestPath(iuiRoot), {
6039
- iuiRoot,
6040
- packages: unique.map((dir) => path19.relative(iuiRoot, dir) || "."),
6228
+ function writeWorkspaceManifest(iuiRoot2, packageDirs) {
6229
+ const unique = [...new Set(packageDirs.map((dir) => path21.resolve(dir)))];
6230
+ atomicWriteJson(workspaceManifestPath(iuiRoot2), {
6231
+ iuiRoot: iuiRoot2,
6232
+ packages: unique.map((dir) => path21.relative(iuiRoot2, dir) || "."),
6041
6233
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
6042
6234
  });
6043
6235
  }
6044
- function resolveRegisteredPackageDirs(iuiRoot) {
6045
- const resolvedRoot = path19.resolve(iuiRoot);
6236
+ function resolveRegisteredPackageDirs(iuiRoot2) {
6237
+ const resolvedRoot = path21.resolve(iuiRoot2);
6046
6238
  const manifest = readWorkspaceManifest(resolvedRoot);
6047
6239
  if (!manifest) return [resolvedRoot];
6048
6240
  const dirs = manifest.packages.map(
6049
- (rel) => path19.resolve(resolvedRoot, rel === "." ? "" : rel)
6241
+ (rel) => path21.resolve(resolvedRoot, rel === "." ? "" : rel)
6050
6242
  );
6051
- if (!dirs.some((dir) => path19.resolve(dir) === resolvedRoot)) {
6243
+ if (!dirs.some((dir) => path21.resolve(dir) === resolvedRoot)) {
6052
6244
  dirs.unshift(resolvedRoot);
6053
6245
  }
6054
6246
  return dirs;
6055
6247
  }
6056
- function registerWorkspacePackage(iuiRoot, packageDir) {
6057
- const resolvedRoot = path19.resolve(iuiRoot);
6058
- const resolvedPackage = path19.resolve(packageDir);
6248
+ function registerWorkspacePackage(iuiRoot2, packageDir) {
6249
+ const resolvedRoot = path21.resolve(iuiRoot2);
6250
+ const resolvedPackage = path21.resolve(packageDir);
6059
6251
  const existing = resolveRegisteredPackageDirs(resolvedRoot);
6060
- if (!existing.some((dir) => path19.resolve(dir) === resolvedPackage)) {
6252
+ if (!existing.some((dir) => path21.resolve(dir) === resolvedPackage)) {
6061
6253
  existing.push(resolvedPackage);
6062
6254
  }
6063
6255
  writeWorkspaceManifest(resolvedRoot, existing);
6064
6256
  }
6065
- function registerAllWorkspacePackages(iuiRoot) {
6066
- const resolvedRoot = path19.resolve(iuiRoot);
6257
+ function registerAllWorkspacePackages(iuiRoot2) {
6258
+ const resolvedRoot = path21.resolve(iuiRoot2);
6067
6259
  const workspaceRoot = findWorkspaceRoot(resolvedRoot);
6068
6260
  const targets = /* @__PURE__ */ new Set([resolvedRoot]);
6069
6261
  if (workspaceRoot) {
6070
6262
  for (const pkgDir of listWorkspacePackageDirs(workspaceRoot)) {
6071
- targets.add(path19.resolve(pkgDir));
6263
+ targets.add(path21.resolve(pkgDir));
6072
6264
  }
6073
6265
  }
6074
6266
  const dirs = [...targets];
6075
6267
  writeWorkspaceManifest(resolvedRoot, dirs);
6076
6268
  return dirs;
6077
6269
  }
6078
- function bootstrapRegisteredPackages(iuiRoot) {
6079
- const resolvedRoot = resolveIuiProjectRoot(iuiRoot);
6270
+ function bootstrapRegisteredPackages(iuiRoot2) {
6271
+ const resolvedRoot = resolveIuiProjectRoot(iuiRoot2);
6080
6272
  const bootstrapped = [];
6081
6273
  for (const packageDir of resolveRegisteredPackageDirs(resolvedRoot)) {
6082
- if (!fs16.existsSync(path19.join(packageDir, "package.json"))) continue;
6274
+ if (!fs17.existsSync(path21.join(packageDir, "package.json"))) continue;
6083
6275
  ensureProjectNpmrc(packageDir);
6084
6276
  writeSlotBridge(packageDir, resolvedRoot);
6277
+ writeProjectBootstrapArtifacts(packageDir, resolvedRoot);
6085
6278
  bootstrapped.push(packageDir);
6086
6279
  }
6087
6280
  return bootstrapped;
6088
6281
  }
6089
- async function bootstrapWorkspacePackage(packageDir, iuiRoot) {
6090
- const resolvedPackage = path19.resolve(packageDir);
6091
- const resolvedIuiRoot = resolveIuiProjectRoot(iuiRoot);
6092
- if (!fs16.existsSync(path19.join(resolvedPackage, "package.json"))) {
6282
+ async function bootstrapWorkspacePackage(packageDir, iuiRoot2) {
6283
+ const resolvedPackage = path21.resolve(packageDir);
6284
+ const resolvedIuiRoot = resolveIuiProjectRoot(iuiRoot2);
6285
+ if (!fs17.existsSync(path21.join(resolvedPackage, "package.json"))) {
6093
6286
  throw new CLIError(
6094
6287
  `No package.json found in ${resolvedPackage}.`,
6095
6288
  "Run iui init from a workspace app directory that contains package.json."
@@ -6107,7 +6300,7 @@ async function bootstrapWorkspacePackage(packageDir, iuiRoot) {
6107
6300
  "This app is linked to an existing IUI setup \u2014 packages and configs stay at the IUI root."
6108
6301
  );
6109
6302
  nextSteps([
6110
- 'import "./iui/slot" in your app entry',
6303
+ 'import "./iui/bootstrap" in your app entry (or rely on Vite auto-wiring)',
6111
6304
  "iui doctor \u2014 Verify project health",
6112
6305
  "iui list \u2014 View installed components"
6113
6306
  ]);
@@ -6115,9 +6308,8 @@ async function bootstrapWorkspacePackage(packageDir, iuiRoot) {
6115
6308
 
6116
6309
  // src/services/slot-registry.ts
6117
6310
  var STATE_SCHEMA_VERSION = 1;
6118
- var STATE_FILE = "slot-registration-state.json";
6119
6311
  function statePath(cwd) {
6120
- return path20.join(cwd, IUI_DIR, STATE_FILE);
6312
+ return iuiCacheFile(cwd, "slotState");
6121
6313
  }
6122
6314
  function now() {
6123
6315
  return (/* @__PURE__ */ new Date()).toISOString();
@@ -6126,17 +6318,17 @@ function checksumFor(components, slots) {
6126
6318
  return sha256(JSON.stringify({ components, slots }));
6127
6319
  }
6128
6320
  function backupCorruptFile(filePath) {
6129
- if (!fs17.existsSync(filePath)) return;
6321
+ if (!fs18.existsSync(filePath)) return;
6130
6322
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
6131
6323
  try {
6132
- fs17.moveSync(filePath, `${filePath}.corrupt-${stamp}`, { overwrite: false });
6324
+ fs18.moveSync(filePath, `${filePath}.corrupt-${stamp}`, { overwrite: false });
6133
6325
  } catch {
6134
6326
  }
6135
6327
  }
6136
6328
  function readJsonObject(filePath, fallback, issues, label) {
6137
- if (!fs17.existsSync(filePath)) return fallback;
6329
+ if (!fs18.existsSync(filePath)) return fallback;
6138
6330
  try {
6139
- const value = fs17.readJsonSync(filePath);
6331
+ const value = fs18.readJsonSync(filePath);
6140
6332
  if (value && typeof value === "object" && !Array.isArray(value)) {
6141
6333
  return value;
6142
6334
  }
@@ -6148,9 +6340,9 @@ function readJsonObject(filePath, fallback, issues, label) {
6148
6340
  }
6149
6341
  function readState(cwd, issues) {
6150
6342
  const filePath = statePath(cwd);
6151
- if (!fs17.existsSync(filePath)) return null;
6343
+ if (!fs18.existsSync(filePath)) return null;
6152
6344
  try {
6153
- const raw = fs17.readJsonSync(filePath);
6345
+ const raw = fs18.readJsonSync(filePath);
6154
6346
  if (raw.schemaVersion !== STATE_SCHEMA_VERSION) {
6155
6347
  issues.push("registration state schema was upgraded");
6156
6348
  return null;
@@ -6252,9 +6444,9 @@ async function ensureSlotRegistry(options = {}) {
6252
6444
  if (!isInsideProject(cwd)) {
6253
6445
  return { status: "skipped", packageVersion: null, repairedIssues: [] };
6254
6446
  }
6255
- const iuiRoot = resolveIuiProjectRoot(cwd);
6256
- return withRegistryLock(iuiRoot, async () => {
6257
- const iuiPath = path20.join(iuiRoot, IUI_DIR);
6447
+ const iuiRoot2 = resolveIuiProjectRoot(cwd);
6448
+ return withRegistryLock(iuiRoot2, async () => {
6449
+ const iuiPath = path22.join(iuiRoot2, IUI_DIR);
6258
6450
  const issues = [];
6259
6451
  cleanupTempFiles(iuiPath);
6260
6452
  const registry = ensureInstalledManifest(
@@ -6265,23 +6457,23 @@ async function ensureSlotRegistry(options = {}) {
6265
6457
  return { status: "skipped", packageVersion: null, repairedIssues: [] };
6266
6458
  }
6267
6459
  const packageVersion = getInstalledPackageVersion(COMPONENTS_PACKAGE, cwd) ?? registry.version;
6268
- const previousState = readState(iuiRoot, issues);
6460
+ const previousState = readState(iuiRoot2, issues);
6269
6461
  let state = null;
6270
6462
  try {
6271
6463
  const currentComponents = readJsonObject(
6272
- componentManifestPath(iuiRoot),
6464
+ componentManifestPath(iuiRoot2),
6273
6465
  {},
6274
6466
  issues,
6275
6467
  ".iui/components.json"
6276
6468
  );
6277
6469
  const currentPackages = readJsonObject(
6278
- packageManifestPath(iuiRoot),
6470
+ packageManifestPath(iuiRoot2),
6279
6471
  {},
6280
6472
  issues,
6281
6473
  ".iui/packages.json"
6282
6474
  );
6283
6475
  const currentSlots = readJsonObject(
6284
- slotManifestPath(iuiRoot),
6476
+ slotManifestPath(iuiRoot2),
6285
6477
  {},
6286
6478
  issues,
6287
6479
  ".iui/slots.json"
@@ -6308,8 +6500,8 @@ async function ensureSlotRegistry(options = {}) {
6308
6500
  if (driftDetected) {
6309
6501
  issues.push("slot manifests drifted");
6310
6502
  }
6311
- const generationIssues = validateGeneratedSlotImports(iuiRoot);
6312
- const assetBoundIssues = validateGeneratedAssetBoundImports(iuiRoot);
6503
+ const generationIssues = validateGeneratedSlotImports(iuiRoot2);
6504
+ const assetBoundIssues = validateGeneratedAssetBoundImports(iuiRoot2);
6313
6505
  const integrityIssues = [...generationIssues, ...assetBoundIssues];
6314
6506
  if (shouldSkipWritesFastPath({
6315
6507
  mode,
@@ -6349,37 +6541,37 @@ async function ensureSlotRegistry(options = {}) {
6349
6541
  attempts: (previousState?.attempts ?? 0) + 1,
6350
6542
  repairedIssues: issues
6351
6543
  };
6352
- writeState(iuiRoot, state);
6353
- updateState(iuiRoot, state, "state-loaded");
6544
+ writeState(iuiRoot2, state);
6545
+ updateState(iuiRoot2, state, "state-loaded");
6354
6546
  await retry(() => {
6355
- writeComponentManifest(desired.components, iuiRoot);
6356
- writePackageManifest(currentPackages, iuiRoot);
6357
- writeSlotManifest(desired.slots, iuiRoot);
6547
+ writeComponentManifest(desired.components, iuiRoot2);
6548
+ writePackageManifest(currentPackages, iuiRoot2);
6549
+ writeSlotManifest(desired.slots, iuiRoot2);
6358
6550
  });
6359
- let next = updateState(iuiRoot, state, "manifests-written", {
6551
+ let next = updateState(iuiRoot2, state, "manifests-written", {
6360
6552
  checksum,
6361
6553
  repairedIssues: issues
6362
6554
  });
6363
6555
  await retry(async () => {
6364
- writeComponentSlotFiles(iuiRoot);
6365
- writeAssetsConfig(iuiRoot);
6366
- ensureProjectConfig(iuiRoot);
6367
- await writeAssetBoundFiles(iuiRoot);
6368
- writeSlotHelperFile(iuiRoot);
6556
+ writeComponentSlotFiles(iuiRoot2);
6557
+ writeAssetsConfig(iuiRoot2);
6558
+ ensureProjectConfig(iuiRoot2);
6559
+ await writeAssetBoundFiles(iuiRoot2);
6560
+ writeSlotHelperFile(iuiRoot2);
6369
6561
  if (projectHasViteTooling(cwd)) {
6370
6562
  ensureInventiveUiViteConfig(cwd);
6371
6563
  }
6372
6564
  });
6373
- bootstrapRegisteredPackages(iuiRoot);
6374
- next = updateState(iuiRoot, next, "slot-files-written", { repairedIssues: issues });
6565
+ bootstrapRegisteredPackages(iuiRoot2);
6566
+ next = updateState(iuiRoot2, next, "slot-files-written", { repairedIssues: issues });
6375
6567
  if (integrityIssues.length > 0) {
6376
6568
  throw new CLIError(
6377
6569
  "Slot registry integrity check failed.",
6378
6570
  integrityIssues.map((issue) => `- ${issue}`).join("\n")
6379
6571
  );
6380
6572
  }
6381
- next = updateState(iuiRoot, next, "integrity-verified", { repairedIssues: issues });
6382
- updateState(iuiRoot, next, "complete", {
6573
+ next = updateState(iuiRoot2, next, "integrity-verified", { repairedIssues: issues });
6574
+ updateState(iuiRoot2, next, "complete", {
6383
6575
  status: "complete",
6384
6576
  completedAt: now(),
6385
6577
  lastError: void 0,
@@ -6396,7 +6588,7 @@ async function ensureSlotRegistry(options = {}) {
6396
6588
  } catch (error) {
6397
6589
  const message = error instanceof Error ? error.message : "Slot registry update failed";
6398
6590
  if (state) {
6399
- updateState(iuiRoot, state, "state-loaded", {
6591
+ updateState(iuiRoot2, state, "state-loaded", {
6400
6592
  status: "failed",
6401
6593
  lastError: message,
6402
6594
  repairedIssues: issues
@@ -6549,7 +6741,7 @@ async function initCommand(opts) {
6549
6741
  try {
6550
6742
  heading("Initialize Project");
6551
6743
  const existingIuiRoot = findIuiProjectRoot(invocationCwd);
6552
- if (existingIuiRoot && path21.resolve(existingIuiRoot) !== path21.resolve(invocationCwd)) {
6744
+ if (existingIuiRoot && path23.resolve(existingIuiRoot) !== path23.resolve(invocationCwd)) {
6553
6745
  await bootstrapWorkspacePackage(invocationCwd, existingIuiRoot);
6554
6746
  return;
6555
6747
  }
@@ -6568,10 +6760,10 @@ async function initCommand(opts) {
6568
6760
  return;
6569
6761
  }
6570
6762
  const originalCwd = process.cwd();
6571
- if (path21.resolve(initRoot) !== path21.resolve(originalCwd)) {
6763
+ if (path23.resolve(initRoot) !== path23.resolve(originalCwd)) {
6572
6764
  process.chdir(initRoot);
6573
6765
  hint(
6574
- `Monorepo --workspace: initializing at ${path21.relative(invocationCwd, initRoot) || initRoot}`
6766
+ `Monorepo --workspace: initializing at ${path23.relative(invocationCwd, initRoot) || initRoot}`
6575
6767
  );
6576
6768
  } else if (!sharedWorkspace && findIuiProjectRoot(initRoot) === null) {
6577
6769
  hint("Initializing this package only \u2014 other monorepo apps are untouched.");
@@ -6630,7 +6822,12 @@ async function initCommand(opts) {
6630
6822
  projectId: project.project_id,
6631
6823
  repoUrl,
6632
6824
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
6633
- initScope: sharedWorkspace ? "workspace" : "package"
6825
+ initScope: sharedWorkspace ? "workspace" : "package",
6826
+ configs: {
6827
+ theme: "./iui.config.ts",
6828
+ assets: "./assets.config.json",
6829
+ components: "./component.config.ts"
6830
+ }
6634
6831
  };
6635
6832
  writeProjectMeta(meta, initRoot);
6636
6833
  step("Configuring npm registry\u2026");
@@ -7449,17 +7646,17 @@ async function deployTokenRevokeCommand(tokenId) {
7449
7646
  }
7450
7647
 
7451
7648
  // src/commands/setup.ts
7452
- import path24 from "path";
7453
- import fs19 from "fs-extra";
7649
+ import path26 from "path";
7650
+ import fs20 from "fs-extra";
7454
7651
  import ora6 from "ora";
7455
7652
 
7456
7653
  // src/commands/doctor.ts
7457
- import path23 from "path";
7654
+ import path25 from "path";
7458
7655
 
7459
7656
  // src/services/health.ts
7460
7657
  import { execFileSync as execFileSync2 } from "child_process";
7461
- import path22 from "path";
7462
- import fs18 from "fs-extra";
7658
+ import path24 from "path";
7659
+ import fs19 from "fs-extra";
7463
7660
  function installDevTypeScript(cwd) {
7464
7661
  const pm = detectPackageManager(cwd);
7465
7662
  try {
@@ -7502,8 +7699,8 @@ function checkGeneratedSlotValidity(cwd = process.cwd()) {
7502
7699
  };
7503
7700
  }
7504
7701
  function checkComponentConfigValidity(cwd = process.cwd(), options = {}) {
7505
- const configPath = path22.join(cwd, COMPONENT_CONFIG_FILE);
7506
- if (!fs18.existsSync(configPath)) {
7702
+ const configPath = path24.join(cwd, COMPONENT_CONFIG_FILE);
7703
+ if (!fs19.existsSync(configPath)) {
7507
7704
  return {
7508
7705
  ok: false,
7509
7706
  summary: "component.config.ts not found",
@@ -7511,8 +7708,8 @@ function checkComponentConfigValidity(cwd = process.cwd(), options = {}) {
7511
7708
  };
7512
7709
  }
7513
7710
  const tsPkgDir = resolvePackageDir("typescript", cwd);
7514
- const tscPath = tsPkgDir ? path22.join(tsPkgDir, "bin", "tsc") : path22.join(cwd, "node_modules", "typescript", "bin", "tsc");
7515
- if (!fs18.existsSync(tscPath)) {
7711
+ const tscPath = tsPkgDir ? path24.join(tsPkgDir, "bin", "tsc") : path24.join(cwd, "node_modules", "typescript", "bin", "tsc");
7712
+ if (!fs19.existsSync(tscPath)) {
7516
7713
  if (!options.autoFix) {
7517
7714
  return {
7518
7715
  ok: false,
@@ -7580,9 +7777,9 @@ ${stderr}`.trim() };
7580
7777
  function checkCompileFirstReadiness(cwd = process.cwd(), _options = {}) {
7581
7778
  const warnings = [];
7582
7779
  const hints = [];
7583
- const configPath = path22.join(cwd, PROJECT_CONFIG_FILE);
7584
- if (fs18.existsSync(configPath)) {
7585
- const configContent = fs18.readFileSync(configPath, "utf-8");
7780
+ const configPath = path24.join(cwd, PROJECT_CONFIG_FILE);
7781
+ if (fs19.existsSync(configPath)) {
7782
+ const configContent = fs19.readFileSync(configPath, "utf-8");
7586
7783
  if (!/\bbuild\s*:\s*\{/.test(configContent)) {
7587
7784
  warnings.push("iui.config.ts is missing a compile-first `build` block");
7588
7785
  hints.push(
@@ -7611,11 +7808,11 @@ function checkCompileFirstReadiness(cwd = process.cwd(), _options = {}) {
7611
7808
  }
7612
7809
  if (projectHasViteTooling(cwd)) {
7613
7810
  const viteCandidates = ["vite.config.ts", "vite.config.mjs", "vite.config.js"];
7614
- const vitePath = viteCandidates.map((name) => path22.join(cwd, name)).find((p) => fs18.existsSync(p));
7811
+ const vitePath = viteCandidates.map((name) => path24.join(cwd, name)).find((p) => fs19.existsSync(p));
7615
7812
  if (!vitePath) {
7616
7813
  warnings.push("Vite tooling detected but no vite.config.* found");
7617
7814
  } else {
7618
- const viteContent = fs18.readFileSync(vitePath, "utf-8");
7815
+ const viteContent = fs19.readFileSync(vitePath, "utf-8");
7619
7816
  if (!/inventiveUiVite\s*\(/.test(viteContent)) {
7620
7817
  warnings.push("vite.config is missing inventiveUiVite() \u2014 compile-first CSS will not generate");
7621
7818
  hints.push("Wire plugins: [...inventiveUiVite({ root: import.meta.dirname }), react()]");
@@ -7629,11 +7826,11 @@ function checkCompileFirstReadiness(cwd = process.cwd(), _options = {}) {
7629
7826
  "webpack.config.mjs",
7630
7827
  "webpack.config.ts"
7631
7828
  ];
7632
- const webpackPath = webpackCandidates.map((name) => path22.join(cwd, name)).find((p) => fs18.existsSync(p));
7829
+ const webpackPath = webpackCandidates.map((name) => path24.join(cwd, name)).find((p) => fs19.existsSync(p));
7633
7830
  if (!webpackPath) {
7634
7831
  warnings.push("Webpack tooling detected but no webpack.config.* found");
7635
7832
  } else {
7636
- const webpackContent = fs18.readFileSync(webpackPath, "utf-8");
7833
+ const webpackContent = fs19.readFileSync(webpackPath, "utf-8");
7637
7834
  if (!/inventiveUiWebpack\s*\(/.test(webpackContent)) {
7638
7835
  warnings.push("webpack.config is missing inventiveUiWebpack() \u2014 compile-first CSS will not generate");
7639
7836
  hints.push('Wire plugins: [...inventiveUiWebpack()] from "@inventive-ui/framework/webpack"');
@@ -7643,11 +7840,11 @@ function checkCompileFirstReadiness(cwd = process.cwd(), _options = {}) {
7643
7840
  }
7644
7841
  if (projectHasNextTooling(cwd)) {
7645
7842
  const nextCandidates = ["next.config.ts", "next.config.mjs", "next.config.js", "next.config.cjs"];
7646
- const nextPath = nextCandidates.map((name) => path22.join(cwd, name)).find((p) => fs18.existsSync(p));
7843
+ const nextPath = nextCandidates.map((name) => path24.join(cwd, name)).find((p) => fs19.existsSync(p));
7647
7844
  if (!nextPath) {
7648
7845
  warnings.push("Next.js detected but no next.config.* found");
7649
7846
  } else {
7650
- const nextContent = fs18.readFileSync(nextPath, "utf-8");
7847
+ const nextContent = fs19.readFileSync(nextPath, "utf-8");
7651
7848
  if (!/withIUI\s*\(/.test(nextContent)) {
7652
7849
  warnings.push("next.config is missing withIUI() \u2014 compile-first CSS will not generate");
7653
7850
  hints.push('Wrap config: export default withIUI({ ... }) from "@inventive-ui/framework/next"');
@@ -7660,11 +7857,26 @@ function checkCompileFirstReadiness(cwd = process.cwd(), _options = {}) {
7660
7857
  "src/app/layout.jsx",
7661
7858
  "app/providers.tsx",
7662
7859
  "src/app/providers.tsx"
7663
- ].map((rel) => path22.join(cwd, rel));
7664
- const hasRegistry = layoutCandidates.some((file) => {
7665
- if (!fs18.existsSync(file)) return false;
7860
+ ].map((rel) => path24.join(cwd, rel));
7861
+ const readableLayouts = layoutCandidates.filter((file) => fs19.existsSync(file));
7862
+ const hasRegistry = readableLayouts.some((file) => {
7666
7863
  try {
7667
- return /\bIUIRegistry\b/.test(fs18.readFileSync(file, "utf-8"));
7864
+ return /\bIUIRegistry\b/.test(fs19.readFileSync(file, "utf-8"));
7865
+ } catch {
7866
+ return false;
7867
+ }
7868
+ });
7869
+ const hasBootstrapImport = readableLayouts.some((file) => {
7870
+ try {
7871
+ const content = fs19.readFileSync(file, "utf-8");
7872
+ return /next\/bootstrap/.test(content) || /["']iui-bootstrap["']/.test(content) || /iui\/bootstrap/.test(content);
7873
+ } catch {
7874
+ return false;
7875
+ }
7876
+ });
7877
+ const hasProvider = readableLayouts.some((file) => {
7878
+ try {
7879
+ return /\bIUIProvider\b/.test(fs19.readFileSync(file, "utf-8"));
7668
7880
  } catch {
7669
7881
  return false;
7670
7882
  }
@@ -7673,6 +7885,16 @@ function checkCompileFirstReadiness(cwd = process.cwd(), _options = {}) {
7673
7885
  warnings.push("Next.js app should wrap the root layout with <IUIRegistry>");
7674
7886
  hints.push('Import IUIRegistry from "@inventive-ui/framework/next/registry" in the root layout');
7675
7887
  }
7888
+ if (!hasBootstrapImport) {
7889
+ warnings.push("Next.js root layout should import bootstrap before render");
7890
+ hints.push(
7891
+ 'Add `import "@inventive-ui/framework/next/bootstrap"` to the root layout (server) and client providers'
7892
+ );
7893
+ }
7894
+ if (!hasProvider) {
7895
+ warnings.push("Next.js app should use <IUIProvider> for bootstrap-state runtime");
7896
+ hints.push('Wrap children with <IUIProvider> from "@inventive-ui/framework" inside IUIRegistry');
7897
+ }
7676
7898
  }
7677
7899
  const entryCandidates = [
7678
7900
  "src/main.tsx",
@@ -7685,14 +7907,14 @@ function checkCompileFirstReadiness(cwd = process.cwd(), _options = {}) {
7685
7907
  "src/app/providers.tsx",
7686
7908
  "app/layout.tsx",
7687
7909
  "src/app/layout.tsx"
7688
- ].map((rel) => path22.join(cwd, rel));
7910
+ ].map((rel) => path24.join(cwd, rel));
7689
7911
  for (const file of entryCandidates) {
7690
- if (!fs18.existsSync(file)) continue;
7912
+ if (!fs19.existsSync(file)) continue;
7691
7913
  try {
7692
- const content = fs18.readFileSync(file, "utf-8");
7914
+ const content = fs19.readFileSync(file, "utf-8");
7693
7915
  if (/from\s+['"][^'"]*\.generated['"]/.test(content) || /import\s+['"][^'"]*\.generated['"]/.test(content)) {
7694
7916
  warnings.push(
7695
- `Do not import .generated style-map files into the browser (${path22.relative(cwd, file)})`
7917
+ `Do not import .generated style-map files into the browser (${path24.relative(cwd, file)})`
7696
7918
  );
7697
7919
  hints.push(
7698
7920
  "Keep style maps on the scanner path (default src/.iui, or override build.scanDirs) \u2014 see Framework compile-first docs"
@@ -7712,32 +7934,32 @@ function checkCompileFirstReadiness(cwd = process.cwd(), _options = {}) {
7712
7934
  hints.push(
7713
7935
  "Compile-first: avoid dynamic utility templates like `p-${n}` \u2014 use static strings, style maps, or safelist (ESLint: customPlugin/no-dynamic-utility-class)"
7714
7936
  );
7715
- const giPath = path22.join(cwd, ".gitignore");
7716
- if (fs18.existsSync(giPath)) {
7717
- const gi = fs18.readFileSync(giPath, "utf-8");
7718
- if (!gi.includes(".iui/classes.cache.json")) {
7719
- warnings.push(".gitignore missing IUI compile cache entries (.iui/classes.cache.json)");
7720
- hints.push("Run iui init or append compile cache paths from the IUI docs");
7937
+ const giPath = path24.join(cwd, ".gitignore");
7938
+ if (fs19.existsSync(giPath)) {
7939
+ const gi = fs19.readFileSync(giPath, "utf-8");
7940
+ if (!gi.includes(".iui/cache/")) {
7941
+ warnings.push(".gitignore missing IUI cache directory (.iui/cache/)");
7942
+ hints.push("Run iui init or append .iui/cache/ from the IUI docs");
7721
7943
  }
7722
7944
  }
7723
7945
  return { warnings, hints };
7724
7946
  }
7725
7947
  function checkAssetBoundBindings(cwd = process.cwd()) {
7726
- const assetsPath = path22.join(cwd, ASSETS_CONFIG_FILE);
7727
- if (!fs18.existsSync(assetsPath)) {
7948
+ const assetsPath = path24.join(cwd, ASSETS_CONFIG_FILE);
7949
+ if (!fs19.existsSync(assetsPath)) {
7728
7950
  return { ok: true, summary: "Asset binding check skipped (no assets.config.json)" };
7729
7951
  }
7730
7952
  let assets2;
7731
7953
  try {
7732
- assets2 = fs18.readJsonSync(assetsPath);
7954
+ assets2 = fs19.readJsonSync(assetsPath);
7733
7955
  } catch {
7734
7956
  return { ok: false, summary: "assets.config.json is not valid JSON" };
7735
7957
  }
7736
7958
  if (assets2.binding !== "scanned") {
7737
7959
  return { ok: true, summary: "Asset slots use lazy binding (default)" };
7738
7960
  }
7739
- const registerBound = path22.join(generatedAssetsDir(cwd), "register-bound.ts");
7740
- if (!fs18.existsSync(registerBound)) {
7961
+ const registerBound = path24.join(generatedAssetsDir(cwd), "register-bound.ts");
7962
+ if (!fs19.existsSync(registerBound)) {
7741
7963
  return {
7742
7964
  ok: false,
7743
7965
  summary: 'binding is "scanned" but .iui/generated/assets/register-bound.ts is missing',
@@ -7746,6 +7968,76 @@ function checkAssetBoundBindings(cwd = process.cwd()) {
7746
7968
  }
7747
7969
  return { ok: true, summary: "Scanned asset bindings present" };
7748
7970
  }
7971
+ function checkBootstrapSync(cwd = process.cwd(), options = {}) {
7972
+ const iuiRoot2 = resolveIuiProjectRoot(cwd);
7973
+ const generatedPath = bootstrapGeneratedPath(iuiRoot2);
7974
+ const bridgePath = path24.join(cwd, "src", "iui", "bootstrap.ts");
7975
+ if (!fs19.existsSync(generatedPath)) {
7976
+ if (options.autoFix) {
7977
+ writeProjectBootstrapArtifacts(cwd, iuiRoot2);
7978
+ if (fs19.existsSync(generatedPath)) {
7979
+ return { ok: true, summary: "Generated bootstrap artifacts repaired" };
7980
+ }
7981
+ }
7982
+ return {
7983
+ ok: false,
7984
+ summary: "Generated bootstrap missing",
7985
+ details: "Expected .iui/generated/bootstrap.generated.tsx \u2014 run iui doctor --fix."
7986
+ };
7987
+ }
7988
+ if (!fs19.existsSync(bridgePath)) {
7989
+ if (options.autoFix) {
7990
+ writeProjectBootstrapArtifacts(cwd, iuiRoot2);
7991
+ if (fs19.existsSync(bridgePath)) {
7992
+ return { ok: true, summary: "Bootstrap bridge repaired" };
7993
+ }
7994
+ }
7995
+ return {
7996
+ ok: false,
7997
+ summary: "Bootstrap bridge missing",
7998
+ details: "Expected src/iui/bootstrap.ts \u2014 run iui doctor --fix."
7999
+ };
8000
+ }
8001
+ const configs = resolveProjectConfigPaths(iuiRoot2);
8002
+ const missing = [];
8003
+ for (const [key, rel] of Object.entries(configs)) {
8004
+ const abs = path24.resolve(iuiRoot2, rel.replace(/^\.\//, ""));
8005
+ if (!fs19.existsSync(abs)) missing.push(`${key}: ${rel}`);
8006
+ }
8007
+ if (missing.length > 0) {
8008
+ return {
8009
+ ok: false,
8010
+ summary: "Bootstrap config paths from project.json are missing",
8011
+ details: missing.map((line) => `- ${line}`).join("\n")
8012
+ };
8013
+ }
8014
+ const expected = expectedBootstrapImportPaths(iuiRoot2);
8015
+ const generated = fs19.readFileSync(generatedPath, "utf8");
8016
+ const stale = [];
8017
+ for (const [key, importPath] of Object.entries(expected)) {
8018
+ if (!generated.includes(`"${importPath}"`)) {
8019
+ stale.push(`${key} import should be "${importPath}"`);
8020
+ }
8021
+ }
8022
+ if (stale.length > 0) {
8023
+ if (options.autoFix) {
8024
+ writeProjectBootstrapArtifacts(cwd, iuiRoot2);
8025
+ const refreshed = fs19.readFileSync(bootstrapGeneratedPath(iuiRoot2), "utf8");
8026
+ const stillStale = Object.entries(expected).filter(
8027
+ ([, importPath]) => !refreshed.includes(`"${importPath}"`)
8028
+ );
8029
+ if (stillStale.length === 0) {
8030
+ return { ok: true, summary: "Generated bootstrap refreshed from project.json" };
8031
+ }
8032
+ }
8033
+ return {
8034
+ ok: false,
8035
+ summary: "Generated bootstrap is stale",
8036
+ details: stale.map((line) => `- ${line}`).join("\n")
8037
+ };
8038
+ }
8039
+ return { ok: true, summary: "Generated bootstrap matches project.json config paths" };
8040
+ }
7749
8041
 
7750
8042
  // src/commands/doctor.ts
7751
8043
  function runConfigTierDiagnostics(targetCwd, opts, counters, options = {}) {
@@ -7975,6 +8267,22 @@ async function runPackageDiagnostics(targetCwd, opts, counters) {
7975
8267
  }
7976
8268
  hint("Fix: reinstall @inventive-ui/components and rerun iui doctor");
7977
8269
  }
8270
+ const bootstrapSync = checkBootstrapSync(targetCwd, {
8271
+ autoFix: opts?.fix === true
8272
+ });
8273
+ if (bootstrapSync.ok) {
8274
+ pass(bootstrapSync.summary);
8275
+ } else {
8276
+ fail2(bootstrapSync.summary);
8277
+ if (bootstrapSync.details) {
8278
+ for (const line of bootstrapSync.details.split("\n")) {
8279
+ hint(line);
8280
+ }
8281
+ }
8282
+ if (!opts?.fix) {
8283
+ hint("Fix: run iui doctor --fix to regenerate bootstrap artifacts");
8284
+ }
8285
+ }
7978
8286
  runConfigTierDiagnostics(targetCwd, opts, counters, {
7979
8287
  includePackageJson: false,
7980
8288
  includeSlotCheck: false
@@ -7983,7 +8291,7 @@ async function runPackageDiagnostics(targetCwd, opts, counters) {
7983
8291
  async function doctorCommand(opts) {
7984
8292
  try {
7985
8293
  const invocationCwd = process.cwd();
7986
- const targets = opts?.cwd ? [path23.resolve(opts.cwd)] : resolveSetupDoctorTargets(invocationCwd);
8294
+ const targets = opts?.cwd ? [path25.resolve(opts.cwd)] : resolveSetupDoctorTargets(invocationCwd);
7987
8295
  const installRoot = resolveDependencyInstallRoot(invocationCwd);
7988
8296
  const multiPackage = targets.length > 1;
7989
8297
  heading("Diagnostics");
@@ -8026,7 +8334,7 @@ async function doctorCommand(opts) {
8026
8334
  for (const targetCwd of targets) {
8027
8335
  if (multiPackage) {
8028
8336
  newline();
8029
- const label = path23.relative(installRoot, targetCwd) || path23.basename(targetCwd);
8337
+ const label = path25.relative(installRoot, targetCwd) || path25.basename(targetCwd);
8030
8338
  kv("Package", label);
8031
8339
  }
8032
8340
  await runPackageDiagnostics(targetCwd, opts, counters);
@@ -8054,9 +8362,9 @@ async function doctorCommand(opts) {
8054
8362
 
8055
8363
  // src/commands/setup.ts
8056
8364
  function detectDevScript(cwd) {
8057
- const pkgPath = path24.join(cwd, "package.json");
8365
+ const pkgPath = path26.join(cwd, "package.json");
8058
8366
  try {
8059
- const pkg = fs19.readJsonSync(pkgPath);
8367
+ const pkg = fs20.readJsonSync(pkgPath);
8060
8368
  if (pkg.scripts?.dev) return "npm run dev";
8061
8369
  if (pkg.scripts?.start) return "npm run start";
8062
8370
  } catch {
@@ -8065,8 +8373,8 @@ function detectDevScript(cwd) {
8065
8373
  return null;
8066
8374
  }
8067
8375
  function relativePackageLabel(installRoot, packageDir) {
8068
- const rel = path24.relative(installRoot, packageDir);
8069
- return rel && rel !== "." ? rel : path24.basename(packageDir);
8376
+ const rel = path26.relative(installRoot, packageDir);
8377
+ return rel && rel !== "." ? rel : path26.basename(packageDir);
8070
8378
  }
8071
8379
  async function setupCommand(opts) {
8072
8380
  try {
@@ -8075,7 +8383,7 @@ async function setupCommand(opts) {
8075
8383
  const installRoot = resolveDependencyInstallRoot(cwd);
8076
8384
  const workspaceRoot = findWorkspaceRoot(cwd);
8077
8385
  const inMonorepo = workspaceRoot !== null;
8078
- const installFromChild = inMonorepo && path24.resolve(installRoot) !== path24.resolve(cwd);
8386
+ const installFromChild = inMonorepo && path26.resolve(installRoot) !== path26.resolve(cwd);
8079
8387
  if (!hasPackageJson(cwd) && !hasPackageJson(installRoot)) {
8080
8388
  throw new CLIError(
8081
8389
  "No package.json found in the current directory.",
@@ -8109,7 +8417,7 @@ async function setupCommand(opts) {
8109
8417
  for (const w of warnings) warn(w);
8110
8418
  kv("Package manager", `${pm} (${source})`);
8111
8419
  if (installFromChild) {
8112
- const rel = path24.relative(cwd, installRoot) || ".";
8420
+ const rel = path26.relative(cwd, installRoot) || ".";
8113
8421
  kv("Install directory", rel === ".." || rel.includes("..") ? installRoot : rel);
8114
8422
  }
8115
8423
  const installCmd2 = syncInstallCommand(pm);
@@ -8123,7 +8431,7 @@ async function setupCommand(opts) {
8123
8431
  } catch (err) {
8124
8432
  installSpinner.fail("Dependency install failed");
8125
8433
  const detail = formatExecSyncError(err);
8126
- const manual = path24.resolve(installRoot) === path24.resolve(cwd) ? installCmd2 : `cd ${JSON.stringify(installRoot)} && ${installCmd2}`;
8434
+ const manual = path26.resolve(installRoot) === path26.resolve(cwd) ? installCmd2 : `cd ${JSON.stringify(installRoot)} && ${installCmd2}`;
8127
8435
  throw new CLIError(
8128
8436
  detail ? `Could not install project dependencies.
8129
8437
  ${detail}` : "Could not install project dependencies.",
@@ -8281,7 +8589,7 @@ async function updateCommand(opts = {}) {
8281
8589
  const auth = await ensureAuthSession();
8282
8590
  await ensureLicenseSession();
8283
8591
  const inProject = isInsideProject();
8284
- const currentCliVersion = true ? "0.0.2" : "unknown";
8592
+ const currentCliVersion = true ? "0.0.4" : "unknown";
8285
8593
  const latestCliVersion = await fetchLatestCliVersion(auth.token);
8286
8594
  const cliUpdateAvailable = latestCliVersion !== null && isVersionGreater(latestCliVersion, currentCliVersion);
8287
8595
  if (latestCliVersion && cliUpdateAvailable) {
@@ -8563,7 +8871,7 @@ var AUTH_EXEMPT_COMMANDS = /* @__PURE__ */ new Set([
8563
8871
  "doctor",
8564
8872
  "list"
8565
8873
  ]);
8566
- program.name("iui").description("The official CLI for the Inventive UI Design System").version(true ? "0.0.2" : "1.0.0").option("-C, --cwd <dir>", "Run as if started in the given directory").option("-q, --quiet", "Minimal output (also respects IUI_QUIET=1)").option("--no-color", "Disable ANSI colors");
8874
+ program.name("iui").description("The official CLI for the Inventive UI Design System").version(true ? "0.0.4" : "1.0.0").option("-C, --cwd <dir>", "Run as if started in the given directory").option("-q, --quiet", "Minimal output (also respects IUI_QUIET=1)").option("--no-color", "Disable ANSI colors");
8567
8875
  program.command("login").description("Authenticate with GitHub and link your license").option("-f, --force", "Force re-authentication and register this device").option("--bootstrap", "After login, run optional setup prompts").action((opts) => loginCommand(opts));
8568
8876
  program.command("logout").description("Remove stored credentials").action(logoutCommand);
8569
8877
  program.command("whoami").description("Show authenticated identity and license details").action(whoamiCommand);
@@ -8661,7 +8969,7 @@ program.hook("preAction", async (_thisCommand, actionCommand) => {
8661
8969
  const root = topLevelCommandName(actionCommand);
8662
8970
  const globalOpts = program.opts();
8663
8971
  if (globalOpts.cwd) {
8664
- process.chdir(path25.resolve(globalOpts.cwd));
8972
+ process.chdir(path27.resolve(globalOpts.cwd));
8665
8973
  }
8666
8974
  if (isInsideProject()) {
8667
8975
  try {