inventive-ui 0.0.8 → 0.0.10

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
@@ -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.8" : "1.0.0";
193
+ return true ? "0.0.10" : "1.0.0";
194
194
  } catch {
195
195
  return "1.0.0";
196
196
  }
@@ -1443,42 +1443,6 @@ function buildProjectConfigSource(cwd = process.cwd()) {
1443
1443
  });
1444
1444
  }
1445
1445
 
1446
- // src/utils/security/identifiers.ts
1447
- var SLUG_RE = /^[a-z][a-z0-9-]*$/;
1448
- var JS_IDENTIFIER_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
1449
- var NPM_SCOPE_IMPORT_RE = /^@inventive-ui\/[a-z0-9][a-z0-9._-]*$/;
1450
- var NPM_COMPONENT_SUBPATH_RE = /^@inventive-ui\/components\/[A-Za-z][A-Za-z0-9-]*$/;
1451
- function assertComponentSlug(slug) {
1452
- if (!SLUG_RE.test(slug)) {
1453
- throw new CLIError(
1454
- `Invalid component slug: "${slug}"`,
1455
- "Use lowercase letters, numbers, and hyphens (e.g. button, input)."
1456
- );
1457
- }
1458
- }
1459
- function assertJsIdentifier(name, label) {
1460
- if (!JS_IDENTIFIER_RE.test(name)) {
1461
- throw new CLIError(`Invalid ${label}: "${name}"`);
1462
- }
1463
- }
1464
- function assertImportSpecifier(specifier) {
1465
- if (NPM_SCOPE_IMPORT_RE.test(specifier)) return;
1466
- if (NPM_COMPONENT_SUBPATH_RE.test(specifier)) return;
1467
- if (/^@inventive-ui\/[a-z0-9][a-z0-9-]*$/.test(specifier)) return;
1468
- throw new CLIError(`Unsafe import specifier: "${specifier}"`);
1469
- }
1470
- function escapeTsStringLiteral(value) {
1471
- return JSON.stringify(value);
1472
- }
1473
- function sanitizePackageVersionHeader(value) {
1474
- if (!value) return null;
1475
- const trimmed = value.trim();
1476
- if (!/^[0-9A-Za-z.+~^<>= -]+$/.test(trimmed) || trimmed.length > 64) {
1477
- throw new CLIError("Server returned an invalid package version header.");
1478
- }
1479
- return trimmed;
1480
- }
1481
-
1482
1446
  // src/utils/config-patch/vite-config.ts
1483
1447
  import ts from "typescript";
1484
1448
  var IUI_MANAGED_MARKER = "@iui-managed";
@@ -1955,452 +1919,54 @@ function patchViteConfigContent(source) {
1955
1919
  }
1956
1920
 
1957
1921
  // src/utils/config-patch/iui-config.ts
1958
- var BUILD_BLOCK = ` /**
1959
- * Compile-first CSS \u2014 scanned at build time by the Vite/Webpack/Next plugin.
1960
- * Do not import style-map ".generated" files into the browser graph.
1961
- * scanDirs / scanPackages default in Framework \u2014 override only when needed.
1962
- * See Framework docs/01-compile-first-guide.md for all build options.
1963
- */
1964
- build: {
1965
- safelist: [],
1966
- includeShadeMatrix: false,
1967
- includeThemePresets: true,
1968
- includeThemeGrayScale: true,
1969
- resolvePalettePatterns: true,
1970
- includeArbitraryScan: true,
1971
- writeFiles: false,
1972
- minify: true,
1973
- useAst: true,
1974
- },
1975
- `;
1976
- var BUILD_DEFAULT_ENTRIES = [
1977
- ["safelist", "[]"],
1978
- ["includeShadeMatrix", "false"],
1979
- ["includeThemePresets", "true"],
1980
- ["includeThemeGrayScale", "true"],
1981
- ["resolvePalettePatterns", "true"],
1982
- ["includeArbitraryScan", "true"],
1983
- ["writeFiles", "false"],
1984
- ["minify", "true"],
1985
- ["useAst", "true"]
1986
- ];
1922
+ var DEPRECATED_BUILD_FLAG = /\b(includeShadeMatrix|includeThemePresets|includeThemeGrayScale|resolvePalettePatterns|includeArbitraryScan|packageSafelist|useAst|writeFiles)\s*:/;
1987
1923
  function patchProjectConfigBuildBlock(content) {
1988
- if (!/\bbuild\s*:\s*\{/.test(content)) {
1989
- const updated = content.replace(
1990
- /(\n)(};)\s*\n(\s*export default config;)/,
1991
- `$1${BUILD_BLOCK}$1$2
1992
- $3`
1993
- );
1994
- if (updated === content) return { content, changed: false };
1995
- return { content: updated, changed: true };
1996
- }
1997
- let next = content;
1998
- let changed = false;
1999
- if (!/\bbuild\s*:\s*\{/.test(next)) {
1924
+ if (DEPRECATED_BUILD_FLAG.test(content)) {
2000
1925
  return { content, changed: false };
2001
1926
  }
2002
- for (const [key, value] of BUILD_DEFAULT_ENTRIES) {
2003
- if (new RegExp(`\\b${key}\\s*:`).test(next)) continue;
2004
- const replaced = next.replace(/(\bbuild\s*:\s*\{\n)/, `$1 ${key}: ${value},
2005
- `);
2006
- if (replaced !== next) {
2007
- next = replaced;
2008
- changed = true;
2009
- }
1927
+ if (/\bscan\s*:\s*\{/.test(content)) {
1928
+ return { content, changed: false };
2010
1929
  }
2011
- return { content: next, changed };
1930
+ return { content, changed: false };
2012
1931
  }
2013
1932
 
2014
1933
  // src/utils/config-patch/component-config.ts
2015
1934
  import ts2 from "typescript";
2016
1935
 
2017
- // src/utils/componentExports.ts
2018
- import path7 from "path";
2019
- import fs6 from "fs-extra";
2020
- function toRecord(value) {
2021
- if (!value || typeof value !== "object" || Array.isArray(value)) return null;
2022
- return value;
2023
- }
2024
- function toPascalCase(value) {
2025
- return value.replace(/(^|[-_\s]+)([a-zA-Z0-9])/g, (_m, _p, c) => c.toUpperCase()).replace(/[^a-zA-Z0-9]/g, "");
2026
- }
2027
- function readComponentsPackageInfo(cwd) {
2028
- const packageRoot = resolvePackageDir("@inventive-ui/components", cwd);
2029
- if (!packageRoot) return null;
2030
- const pkgPath = path7.join(packageRoot, "package.json");
2031
- if (!fs6.existsSync(pkgPath)) return null;
2032
- try {
2033
- const pkg = fs6.readJsonSync(pkgPath);
2034
- const exportsField = toRecord(pkg.exports) ?? {};
2035
- const rootExport = toRecord(exportsField["."]);
2036
- const rootTypes = resolveTypesPathFromExportEntry(rootExport) ?? (typeof pkg.types === "string" ? pkg.types : null);
2037
- return {
2038
- packageRoot,
2039
- exportsField,
2040
- rootTypesPath: rootTypes ? path7.join(packageRoot, rootTypes) : null
2041
- };
2042
- } catch {
2043
- return null;
2044
- }
2045
- }
2046
- function resolveTypesPathFromExportEntry(entry) {
2047
- if (!entry) return null;
2048
- if (typeof entry === "string") return null;
2049
- const obj = toRecord(entry);
2050
- if (!obj) return null;
2051
- if (typeof obj.types === "string") return obj.types;
2052
- for (const key of ["import", "require", "default", "node", "browser"]) {
2053
- const nested = toRecord(obj[key]);
2054
- if (!nested) continue;
2055
- if (typeof nested.types === "string") return nested.types;
2056
- }
2057
- return null;
2058
- }
2059
- function parseNamedExportClause(clause, parsed) {
2060
- const parts = clause.split(",").map((p) => p.trim()).filter(Boolean);
2061
- for (const rawPart of parts) {
2062
- let part = rawPart;
2063
- let isTypeOnly = false;
2064
- if (part.startsWith("type ")) {
2065
- isTypeOnly = true;
2066
- part = part.slice("type ".length).trim();
2067
- }
2068
- const asMatch = part.match(/^([A-Za-z_][A-Za-z0-9_]*)\s+as\s+([A-Za-z_][A-Za-z0-9_]*)$/);
2069
- const symbol = asMatch ? asMatch[2] : part;
2070
- if (!symbol) continue;
2071
- if (isTypeOnly) parsed.typeExports.add(symbol);
2072
- else parsed.valueExports.add(symbol);
2073
- }
2074
- }
2075
- function mergeParsedExports(target, source) {
2076
- for (const sym of source.valueExports) target.valueExports.add(sym);
2077
- for (const sym of source.typeExports) target.typeExports.add(sym);
2078
- }
2079
- function resolveRelativeTypesPath(fromFile, rel) {
2080
- const base = path7.dirname(fromFile);
2081
- const noExt = path7.join(base, rel);
2082
- const candidates = [`${noExt}.d.ts`, path7.join(noExt, "index.d.ts")];
2083
- for (const candidate of candidates) {
2084
- if (fs6.existsSync(candidate)) return candidate;
2085
- }
2086
- return null;
2087
- }
2088
- function parseTypeExports(typesFilePath, visited = /* @__PURE__ */ new Set()) {
2089
- const parsed = {
2090
- valueExports: /* @__PURE__ */ new Set(),
2091
- typeExports: /* @__PURE__ */ new Set()
2092
- };
2093
- const abs = path7.resolve(typesFilePath);
2094
- if (visited.has(abs)) return parsed;
2095
- visited.add(abs);
2096
- if (!fs6.existsSync(abs)) return parsed;
2097
- let text = "";
2098
- try {
2099
- text = fs6.readFileSync(abs, "utf-8");
2100
- } catch {
2101
- return parsed;
2102
- }
2103
- applyTypeExportPatterns(text, parsed);
2104
- const reexportFrom = text.matchAll(
2105
- /export\s+(?:type\s+)?(?:\{[^}]*\}|\*)\s+from\s+["'](\.[^"']+)["']/g
2106
- );
2107
- for (const m of reexportFrom) {
2108
- const refPath = resolveRelativeTypesPath(abs, m[1]);
2109
- if (refPath) mergeParsedExports(parsed, parseTypeExports(refPath, visited));
2110
- }
2111
- return parsed;
2112
- }
2113
- function parseTypeExportsLocal(typesFilePath) {
2114
- const parsed = {
2115
- valueExports: /* @__PURE__ */ new Set(),
2116
- typeExports: /* @__PURE__ */ new Set()
2117
- };
2118
- const abs = path7.resolve(typesFilePath);
2119
- if (!fs6.existsSync(abs)) return parsed;
2120
- let text = "";
2121
- try {
2122
- text = fs6.readFileSync(abs, "utf-8");
2123
- } catch {
2124
- return parsed;
2125
- }
2126
- applyTypeExportPatterns(text, parsed);
2127
- return parsed;
2128
- }
2129
- function applyTypeExportPatterns(text, parsed) {
2130
- const valueDecl = /export\s+(?:declare\s+)?(?:const|let|var|function|class)\s+([A-Za-z_][A-Za-z0-9_]*)/g;
2131
- const typeDecl = /export\s+(?:declare\s+)?(?:type|interface)\s+([A-Za-z_][A-Za-z0-9_]*)/g;
2132
- const namedClause = /export\s+(?!type\s*\{)\{([^}]+)\}/g;
2133
- const typeNamedClause = /export\s+type\s*\{([^}]+)\}/g;
2134
- for (const m of text.matchAll(valueDecl)) {
2135
- parsed.valueExports.add(m[1]);
2136
- }
2137
- for (const m of text.matchAll(typeDecl)) {
2138
- parsed.typeExports.add(m[1]);
2139
- }
2140
- for (const m of text.matchAll(namedClause)) {
2141
- parseNamedExportClause(m[1], parsed);
2142
- }
2143
- for (const m of text.matchAll(typeNamedClause)) {
2144
- parseNamedExportClause(m[1], parsed);
2145
- }
2146
- }
2147
- function pickComponentName(item, parsed) {
2148
- const expected = [toPascalCase(item.dirName), toPascalCase(item.name)];
2149
- for (const name of expected) {
2150
- if (parsed.valueExports.has(name)) return name;
2151
- }
2152
- const lowered = new Set(expected.map((n) => n.toLowerCase()));
2153
- for (const exp of parsed.valueExports) {
2154
- if (lowered.has(exp.toLowerCase())) return exp;
2155
- }
2156
- return null;
2157
- }
2158
- function pickPropsName(componentName, parsed) {
2159
- const direct = `${componentName}Props`;
2160
- if (parsed.typeExports.has(direct) || parsed.valueExports.has(direct)) return direct;
2161
- for (const sym of parsed.typeExports) {
2162
- if (sym.toLowerCase() === direct.toLowerCase()) return sym;
2163
- }
2164
- for (const sym of parsed.valueExports) {
2165
- if (sym.toLowerCase() === direct.toLowerCase()) return sym;
2166
- }
2167
- return null;
2168
- }
2169
- function pickDefaultExportComponent(item, typesIndexPath) {
2170
- const expected = [toPascalCase(item.dirName), toPascalCase(item.name)];
2171
- for (const name of expected) {
2172
- const mainTypesPath = findMainComponentTypesPath(typesIndexPath, name);
2173
- if (!mainTypesPath) continue;
2174
- const mainText = readTypesFileText(mainTypesPath);
2175
- const defaultExportMatch = mainText.match(/export\s+default\s+([A-Za-z_][A-Za-z0-9_]*)/);
2176
- if (!defaultExportMatch) continue;
2177
- const symbol = defaultExportMatch[1];
2178
- if (expected.some((candidate) => candidate.toLowerCase() === symbol.toLowerCase())) {
2179
- return symbol;
2180
- }
2181
- }
2182
- return null;
2183
- }
2184
- function readTypesFileText(typesFilePath) {
2185
- try {
2186
- return fs6.readFileSync(typesFilePath, "utf-8");
2187
- } catch {
2188
- return "";
2189
- }
2190
- }
2191
- function findMainComponentTypesPath(typesIndexPath, componentName) {
2192
- const dir = path7.dirname(typesIndexPath);
2193
- const indexText = readTypesFileText(typesIndexPath);
2194
- const fromMatches = indexText.matchAll(/from\s+["']\.\/([^"']+)["']/g);
2195
- for (const match of fromMatches) {
2196
- const candidate = path7.join(dir, `${match[1]}.d.ts`);
2197
- if (fs6.existsSync(candidate)) return candidate;
2198
- }
2199
- const byName = path7.join(dir, `${componentName}.d.ts`);
2200
- return fs6.existsSync(byName) ? byName : null;
2201
- }
2202
- function isNonCallableCompoundExport(typesText, symbolName) {
2203
- const objectDecl = new RegExp(
2204
- `(?:declare\\s+const|const)\\s+${symbolName}\\s*:\\s*\\{`
2205
- );
2206
- return objectDecl.test(typesText);
2207
- }
2208
- function pickCompoundRenderMember(typesText) {
2209
- if (/\bText\s*:\s*React\./.test(typesText)) return "Text";
2210
- const memberMatch = typesText.match(
2211
- /^\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*React\.(?:ForwardRefExoticComponent|NamedExoticComponent|FC)/m
2212
- );
2213
- return memberMatch?.[1] ?? "Text";
2214
- }
2215
- function resolveLazyAccess(typesIndexPath, componentName) {
2216
- const indexText = readTypesFileText(typesIndexPath);
2217
- const mainTypesPath = findMainComponentTypesPath(typesIndexPath, componentName);
2218
- const mainText = mainTypesPath ? readTypesFileText(mainTypesPath) : "";
2219
- const defaultAsMatch = indexText.match(
2220
- new RegExp(`export\\s*\\{[^}]*\\bdefault\\s+as\\s+${componentName}\\b[^}]*\\}`)
2221
- );
2222
- const namedExportMatch = indexText.match(
2223
- new RegExp(`export\\s*\\{[^}]*\\b${componentName}\\b[^}]*\\}`)
2224
- );
2225
- const defaultExportMatch = mainText.match(/export\s+default\s+([A-Za-z_][A-Za-z0-9_]*)/);
2226
- const defaultSymbol = defaultExportMatch?.[1];
2227
- const compoundSymbol = defaultSymbol && isNonCallableCompoundExport(mainText, defaultSymbol) ? defaultSymbol : isNonCallableCompoundExport(mainText, componentName) ? componentName : null;
2228
- if (compoundSymbol) {
2229
- const member = pickCompoundRenderMember(mainText);
2230
- if (defaultAsMatch || namedExportMatch) {
2231
- return `.${componentName}.${member}`;
2232
- }
2233
- return `.default.${member}`;
2234
- }
2235
- if (defaultAsMatch || namedExportMatch) return `.${componentName}`;
2236
- if (defaultSymbol && defaultSymbol === componentName) {
2237
- return `.default`;
2238
- }
2239
- return `.${componentName}`;
2240
- }
2241
- function subpathExposesLazyBinding(typesIndexPath, componentName) {
2242
- const indexText = readTypesFileText(typesIndexPath);
2243
- if (new RegExp(`export\\s*\\{[^}]*\\bdefault\\s+as\\s+${componentName}\\b[^}]*\\}`).test(
2244
- indexText
2245
- )) {
2246
- return true;
2247
- }
2248
- if (new RegExp(`export\\s*\\{[^}]*\\b${componentName}\\b[^}]*\\}`).test(indexText)) {
2249
- return true;
2250
- }
2251
- if (/export\s+default\b/.test(indexText)) return true;
2252
- return pickComponentName(
2253
- { name: componentName, dirName: componentName },
2254
- parseTypeExportsLocal(typesIndexPath)
2255
- ) !== null;
2256
- }
2257
- function resolveLazyImport(pkgInfo, importSpecifier, typesFilePath, componentName) {
2258
- let lazyImportSpecifier = importSpecifier;
2259
- let lazyAccess = resolveLazyAccess(typesFilePath, componentName);
2260
- if (importSpecifier !== "@inventive-ui/components" && !subpathExposesLazyBinding(typesFilePath, componentName) && pkgInfo.rootTypesPath) {
2261
- lazyImportSpecifier = "@inventive-ui/components";
2262
- lazyAccess = `.${componentName}`;
2263
- }
2264
- return { lazyImportSpecifier, lazyAccess };
2265
- }
2266
- function describeExpected(item) {
2267
- return `${toPascalCase(item.dirName)} / ${toPascalCase(item.name)}`;
2268
- }
2269
- function resolveFromTypesFile(item, importSpecifier, typesFilePath, pkgInfo) {
2270
- const parsed = parseTypeExports(typesFilePath);
2271
- const indexParsed = parseTypeExportsLocal(typesFilePath);
2272
- const componentName = pickComponentName(item, parsed) ?? pickDefaultExportComponent(item, typesFilePath);
2273
- if (!componentName) {
2274
- return {
2275
- ok: false,
2276
- reason: `No matching component export in ${importSpecifier}. Expected ${describeExpected(item)}.`
2277
- };
1936
+ // src/utils/security/identifiers.ts
1937
+ var SLUG_RE = /^[a-z][a-z0-9-]*$/;
1938
+ var JS_IDENTIFIER_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
1939
+ var NPM_SCOPE_IMPORT_RE = /^@inventive-ui\/[a-z0-9][a-z0-9._-]*$/;
1940
+ var NPM_COMPONENT_SUBPATH_RE = /^@inventive-ui\/components\/[A-Za-z][A-Za-z0-9-]*$/;
1941
+ function assertComponentSlug(slug) {
1942
+ if (!SLUG_RE.test(slug)) {
1943
+ throw new CLIError(
1944
+ `Invalid component slug: "${slug}"`,
1945
+ "Use lowercase letters, numbers, and hyphens (e.g. button, input)."
1946
+ );
2278
1947
  }
2279
- const propsName = pickPropsName(componentName, indexParsed) ?? pickPropsName(componentName, parsed) ?? (() => {
2280
- const typesPath = path7.join(path7.dirname(typesFilePath), "types.d.ts");
2281
- if (!fs6.existsSync(typesPath)) return null;
2282
- return pickPropsName(componentName, parseTypeExports(typesPath));
2283
- })();
2284
- const lazyImport = resolveLazyImport(
2285
- pkgInfo,
2286
- importSpecifier,
2287
- typesFilePath,
2288
- componentName
2289
- );
2290
- return {
2291
- ok: true,
2292
- importSpecifier,
2293
- lazyImportSpecifier: lazyImport.lazyImportSpecifier,
2294
- componentName,
2295
- propsName: propsName ?? void 0,
2296
- lazyAccess: lazyImport.lazyAccess
2297
- };
2298
- }
2299
- function exportCandidatesForItem(item) {
2300
- const candidates = [
2301
- `./${item.name}`,
2302
- `./${item.name.toLowerCase()}`,
2303
- `./${item.dirName}`,
2304
- `./${item.dirName.toLowerCase()}`
2305
- ];
2306
- return [...new Set(candidates)];
2307
1948
  }
2308
- function componentFolderCandidates(item) {
2309
- return [
2310
- .../* @__PURE__ */ new Set([
2311
- item.dirName,
2312
- item.name,
2313
- toPascalCase(item.dirName),
2314
- toPascalCase(item.name)
2315
- ])
2316
- ];
2317
- }
2318
- function resolveWildcardTypesPath(pkgInfo, segment) {
2319
- const wildcardEntry = pkgInfo.exportsField["./*"];
2320
- if (!wildcardEntry) return null;
2321
- const typesRel = resolveTypesPathFromExportEntry(wildcardEntry);
2322
- if (!typesRel || !typesRel.includes("*")) return null;
2323
- const resolvedRel = typesRel.replace(/\*/g, segment);
2324
- const fullPath = path7.join(pkgInfo.packageRoot, resolvedRel);
2325
- return fs6.existsSync(fullPath) ? fullPath : null;
2326
- }
2327
- function resolveTypesPathForExportCandidate(pkgInfo, candidate) {
2328
- const entry = pkgInfo.exportsField[candidate];
2329
- if (entry) {
2330
- const typesRel = resolveTypesPathFromExportEntry(entry);
2331
- return typesRel ? path7.join(pkgInfo.packageRoot, typesRel) : null;
2332
- }
2333
- const segment = candidate.replace(/^\.\//, "");
2334
- return resolveWildcardTypesPath(pkgInfo, segment);
2335
- }
2336
- function resolveFromComponentFolders(item, pkgInfo) {
2337
- for (const folder of componentFolderCandidates(item)) {
2338
- const typesPath = resolveWildcardTypesPath(pkgInfo, folder) ?? (() => {
2339
- const directPath = path7.join(
2340
- pkgInfo.packageRoot,
2341
- "dist",
2342
- "components",
2343
- folder,
2344
- "index.d.ts"
2345
- );
2346
- return fs6.existsSync(directPath) ? directPath : null;
2347
- })();
2348
- if (!typesPath) continue;
2349
- const importSpecifier = `@inventive-ui/components/${folder}`;
2350
- try {
2351
- assertImportSpecifier(importSpecifier);
2352
- } catch {
2353
- continue;
2354
- }
2355
- const resolved = resolveFromTypesFile(item, importSpecifier, typesPath, pkgInfo);
2356
- if (resolved.ok) return resolved;
1949
+ function assertJsIdentifier(name, label) {
1950
+ if (!JS_IDENTIFIER_RE.test(name)) {
1951
+ throw new CLIError(`Invalid ${label}: "${name}"`);
2357
1952
  }
2358
- return null;
2359
1953
  }
2360
- function componentBuildExists(item, pkgInfo) {
2361
- return componentFolderCandidates(item).some(
2362
- (folder) => fs6.existsSync(path7.join(pkgInfo.packageRoot, "dist", "components", folder))
2363
- );
1954
+ function assertImportSpecifier(specifier) {
1955
+ if (NPM_SCOPE_IMPORT_RE.test(specifier)) return;
1956
+ if (NPM_COMPONENT_SUBPATH_RE.test(specifier)) return;
1957
+ if (/^@inventive-ui\/[a-z0-9][a-z0-9-]*$/.test(specifier)) return;
1958
+ throw new CLIError(`Unsafe import specifier: "${specifier}"`);
2364
1959
  }
2365
- function buildMissingComponentReason(item) {
2366
- return `Component "${item.name}" is listed in iui-manifest.json but is missing from the published @inventive-ui/components build (expected dist/components/${item.dirName}). Run a full components build, export ${describeExpected(item)} from dist/index.d.ts, and republish.`;
1960
+ function escapeTsStringLiteral(value) {
1961
+ return JSON.stringify(value);
2367
1962
  }
2368
- function resolveComponentExport(item, cwd = process.cwd()) {
2369
- const pkgInfo = readComponentsPackageInfo(cwd);
2370
- if (!pkgInfo) {
2371
- return {
2372
- ok: false,
2373
- reason: "@inventive-ui/components is not installed in node_modules."
2374
- };
2375
- }
2376
- const fromFolders = resolveFromComponentFolders(item, pkgInfo);
2377
- if (fromFolders?.ok) return fromFolders;
2378
- for (const candidate of exportCandidatesForItem(item)) {
2379
- const typesPath = resolveTypesPathForExportCandidate(pkgInfo, candidate);
2380
- if (!typesPath) continue;
2381
- const importSpecifier = `@inventive-ui/components/${candidate.replace(/^\.\//, "")}`;
2382
- try {
2383
- assertImportSpecifier(importSpecifier);
2384
- } catch {
2385
- continue;
2386
- }
2387
- const resolved = resolveFromTypesFile(item, importSpecifier, typesPath, pkgInfo);
2388
- if (resolved.ok) return resolved;
2389
- }
2390
- if (pkgInfo.rootTypesPath) {
2391
- const fromRoot = resolveFromTypesFile(item, "@inventive-ui/components", pkgInfo.rootTypesPath, pkgInfo);
2392
- if (fromRoot.ok) return fromRoot;
2393
- }
2394
- if (!componentBuildExists(item, pkgInfo)) {
2395
- return {
2396
- ok: false,
2397
- reason: buildMissingComponentReason(item)
2398
- };
1963
+ function sanitizePackageVersionHeader(value) {
1964
+ if (!value) return null;
1965
+ const trimmed = value.trim();
1966
+ if (!/^[0-9A-Za-z.+~^<>= -]+$/.test(trimmed) || trimmed.length > 64) {
1967
+ throw new CLIError("Server returned an invalid package version header.");
2399
1968
  }
2400
- return {
2401
- ok: false,
2402
- reason: `No matching component export for "${item.name}" in @inventive-ui/components. Expected a value export named ${describeExpected(item)}.`
2403
- };
1969
+ return trimmed;
2404
1970
  }
2405
1971
 
2406
1972
  // src/utils/config-patch/component-config.ts
@@ -2421,19 +1987,6 @@ function findComponentConfigObject(sourceFile) {
2421
1987
  visit(sourceFile);
2422
1988
  return found;
2423
1989
  }
2424
- function findComponentConfigMapType(sourceFile) {
2425
- let found;
2426
- const visit = (node) => {
2427
- if (found) return;
2428
- if (ts2.isTypeAliasDeclaration(node) && ts2.isIdentifier(node.name) && node.name.text === "ComponentConfigMap" && node.type && ts2.isTypeLiteralNode(node.type)) {
2429
- found = node.type;
2430
- return;
2431
- }
2432
- ts2.forEachChild(node, visit);
2433
- };
2434
- visit(sourceFile);
2435
- return found;
2436
- }
2437
1990
  function existingComponentKeys(obj) {
2438
1991
  const keys = /* @__PURE__ */ new Set();
2439
1992
  for (const prop of obj.properties) {
@@ -2443,33 +1996,14 @@ function existingComponentKeys(obj) {
2443
1996
  }
2444
1997
  return keys;
2445
1998
  }
2446
- function formatDefaultConfig(cfg) {
2447
- return JSON.stringify(cfg, null, 6).split("\n").map((line, i) => i === 0 ? line : ` ${line}`).join("\n");
2448
- }
2449
1999
  function buildComponentEntry(item) {
2450
2000
  assertJsIdentifier(item.dirName, "component dirName");
2451
- const cfg = item.meta?.defaultConfig ?? {};
2452
- const cfgStr = formatDefaultConfig(cfg);
2453
2001
  return ` ${item.dirName}: {
2454
- default: ${cfgStr},
2002
+ default: {},
2455
2003
  },
2456
2004
 
2457
2005
  `;
2458
2006
  }
2459
- function buildTypeEntry(item, cwd) {
2460
- const resolved = resolveComponentExport(item, cwd);
2461
- if (resolved.ok && resolved.propsName) {
2462
- return ` ${item.dirName}: { default: Partial<${resolved.propsName}> };`;
2463
- }
2464
- return ` ${item.dirName}: { default: Record<string, unknown> };`;
2465
- }
2466
- function buildTypeImport(item, cwd) {
2467
- const resolved = resolveComponentExport(item, cwd);
2468
- if (resolved.ok && resolved.propsName && resolved.importSpecifier) {
2469
- return `import type { ${resolved.propsName} } from "${resolved.importSpecifier}";`;
2470
- }
2471
- return null;
2472
- }
2473
2007
  function insertBeforeClosingBrace(source, objectEnd, insertion) {
2474
2008
  let pos = objectEnd - 1;
2475
2009
  while (pos >= 0 && /\s/.test(source[pos] ?? "")) pos--;
@@ -2481,7 +2015,7 @@ function insertBeforeClosingBrace(source, objectEnd, insertion) {
2481
2015
  }
2482
2016
  return source;
2483
2017
  }
2484
- function mergeComponentConfigContent(source, manifest, cwd) {
2018
+ function mergeComponentConfigContent(source, manifest) {
2485
2019
  if (!manifest || manifest.items.length === 0) {
2486
2020
  return { content: source, changed: false };
2487
2021
  }
@@ -2497,33 +2031,78 @@ function mergeComponentConfigContent(source, manifest, cwd) {
2497
2031
  const existing = existingComponentKeys(configObject);
2498
2032
  const missing = manifest.items.filter((item) => !existing.has(item.dirName));
2499
2033
  if (missing.length === 0) return { content: source, changed: false };
2500
- let next = source;
2501
2034
  const newEntries = missing.map((item) => buildComponentEntry(item)).join("");
2502
- next = insertBeforeClosingBrace(next, configObject.getEnd(), newEntries);
2503
- const typeLiteral = findComponentConfigMapType(
2504
- ts2.createSourceFile("component.config.ts", next, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TS)
2035
+ const next = insertBeforeClosingBrace(
2036
+ source,
2037
+ configObject.getEnd(),
2038
+ newEntries
2505
2039
  );
2506
- if (typeLiteral) {
2507
- const typeLines = `${missing.map((item) => buildTypeEntry(item, cwd)).join("\n")}
2508
- `;
2509
- next = insertBeforeClosingBrace(next, typeLiteral.getEnd(), typeLines);
2510
- }
2511
- const existingImportLines = new Set(next.match(/^import\s.+;$/gm) ?? []);
2512
- const newImports = missing.map((item) => buildTypeImport(item, cwd)).filter((line) => line !== null && !existingImportLines.has(line));
2513
- if (newImports.length > 0) {
2514
- const importMatches = [...next.matchAll(/^import\s.+;$/gm)];
2515
- const lastImport = importMatches.at(-1);
2516
- if (lastImport?.index !== void 0) {
2517
- const insertAt = lastImport.index + lastImport[0].length;
2518
- next = `${next.slice(0, insertAt)}
2519
- ${[...new Set(newImports)].join("\n")}${next.slice(insertAt)}`;
2520
- } else {
2521
- next = `${[...new Set(newImports)].join("\n")}
2040
+ return { content: next, changed: true };
2041
+ }
2522
2042
 
2523
- ${next}`;
2043
+ // src/utils/config-patch/tsconfig-iui.ts
2044
+ import path7 from "path";
2045
+ import fs6 from "fs-extra";
2046
+ var IUI_TS_ROOT_FILES = ["iui.config.ts", "component.config.ts"];
2047
+ function isSolutionStyleTsconfig(config) {
2048
+ const refs = config.references;
2049
+ return Array.isArray(refs) && refs.length > 0;
2050
+ }
2051
+ function patchJsonInclude(filePath, extra) {
2052
+ if (!fs6.existsSync(filePath)) return false;
2053
+ const raw = fs6.readJsonSync(filePath);
2054
+ const include = Array.isArray(raw.include) ? [...raw.include.map(String)] : [];
2055
+ let changed = false;
2056
+ for (const item of extra) {
2057
+ if (!include.includes(item)) {
2058
+ include.push(item);
2059
+ changed = true;
2524
2060
  }
2525
2061
  }
2526
- return { content: next, changed: true };
2062
+ if (!changed) return false;
2063
+ atomicWriteJson(filePath, { ...raw, include });
2064
+ return true;
2065
+ }
2066
+ function resolveAppTsconfigPath(cwd, root) {
2067
+ const refs = root.references;
2068
+ if (!refs) return null;
2069
+ for (const ref of refs) {
2070
+ const p = ref.path?.replace(/^\.\//, "") ?? "";
2071
+ const base = p.replace(/\.json$/i, "");
2072
+ if (/app/i.test(base)) {
2073
+ return path7.join(cwd, p.endsWith(".json") ? p : `${p}.json`);
2074
+ }
2075
+ }
2076
+ for (const ref of refs) {
2077
+ const p = ref.path?.replace(/^\.\//, "") ?? "";
2078
+ if (!/node/i.test(p)) {
2079
+ return path7.join(cwd, p.endsWith(".json") ? p : `${p}.json`);
2080
+ }
2081
+ }
2082
+ return null;
2083
+ }
2084
+ function repairSolutionStyleRootTsconfig(cwd) {
2085
+ const rootPath = path7.join(cwd, "tsconfig.json");
2086
+ if (!fs6.existsSync(rootPath)) return false;
2087
+ const existing = fs6.readJsonSync(rootPath);
2088
+ if (!isSolutionStyleTsconfig(existing)) return false;
2089
+ const polluted = existing.compilerOptions !== void 0 || Array.isArray(existing.include) && existing.include.length > 0 || Array.isArray(existing.exclude) && existing.exclude.length > 0;
2090
+ if (!polluted) return false;
2091
+ atomicWriteJson(rootPath, {
2092
+ files: Array.isArray(existing.files) ? existing.files : [],
2093
+ references: existing.references
2094
+ });
2095
+ return true;
2096
+ }
2097
+ function patchSolutionStyleTsconfigForIui(cwd) {
2098
+ const rootPath = path7.join(cwd, "tsconfig.json");
2099
+ if (!fs6.existsSync(rootPath)) return false;
2100
+ const existing = fs6.readJsonSync(rootPath);
2101
+ if (!isSolutionStyleTsconfig(existing)) return false;
2102
+ const repairedRoot = repairSolutionStyleRootTsconfig(cwd);
2103
+ const appPath = resolveAppTsconfigPath(cwd, existing);
2104
+ const patchedApp = appPath ? patchJsonInclude(appPath, IUI_TS_ROOT_FILES) : false;
2105
+ return repairedRoot || patchedApp;
2527
2106
  }
2528
2107
 
2529
2108
  // src/validation/configTierChecks.ts
@@ -2922,15 +2501,6 @@ function loadAssetsConfigTemplate() {
2922
2501
  return {};
2923
2502
  }
2924
2503
  }
2925
- function loadComponentConfigPresetsTemplate() {
2926
- const templatePath = path10.join(getCliTemplatesDir(), "component.config.presets.json");
2927
- if (!fs8.existsSync(templatePath)) return {};
2928
- try {
2929
- return fs8.readJsonSync(templatePath);
2930
- } catch {
2931
- return {};
2932
- }
2933
- }
2934
2504
  function mergeAssetSlotWithTemplate(slot, templateSlot) {
2935
2505
  if (!templateSlot) return slot ?? {};
2936
2506
  const out = { ...templateSlot, ...slot ?? {} };
@@ -3277,7 +2847,24 @@ function writeTsConfigNode(cwd = process.cwd()) {
3277
2847
  };
3278
2848
  atomicWriteJson(nodeTsPath, content);
3279
2849
  }
3280
- function writeTsConfig(framework, cwd = process.cwd()) {
2850
+ function ensureTsConfigForIui(framework, cwd = process.cwd()) {
2851
+ const tsconfigPath = path10.join(cwd, "tsconfig.json");
2852
+ let existing = {};
2853
+ if (fs8.existsSync(tsconfigPath)) {
2854
+ try {
2855
+ existing = fs8.readJsonSync(tsconfigPath);
2856
+ } catch {
2857
+ existing = {};
2858
+ }
2859
+ }
2860
+ if (framework === "vite" && isSolutionStyleTsconfig(existing)) {
2861
+ patchSolutionStyleTsconfigForIui(cwd);
2862
+ writeTsConfigNode(cwd);
2863
+ return;
2864
+ }
2865
+ writeFlatProjectTsConfig(framework, cwd);
2866
+ }
2867
+ function writeFlatProjectTsConfig(framework, cwd = process.cwd()) {
3281
2868
  const tsconfigPath = path10.join(cwd, "tsconfig.json");
3282
2869
  let existing = {};
3283
2870
  if (fs8.existsSync(tsconfigPath)) {
@@ -3345,56 +2932,22 @@ function writeTsConfig(framework, cwd = process.cwd()) {
3345
2932
  };
3346
2933
  atomicWriteJson(tsconfigPath, output);
3347
2934
  }
3348
- function writeComponentConfig(manifest, cwd = process.cwd()) {
2935
+ function writeComponentConfig(_manifest, cwd = process.cwd()) {
3349
2936
  const configPath = path10.join(cwd, COMPONENT_CONFIG_FILE);
3350
- let entries = "";
3351
- const typedEntries = [];
3352
- const typeImports = [];
3353
- const presetsTemplate = loadComponentConfigPresetsTemplate();
3354
- if (manifest) {
3355
- for (const item of manifest.items) {
3356
- assertJsIdentifier(item.dirName, "component dirName");
3357
- const cfg = item.meta?.defaultConfig ?? {};
3358
- const presetBlock = presetsTemplate[item.dirName];
3359
- const cfgStr = JSON.stringify(cfg, null, 6).split("\n").map((line, i) => i === 0 ? line : ` ${line}`).join("\n");
3360
- let extraBlocks = "";
3361
- if (presetBlock?.presets) {
3362
- const presetsStr = JSON.stringify(presetBlock.presets, null, 6).split("\n").map((line, i) => i === 0 ? line : ` ${line}`).join("\n");
3363
- extraBlocks += `
3364
- presets: ${presetsStr},`;
3365
- }
3366
- entries += ` ${item.dirName}: {
3367
- default: ${cfgStr},${extraBlocks}
3368
- },
3369
-
3370
- `;
3371
- const resolved = resolveComponentExport(item, cwd);
3372
- if (resolved.ok && resolved.propsName && resolved.importSpecifier) {
3373
- typeImports.push(`import type { ${resolved.propsName} } from "${resolved.importSpecifier}";`);
3374
- typedEntries.push(` ${item.dirName}: { default: Partial<${resolved.propsName}> };`);
3375
- } else {
3376
- typedEntries.push(` ${item.dirName}: { default: Record<string, unknown> };`);
3377
- }
3378
- }
3379
- }
3380
- const imports = [...new Set(typeImports)].join("\n");
3381
- const componentConfigType = typedEntries.length > 0 ? `type ComponentConfigMap = {
3382
- ${typedEntries.join("\n")}
3383
- };` : `type ComponentConfigMap = Record<string, { default: Record<string, unknown> }>;`;
3384
2937
  const content = `// \u2500\u2500\u2500 Component Configuration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
3385
2938
  //
3386
- // Default component presets for your Inventive UI project.
3387
- // Customize variants, appearances, and slot assignments below.
3388
- // Entries are rebuilt from the published component registry.
2939
+ // Optional per-component defaults (variant, appearance, presets, cTags).
2940
+ // Only add entries you want to override \u2014 omit components you do not customize.
2941
+ // \`iui update\` may append new registry keys; edit or remove them as needed.
3389
2942
  //
3390
2943
  // Docs: https://inventiveui.com/docs/configuration
3391
2944
 
3392
- ${imports}
3393
-
3394
- ${componentConfigType}
2945
+ import type { ComponentConfig } from "@inventive-ui/components/config";
3395
2946
 
3396
- export const componentConfig: ComponentConfigMap = {
3397
- ${entries}};
2947
+ export const componentConfig = {
2948
+ // Example:
2949
+ // Button: { default: { variant: "solid", appearance: "soft" } },
2950
+ } satisfies ComponentConfig;
3398
2951
  `;
3399
2952
  atomicWriteFile(configPath, content);
3400
2953
  }
@@ -3406,7 +2959,7 @@ function ensureComponentConfig(manifest, cwd = process.cwd(), options = {}) {
3406
2959
  return existed && options.force ? "replaced" : "scaffolded";
3407
2960
  }
3408
2961
  const before = fs8.readFileSync(configPath, "utf-8");
3409
- const result = mergeComponentConfigContent(before, manifest, cwd);
2962
+ const result = mergeComponentConfigContent(before, manifest);
3410
2963
  if (!result.changed) return "noop";
3411
2964
  atomicWriteFile(configPath, result.content);
3412
2965
  return "merged";
@@ -6958,7 +6511,7 @@ async function initCommand(opts) {
6958
6511
  step("Generating config files\u2026");
6959
6512
  writeAssetsConfig(initRoot);
6960
6513
  ensureProjectConfig(initRoot);
6961
- writeTsConfig(framework.framework, initRoot);
6514
+ ensureTsConfigForIui(framework.framework, initRoot);
6962
6515
  if (framework.framework === "vite") {
6963
6516
  ensureInventiveUiViteConfig(initRoot);
6964
6517
  ok("Config files ready (iui.config.ts, tsconfig.json, tsconfig.node.json, vite.config.ts)");
@@ -6968,7 +6521,7 @@ async function initCommand(opts) {
6968
6521
  }
6969
6522
  ok("Config files ready (iui.config.ts, tsconfig.json)");
6970
6523
  }
6971
- step("Generating component.config.ts\u2026");
6524
+ step("Scaffolding component.config.ts\u2026");
6972
6525
  const fetchedRegistry = await fetchComponentRegistry(auth.token);
6973
6526
  if (!fetchedRegistry.registry && fetchedRegistry.apiFailure) {
6974
6527
  warn(`Component registry API: ${fetchedRegistry.apiFailure}`);
@@ -7853,40 +7406,21 @@ function checkCompileFirstReadiness(cwd = process.cwd(), _options = {}) {
7853
7406
  const configPath = path24.join(cwd, PROJECT_CONFIG_FILE);
7854
7407
  if (fs19.existsSync(configPath)) {
7855
7408
  const configContent = fs19.readFileSync(configPath, "utf-8");
7856
- if (!/\bbuild\s*:\s*\{/.test(configContent)) {
7857
- warnings.push("iui.config.ts is missing a compile-first `build` block");
7858
- hints.push(
7859
- "Framework applies default scanDirs/scanPackages \u2014 merge other build flags from docs/01-compile-first-guide.md or run a fresh iui init"
7409
+ if (/packageSafelist\s*:\s*false/.test(configContent)) {
7410
+ warnings.push(
7411
+ "Deprecated iui.config build.packageSafelist \u2014 remove it; Framework always merges IUI package compile contracts"
7412
+ );
7413
+ }
7414
+ if (/includeShadeMatrix\s*:/.test(configContent)) {
7415
+ warnings.push(
7416
+ "Deprecated compiler flags in iui.config build.* \u2014 remove them; compile policy is Framework-internal"
7417
+ );
7418
+ hints.push("Use theme + optional scan.dirs only. See Framework docs/01-compile-first-guide.md");
7419
+ }
7420
+ if (/scanPackages\s*:/.test(configContent) || /scan\.packages\s*:/.test(configContent)) {
7421
+ warnings.push(
7422
+ "Deprecated scanPackages in iui.config \u2014 IUI packages are discovered from package.json dependencies"
7860
7423
  );
7861
- } else {
7862
- if (/packageSafelist\s*:\s*false/.test(configContent)) {
7863
- warnings.push(
7864
- "iui.config.ts build.packageSafelist is false \u2014 package compile.safelist contracts from scanPackages will not merge"
7865
- );
7866
- hints.push(
7867
- "Remove packageSafelist: false to use Framework default (true) so @inventive-ui/components compile.safelist is included"
7868
- );
7869
- }
7870
- if (!/includeShadeMatrix\s*:\s*false/.test(configContent)) {
7871
- warnings.push("iui.config.ts build.includeShadeMatrix should be false unless you need the full compose() matrix");
7872
- }
7873
- if (!/includeThemePresets\s*:\s*true/.test(configContent)) {
7874
- warnings.push("iui.config.ts build.includeThemePresets should be true");
7875
- }
7876
- if (!/includeThemeGrayScale\s*:\s*true/.test(configContent)) {
7877
- warnings.push(
7878
- "iui.config.ts build.includeThemeGrayScale should be true (pre-expand theme gray gray-2\u202698 utilities)"
7879
- );
7880
- }
7881
- if (!/resolvePalettePatterns\s*:\s*true/.test(configContent)) {
7882
- warnings.push("iui.config.ts build.resolvePalettePatterns should be true");
7883
- }
7884
- if (!/includeArbitraryScan\s*:\s*true/.test(configContent)) {
7885
- warnings.push("iui.config.ts build.includeArbitraryScan should be true");
7886
- }
7887
- if (!/useAst\s*:\s*true/.test(configContent)) {
7888
- warnings.push("iui.config.ts build.useAst should be true");
7889
- }
7890
7424
  }
7891
7425
  }
7892
7426
  if (projectHasViteTooling(cwd)) {
@@ -8175,7 +7709,7 @@ function checkBootstrapSync(cwd = process.cwd(), options = {}) {
8175
7709
  }
8176
7710
 
8177
7711
  // src/commands/doctor.ts
8178
- function runConfigTierDiagnostics(targetCwd, opts, counters, options = {}) {
7712
+ async function runConfigTierDiagnostics(targetCwd, opts, counters, options = {}) {
8179
7713
  const pass = (label) => {
8180
7714
  checkPass(label);
8181
7715
  counters.passed++;
@@ -8193,10 +7727,13 @@ function runConfigTierDiagnostics(targetCwd, opts, counters, options = {}) {
8193
7727
  if (opts?.fix === true && includePackageJson) {
8194
7728
  ensureProjectConfig(targetCwd);
8195
7729
  ensureGitignoreHasIuiBuildCache(targetCwd);
8196
- if (projectHasViteTooling(targetCwd)) {
7730
+ const vite = projectHasViteTooling(targetCwd);
7731
+ ensureTsConfigForIui(vite ? "vite" : "react", targetCwd);
7732
+ if (vite) {
8197
7733
  ensureInventiveUiViteConfig(targetCwd);
8198
7734
  }
8199
7735
  ensureComponentConfig(readComponentPackageManifest(targetCwd), targetCwd);
7736
+ await ensureSlotRegistry({ cwd: targetCwd, quiet: true, mode: "repair" });
8200
7737
  }
8201
7738
  if (includeSlotCheck && isInsideProject(targetCwd) && getInstalledPackageVersion(COMPONENTS_PACKAGE, targetCwd)) {
8202
7739
  const slotValidity = checkGeneratedSlotValidity(targetCwd);
@@ -8298,7 +7835,7 @@ async function runPackageDiagnostics(targetCwd, opts, counters) {
8298
7835
  counters.failed++;
8299
7836
  };
8300
7837
  if (opts?.configOnly) {
8301
- runConfigTierDiagnostics(targetCwd, opts, counters, {
7838
+ await runConfigTierDiagnostics(targetCwd, opts, counters, {
8302
7839
  includePackageJson: true,
8303
7840
  includeSlotCheck: true
8304
7841
  });
@@ -8308,10 +7845,13 @@ async function runPackageDiagnostics(targetCwd, opts, counters) {
8308
7845
  else fail2("package.json missing");
8309
7846
  if (opts?.fix === true) {
8310
7847
  ensureProjectConfig(targetCwd);
8311
- if (projectHasViteTooling(targetCwd)) {
7848
+ const vite2 = projectHasViteTooling(targetCwd);
7849
+ ensureTsConfigForIui(vite2 ? "vite" : "react", targetCwd);
7850
+ if (vite2) {
8312
7851
  ensureInventiveUiViteConfig(targetCwd);
8313
7852
  }
8314
7853
  ensureComponentConfig(readComponentPackageManifest(targetCwd), targetCwd);
7854
+ await ensureSlotRegistry({ cwd: targetCwd, quiet: true, mode: "repair" });
8315
7855
  }
8316
7856
  if (isInsideProject(targetCwd)) {
8317
7857
  pass("Inventive UI project initialized");
@@ -8430,7 +7970,7 @@ async function runPackageDiagnostics(targetCwd, opts, counters) {
8430
7970
  hint("Fix: run iui doctor --fix to regenerate bootstrap artifacts");
8431
7971
  }
8432
7972
  }
8433
- runConfigTierDiagnostics(targetCwd, opts, counters, {
7973
+ await runConfigTierDiagnostics(targetCwd, opts, counters, {
8434
7974
  includePackageJson: false,
8435
7975
  includeSlotCheck: false
8436
7976
  });
@@ -8736,7 +8276,7 @@ async function updateCommand(opts = {}) {
8736
8276
  const auth = await ensureAuthSession();
8737
8277
  await ensureLicenseSession();
8738
8278
  const inProject = isInsideProject();
8739
- const currentCliVersion = true ? "0.0.8" : "unknown";
8279
+ const currentCliVersion = true ? "0.0.10" : "unknown";
8740
8280
  const latestCliVersion = await fetchLatestCliVersion(auth.token);
8741
8281
  const cliUpdateAvailable = latestCliVersion !== null && isVersionGreater(latestCliVersion, currentCliVersion);
8742
8282
  if (latestCliVersion && cliUpdateAvailable) {
@@ -9018,7 +8558,7 @@ var AUTH_EXEMPT_COMMANDS = /* @__PURE__ */ new Set([
9018
8558
  "doctor",
9019
8559
  "list"
9020
8560
  ]);
9021
- program.name("iui").description("The official CLI for the Inventive UI Design System").version(true ? "0.0.8" : "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");
8561
+ program.name("iui").description("The official CLI for the Inventive UI Design System").version(true ? "0.0.10" : "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");
9022
8562
  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));
9023
8563
  program.command("logout").description("Remove stored credentials").action(logoutCommand);
9024
8564
  program.command("whoami").description("Show authenticated identity and license details").action(whoamiCommand);