@axis-ds/cli 1.6.0 → 1.6.1

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
@@ -1745,7 +1745,7 @@ import ora5 from "ora";
1745
1745
 
1746
1746
  // src/template/template-apply.ts
1747
1747
  import fs8 from "fs-extra";
1748
- import path8 from "path";
1748
+ import path9 from "path";
1749
1749
  import chalk5 from "chalk";
1750
1750
  import ora3 from "ora";
1751
1751
  import prompts from "prompts";
@@ -1843,8 +1843,18 @@ async function readAxisConfig(baseDir) {
1843
1843
  }
1844
1844
 
1845
1845
  // ../axis-registry-core/src/template/tailwind-core.ts
1846
- import { existsSync, lstatSync, readdirSync, readFileSync } from "fs";
1847
- import { join, resolve } from "path";
1846
+ import { existsSync as existsSync2, lstatSync, readdirSync, readFileSync as readFileSync2 } from "fs";
1847
+ import { extname, join, resolve } from "path";
1848
+
1849
+ // ../axis-registry-core/src/project.ts
1850
+ import { existsSync, readFileSync, statSync } from "fs";
1851
+ import path8 from "path";
1852
+ function detectInstallCommand(baseDir) {
1853
+ if (existsSync(path8.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
1854
+ if (existsSync(path8.join(baseDir, "yarn.lock"))) return "yarn install";
1855
+ if (existsSync(path8.join(baseDir, "package-lock.json"))) return "npm install";
1856
+ return "pnpm install";
1857
+ }
1848
1858
  function hasDependency(pkg, name) {
1849
1859
  for (const field of ["dependencies", "devDependencies"]) {
1850
1860
  const deps = pkg[field];
@@ -1857,6 +1867,134 @@ function hasDependency(pkg, name) {
1857
1867
  function isPlainObject(value) {
1858
1868
  return typeof value === "object" && value !== null && !Array.isArray(value);
1859
1869
  }
1870
+ function addCommandFor(installCommand, deps) {
1871
+ const specs = Object.entries(deps).map(([name, range]) => `"${name}@${range}"`).join(" ");
1872
+ if (installCommand.startsWith("yarn")) return `yarn add ${specs}`;
1873
+ if (installCommand.startsWith("npm")) return `npm install ${specs}`;
1874
+ return `pnpm add ${specs}`;
1875
+ }
1876
+ var GLOBAL_CSS_CANDIDATES = [
1877
+ "app/globals.css",
1878
+ "src/app/globals.css",
1879
+ "styles/globals.css",
1880
+ "src/styles/globals.css",
1881
+ "globals.css"
1882
+ ];
1883
+ var TAILWIND_CONFIG_CANDIDATES = [
1884
+ "tailwind.config.ts",
1885
+ "tailwind.config.js",
1886
+ "tailwind.config.mjs",
1887
+ "tailwind.config.cjs"
1888
+ ];
1889
+ function isFile(file) {
1890
+ try {
1891
+ return statSync(file).isFile();
1892
+ } catch {
1893
+ return false;
1894
+ }
1895
+ }
1896
+ function isDirectory(dir) {
1897
+ try {
1898
+ return statSync(dir).isDirectory();
1899
+ } catch {
1900
+ return false;
1901
+ }
1902
+ }
1903
+ function findFirstFile(baseDir, candidates) {
1904
+ return candidates.find((c) => isFile(path8.join(baseDir, c)));
1905
+ }
1906
+ function detectProjectPaths(baseDirInput) {
1907
+ const baseDir = path8.resolve(baseDirInput);
1908
+ const hasSrc = isDirectory(path8.join(baseDir, "src"));
1909
+ const css = findFirstFile(baseDir, GLOBAL_CSS_CANDIDATES);
1910
+ const tw = findFirstFile(baseDir, TAILWIND_CONFIG_CANDIDATES);
1911
+ return {
1912
+ componentsDir: hasSrc ? "./src/components/ui" : "./components/ui",
1913
+ globalCss: css !== void 0 ? `./${css}` : hasSrc ? "./src/app/globals.css" : "./app/globals.css",
1914
+ globalCssSource: css !== void 0 ? "found" : "default",
1915
+ tailwindConfig: tw !== void 0 ? `./${tw}` : "./tailwind.config.ts",
1916
+ tailwindConfigSource: tw !== void 0 ? "found" : "default"
1917
+ };
1918
+ }
1919
+ function projectFileExists(baseDir, relPath) {
1920
+ return isFile(path8.resolve(baseDir, relPath));
1921
+ }
1922
+ var ROOT_LAYOUT_FILES = [
1923
+ "app/layout.tsx",
1924
+ "app/layout.jsx",
1925
+ "app/layout.js",
1926
+ "src/app/layout.tsx",
1927
+ "src/app/layout.jsx",
1928
+ "src/app/layout.js",
1929
+ "pages/_app.tsx",
1930
+ "pages/_app.jsx",
1931
+ "pages/_document.tsx",
1932
+ "pages/_document.jsx",
1933
+ "src/pages/_app.tsx",
1934
+ "src/pages/_app.jsx",
1935
+ "src/pages/_document.tsx",
1936
+ "src/pages/_document.jsx"
1937
+ ];
1938
+ function exactVersionOf(version) {
1939
+ if (typeof version !== "string") return void 0;
1940
+ const v = version.trim();
1941
+ if (!/^v?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(v) || /^v?0\.0\.0-/.test(v)) return void 0;
1942
+ return v;
1943
+ }
1944
+ function findInstalledPackage(baseDirInput, name) {
1945
+ let dir = path8.resolve(baseDirInput);
1946
+ for (; ; ) {
1947
+ const pkgDir = path8.join(dir, "node_modules", ...name.split("/"));
1948
+ const file = path8.join(pkgDir, "package.json");
1949
+ if (isFile(file)) {
1950
+ let version;
1951
+ try {
1952
+ const parsed = JSON.parse(readFileSync(file, "utf8"));
1953
+ version = isPlainObject(parsed) ? exactVersionOf(parsed.version) : void 0;
1954
+ } catch {
1955
+ version = void 0;
1956
+ }
1957
+ return { dir: pkgDir, version };
1958
+ }
1959
+ const parent = path8.dirname(dir);
1960
+ if (parent === dir) return void 0;
1961
+ dir = parent;
1962
+ }
1963
+ }
1964
+ function isPnpProject(baseDirInput) {
1965
+ let dir = path8.resolve(baseDirInput);
1966
+ for (; ; ) {
1967
+ if (isFile(path8.join(dir, ".pnp.cjs")) || isFile(path8.join(dir, ".pnp.js"))) return true;
1968
+ const parent = path8.dirname(dir);
1969
+ if (parent === dir) return false;
1970
+ dir = parent;
1971
+ }
1972
+ }
1973
+ function compareExactVersions(a, b) {
1974
+ const parse = (v) => {
1975
+ const m = /^v?(\d+)\.(\d+)\.(\d+)(-[0-9A-Za-z.-]+)?/.exec(v.trim());
1976
+ return m ? { core: [Number(m[1]), Number(m[2]), Number(m[3])], pre: m[4] !== void 0 } : void 0;
1977
+ };
1978
+ const x = parse(a);
1979
+ const y = parse(b);
1980
+ if (!x || !y) return void 0;
1981
+ for (let i = 0; i < 3; i++) if (x.core[i] !== y.core[i]) return x.core[i] - y.core[i];
1982
+ return Number(y.pre) - Number(x.pre);
1983
+ }
1984
+
1985
+ // ../axis-registry-core/src/template/tailwind-core.ts
1986
+ function hasDependency2(pkg, name) {
1987
+ for (const field of ["dependencies", "devDependencies"]) {
1988
+ const deps = pkg[field];
1989
+ if (typeof deps === "object" && deps !== null && name in deps) {
1990
+ return String(deps[name]);
1991
+ }
1992
+ }
1993
+ return void 0;
1994
+ }
1995
+ function isPlainObject2(value) {
1996
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1997
+ }
1860
1998
  var VERSION = String.raw`v?(\d+)(?:\.(\d+|[xX*]))?(?:\.(\d+|[xX*]))?(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?`;
1861
1999
  function versionParts(token) {
1862
2000
  const m = new RegExp(`^${VERSION}$`).exec(token);
@@ -1930,12 +2068,12 @@ function majorFromVersion(version) {
1930
2068
  function detectTailwind(baseDirInput, pkg) {
1931
2069
  const baseDir = resolve(baseDirInput);
1932
2070
  const installedFile = join(baseDir, "node_modules", "tailwindcss", "package.json");
1933
- const declared = pkg ? hasDependency(pkg, "tailwindcss") : void 0;
2071
+ const declared = pkg ? hasDependency2(pkg, "tailwindcss") : void 0;
1934
2072
  const bounds = declared !== void 0 ? tailwindMajorBounds(declared) : void 0;
1935
2073
  const declaredMajor = bounds?.lower;
1936
2074
  try {
1937
- const installed = JSON.parse(readFileSync(installedFile, "utf8"));
1938
- const version = isPlainObject(installed) ? installed.version : void 0;
2075
+ const installed = JSON.parse(readFileSync2(installedFile, "utf8"));
2076
+ const version = isPlainObject2(installed) ? installed.version : void 0;
1939
2077
  const major = majorFromVersion(version);
1940
2078
  if (major !== void 0) {
1941
2079
  const found = { major, source: "installed", value: String(version) };
@@ -1982,18 +2120,57 @@ var TOKENS_CSS_IMPORT = /@import\s+(?:url\(\s*)?["'](@axis-ds\/tokens\/css(?:\/s
1982
2120
  function findTokensCssImport(css) {
1983
2121
  return TOKENS_CSS_IMPORT.exec(stripCssComments(css))?.[1];
1984
2122
  }
2123
+ var TOKENS_CSS_JS_IMPORT = /(?:\bimport\s+|\bfrom\s+|\brequire\s*\(\s*)(["'])(@axis-ds\/tokens\/css(?:\/shadcn|\/tailwind4)?)\1/;
2124
+ var AXIS_VARIABLE_DEFINITION = /(?<![\w-])--axis-[\w-]+\s*:/;
2125
+ function findLayoutTokensCssImport(baseDirInput) {
2126
+ const baseDir = resolve(baseDirInput);
2127
+ for (const candidate of ROOT_LAYOUT_FILES) {
2128
+ const file = join(baseDir, candidate);
2129
+ if (!existsSync2(file)) continue;
2130
+ let text;
2131
+ try {
2132
+ text = readFileSync2(file, "utf8");
2133
+ } catch {
2134
+ continue;
2135
+ }
2136
+ const m = TOKENS_CSS_JS_IMPORT.exec(stripJsComments(text));
2137
+ if (m) return { file: candidate, spec: m[2] };
2138
+ }
2139
+ return void 0;
2140
+ }
1985
2141
  function checkGlobalsCss(baseDirInput) {
1986
2142
  const baseDir = resolve(baseDirInput);
1987
2143
  for (const candidate of TAILWIND_CSS_CANDIDATES) {
1988
2144
  const file = join(baseDir, candidate);
1989
- if (!existsSync(file)) continue;
1990
- const content = readFileSync(file, "utf8");
1991
- if (content.includes("--background") && content.includes("--primary")) {
1992
- return { name: "globals.css", severity: "pass", message: `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC815\uC758\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4` };
1993
- }
2145
+ if (!existsSync2(file)) continue;
2146
+ const content = readFileSync2(file, "utf8");
2147
+ const css = stripCssComments(content);
1994
2148
  const imported = findTokensCssImport(content);
1995
- if (imported !== void 0) {
1996
- return { name: "globals.css", severity: "pass", message: `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC788\uC2B5\uB2C8\uB2E4 (${imported} import)` };
2149
+ let pass;
2150
+ if (imported !== void 0) pass = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC788\uC2B5\uB2C8\uB2E4 (${imported} import)`;
2151
+ else if (AXIS_VARIABLE_DEFINITION.test(css)) pass = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218(--axis-*)\uAC00 \uC815\uC758\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4`;
2152
+ else {
2153
+ const layout = findLayoutTokensCssImport(baseDir);
2154
+ if (layout) pass = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC788\uC2B5\uB2C8\uB2E4 (${layout.file}\uC758 ${layout.spec} import)`;
2155
+ }
2156
+ if (pass !== void 0) {
2157
+ const tailwind = detectTailwind(baseDir, readPackageJson(baseDir));
2158
+ const tailwind4 = tailwind.major !== void 0 && tailwind.major >= 4;
2159
+ if (!tailwind4 && findCreateNextAppDefaults(content).some((d) => d.includes("font-family: Arial"))) {
2160
+ return {
2161
+ name: "globals.css",
2162
+ severity: "warn",
2163
+ message: `${pass}. \uB2E4\uB9CC create-next-app \uAE30\uBCF8 body font-family: Arial \uC774 \uB0A8\uC544 \uC788\uC2B5\uB2C8\uB2E4 \u2192 \uC9C0\uC6B0\uC138\uC694(AXIS \uAE00\uAF34 \uB300\uC2E0 Arial \uC774 \uC801\uC6A9\uB428)`
2164
+ };
2165
+ }
2166
+ return { name: "globals.css", severity: "pass", message: pass };
2167
+ }
2168
+ if (css.includes("--background") && css.includes("--primary")) {
2169
+ return {
2170
+ name: "globals.css",
2171
+ severity: "warn",
2172
+ message: `${candidate}\uC5D0 \uC790\uCCB4 CSS \uBCC0\uC218(--background \xB7 --primary)\uB9CC \uC788\uACE0 AXIS \uD1A0\uD070\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 @axis-ds/tokens CSS \uB97C import \uD558\uC138\uC694`
2173
+ };
1997
2174
  }
1998
2175
  return { name: "globals.css", severity: "warn", message: `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4` };
1999
2176
  }
@@ -2056,8 +2233,8 @@ function exactVersion(version) {
2056
2233
  }
2057
2234
  function installedVersion(baseDir, name) {
2058
2235
  try {
2059
- const parsed = JSON.parse(readFileSync(join(baseDir, "node_modules", ...name.split("/"), "package.json"), "utf8"));
2060
- return isPlainObject(parsed) ? exactVersion(parsed.version) : void 0;
2236
+ const parsed = JSON.parse(readFileSync2(join(baseDir, "node_modules", ...name.split("/"), "package.json"), "utf8"));
2237
+ return isPlainObject2(parsed) ? exactVersion(parsed.version) : void 0;
2061
2238
  } catch {
2062
2239
  return void 0;
2063
2240
  }
@@ -2068,7 +2245,7 @@ function axisPackagesBelowTailwind4(pkg, baseDirInput) {
2068
2245
  const out = [];
2069
2246
  const min = lowerOf(TAILWIND4_MIN_AXIS_VERSION);
2070
2247
  for (const name of TAILWIND4_AXIS_PACKAGES) {
2071
- const range = hasDependency(pkg, name);
2248
+ const range = hasDependency2(pkg, name);
2072
2249
  if (range === void 0 || range.trim().startsWith("workspace:")) continue;
2073
2250
  const installed = baseDir !== void 0 ? installedVersion(baseDir, name) : void 0;
2074
2251
  const installedLower = installed !== void 0 ? lowerOf(installed) : void 0;
@@ -2125,8 +2302,10 @@ var CREATE_NEXT_APP_DEFAULTS = [
2125
2302
  },
2126
2303
  {
2127
2304
  prefix: "body",
2128
- pattern: /(?<![\w-])(background|background-color|color)\s*:\s*var\(\s*(--(?:background|foreground))\s*\)/g,
2129
- item: (m) => `${m[1]}: var(${m[2]})`
2305
+ // WI-0070: create-next-app 의 body `font-family: Arial, Helvetica, sans-serif` 도 같은 특징으로 봅니다. 레이어 밖 규칙이라
2306
+ // AXIS 글꼴(Pretendard, html 에 적용)을 이기고 Button 등이 `font-family: inherit` 로 Arial 을 물려받습니다.
2307
+ pattern: /(?<![\w-])(?:(background|background-color|color)\s*:\s*var\(\s*(--(?:background|foreground))\s*\)|font-family\s*:\s*Arial\b)/g,
2308
+ item: (m) => m[1] !== void 0 ? `${m[1]}: var(${m[2]})` : "font-family: Arial"
2130
2309
  }
2131
2310
  ];
2132
2311
  function findCreateNextAppDefaults(css) {
@@ -2182,10 +2361,55 @@ function hasTokensPresetReference(source) {
2182
2361
  return PRESET_REFERENCE.test(stripJsComments(source));
2183
2362
  }
2184
2363
  var PRESET_PASS_SUFFIX = `\uC5D0 AXIS \uD1A0\uD070\uC774 \uC124\uC815\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4 (${TOKENS_TAILWIND3_PRESET} preset)`;
2364
+ var TOKENS_CJS_PRESET_FIXED_VERSION = "1.7.0";
2365
+ var TOKENS_TAILWIND3_CJS_REQUIRE = `require("${TOKENS_TAILWIND3_PRESET}").default`;
2366
+ var PRESET_REQUIRE_CALL = /\brequire\s*\(\s*(["'])@axis-ds\/tokens\/tailwind\1\s*\)/g;
2367
+ var DEFAULT_ACCESS_AHEAD = /^\s*(?:\.\s*default\b|\[\s*["']default["']\s*\])/;
2368
+ function hasBareCjsPresetRequire(code) {
2369
+ for (const m of code.matchAll(PRESET_REQUIRE_CALL)) {
2370
+ const start = m.index ?? 0;
2371
+ const end = start + m[0].length;
2372
+ if (DEFAULT_ACCESS_AHEAD.test(code.slice(end))) continue;
2373
+ const before = code.slice(0, start);
2374
+ if (/\b(?:const|let|var)\s*\{[^{}]*\}\s*=\s*$/.test(before)) continue;
2375
+ const bound = /\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*$/.exec(before);
2376
+ if (!bound) return true;
2377
+ const ident = escapeRegExp(bound[1]);
2378
+ const rest = code.slice(0, bound.index) + code.slice(end);
2379
+ const bareUse = new RegExp(`(?<![\\w$.])${ident}(?![\\w$])(?!\\s*(?:\\.\\s*default\\b|\\[\\s*["']default["']\\s*\\]))`);
2380
+ if (bareUse.test(rest)) return true;
2381
+ }
2382
+ return false;
2383
+ }
2384
+ function isCommonJsConfig(file, source) {
2385
+ return extname(file) === ".cjs" || /\bmodule\.exports\b/.test(source);
2386
+ }
2387
+ function packageVersionGate(baseDirInput, pkg, name, min) {
2388
+ const baseDir = resolve(baseDirInput);
2389
+ if (!isPnpProject(baseDir)) {
2390
+ const installed = findInstalledPackage(baseDir, name)?.version;
2391
+ if (installed !== void 0) {
2392
+ const cmp = compareExactVersions(installed, min);
2393
+ if (cmp !== void 0) return { status: cmp >= 0 ? "ok" : "below", source: "installed", value: installed };
2394
+ }
2395
+ }
2396
+ const declared = pkg ? hasDependency2(pkg, name) : void 0;
2397
+ if (declared !== void 0) {
2398
+ const atLeast = rangeLowerAtLeast(declared, min);
2399
+ if (atLeast !== void 0) return { status: atLeast ? "ok" : "below", source: "declared", value: declared };
2400
+ return { status: "unknown", source: "declared", value: declared };
2401
+ }
2402
+ return { status: "unknown", source: "none" };
2403
+ }
2404
+ function versionGateLabel(gate) {
2405
+ if (gate.source === "installed") return `\uC124\uCE58\uBCF8 ${gate.value}`;
2406
+ if (gate.source === "declared") return `\uC120\uC5B8 ${gate.value}`;
2407
+ return "\uC124\uCE58\uBCF8 \xB7 \uC120\uC5B8 \uC5C6\uC74C";
2408
+ }
2185
2409
  function readPackageJson(baseDir) {
2186
2410
  try {
2187
- const parsed = JSON.parse(readFileSync(join(baseDir, "package.json"), "utf8"));
2188
- return isPlainObject(parsed) ? parsed : void 0;
2411
+ const parsed = JSON.parse(readFileSync2(join(baseDir, "package.json"), "utf8"));
2412
+ return isPlainObject2(parsed) ? parsed : void 0;
2189
2413
  } catch {
2190
2414
  return void 0;
2191
2415
  }
@@ -2195,7 +2419,7 @@ function tailwind4Issues(css, pkg, versions) {
2195
2419
  const hasEntry = hasTokensTailwind4Import(css);
2196
2420
  if (!hasEntry) issues.push(`AXIS \uD1A0\uD070 \uC9C4\uC785\uC810\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${TOKENS_TAILWIND4_IMPORT_LINE}`);
2197
2421
  const missing = TAILWIND4_COMPONENT_PACKAGES.filter(
2198
- (name) => pkg !== void 0 && hasDependency(pkg, name) !== void 0 && !hasComponentTailwindImport(css, name) && !hasComponentSource(css, name)
2422
+ (name) => pkg !== void 0 && hasDependency2(pkg, name) !== void 0 && !hasComponentTailwindImport(css, name) && !hasComponentSource(css, name)
2199
2423
  );
2200
2424
  if (missing.length > 0) {
2201
2425
  issues.push(`\uCEF4\uD3EC\uB10C\uD2B8 \uC2A4\uCE94 \uACBD\uB85C(tailwind.css)\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${missing.map(componentTailwindImportLine).join(" ")}`);
@@ -2222,8 +2446,8 @@ function checkTailwindSetup(baseDirInput) {
2222
2446
  const label = `Tailwind ${tailwind.major}`;
2223
2447
  for (const candidate of TAILWIND_CSS_CANDIDATES) {
2224
2448
  const file = join(baseDir, candidate);
2225
- if (!existsSync(file)) continue;
2226
- const css = readFileSync(file, "utf8");
2449
+ if (!existsSync2(file)) continue;
2450
+ const css = readFileSync2(file, "utf8");
2227
2451
  if (!hasTailwindImport(css)) {
2228
2452
  return {
2229
2453
  name: "tailwind.config",
@@ -2254,9 +2478,21 @@ function checkTailwindSetup(baseDirInput) {
2254
2478
  }
2255
2479
  for (const file of TAILWIND_CONFIG_FILES) {
2256
2480
  const path18 = join(baseDir, file);
2257
- if (!existsSync(path18)) continue;
2258
- const content = readFileSync(path18, "utf8");
2481
+ if (!existsSync2(path18)) continue;
2482
+ const content = readFileSync2(path18, "utf8");
2259
2483
  if (hasTokensPresetReference(content)) {
2484
+ const code = stripJsComments(content);
2485
+ if (isCommonJsConfig(file, code) && hasBareCjsPresetRequire(code)) {
2486
+ const gate = packageVersionGate(baseDir, pkg, "@axis-ds/tokens", TOKENS_CJS_PRESET_FIXED_VERSION);
2487
+ if (gate.status !== "ok") {
2488
+ const why = gate.status === "below" ? `@axis-ds/tokens ${versionGateLabel(gate)} \uC5D0\uC11C\uB294 CommonJS \uC758 require("${TOKENS_TAILWIND3_PRESET}") \uAC00 preset \uC774 \uC544\uB2C8\uB77C { default } \uB97C \uB3CC\uB824\uC918 \uC0C9 \xB7 keyframes \uAC00 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4` : `@axis-ds/tokens \uBC84\uC804\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${versionGateLabel(gate)}). ${TOKENS_CJS_PRESET_FIXED_VERSION} \uBBF8\uB9CC\uC774\uBA74 CommonJS \uC758 require("${TOKENS_TAILWIND3_PRESET}") \uB85C\uB294 preset \uC774 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`;
2489
+ return {
2490
+ name: "tailwind.config",
2491
+ severity: "warn",
2492
+ message: `${file}\uC5D0 AXIS preset \uCC38\uC870\uAC00 \uC788\uC9C0\uB9CC ${why} \u2192 ${TOKENS_TAILWIND3_CJS_REQUIRE} \uB85C \uBC14\uAFB8\uAC70\uB098 @axis-ds/tokens ${TOKENS_CJS_PRESET_FIXED_VERSION} \uC774\uC0C1`
2493
+ };
2494
+ }
2495
+ }
2260
2496
  return { name: "tailwind.config", severity: "pass", message: `${file}${PRESET_PASS_SUFFIX}` };
2261
2497
  }
2262
2498
  const ownMapping = content.includes("--background") || content.includes("hsl(var(");
@@ -2270,8 +2506,8 @@ function checkTailwindSetup(baseDirInput) {
2270
2506
  }
2271
2507
  function readAxisConfigLike(baseDir) {
2272
2508
  try {
2273
- const parsed = JSON.parse(readFileSync(join(baseDir, "axis.config.json"), "utf8"));
2274
- return isPlainObject(parsed) ? parsed : void 0;
2509
+ const parsed = JSON.parse(readFileSync2(join(baseDir, "axis.config.json"), "utf8"));
2510
+ return isPlainObject2(parsed) ? parsed : void 0;
2275
2511
  } catch {
2276
2512
  return void 0;
2277
2513
  }
@@ -2358,7 +2594,7 @@ function inspectTailwindContent(baseDirInput) {
2358
2594
  const pkg = readPackageJson(baseDir);
2359
2595
  const tailwind = detectTailwind(baseDir, pkg);
2360
2596
  if (tailwind.major !== void 0 && tailwind.major >= 4) return null;
2361
- const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync(join(baseDir, f)));
2597
+ const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync2(join(baseDir, f)));
2362
2598
  if (configFile === void 0) return null;
2363
2599
  const targets = [];
2364
2600
  const componentsDir = readAxisConfigLike(baseDir)?.componentsDir;
@@ -2367,12 +2603,12 @@ function inspectTailwindContent(baseDirInput) {
2367
2603
  targets.push({ label: `componentsDir(${componentsDir})`, sample: `${rel3}/button.tsx`, suggest: `./${rel3}/**/*.{ts,tsx}` });
2368
2604
  }
2369
2605
  for (const name of TAILWIND4_COMPONENT_PACKAGES) {
2370
- if (pkg !== void 0 && hasDependency(pkg, name) !== void 0) {
2606
+ if (pkg !== void 0 && hasDependency2(pkg, name) !== void 0) {
2371
2607
  targets.push({ label: name, sample: `node_modules/${name}/dist/index.js`, suggest: `./node_modules/${name}/dist/**/*.{js,mjs}` });
2372
2608
  }
2373
2609
  }
2374
2610
  if (targets.length === 0) return null;
2375
- const read = readTailwindContent(readFileSync(join(baseDir, configFile), "utf8"));
2611
+ const read = readTailwindContent(readFileSync2(join(baseDir, configFile), "utf8"));
2376
2612
  const patterns = (read?.globs ?? []).filter((g) => !g.trim().startsWith("!")).map(contentGlobToRegExp);
2377
2613
  return {
2378
2614
  configFile,
@@ -2437,7 +2673,7 @@ function componentsUseAnimation(baseDir, componentsDir) {
2437
2673
  if (st.isDirectory()) {
2438
2674
  if (name !== "node_modules" && depth < ANIMATION_SCAN_DEPTH_LIMIT) stack.push([p, depth + 1]);
2439
2675
  } else if (st.isFile() && st.size <= ANIMATION_SCAN_FILE_BYTES && /\.(tsx|ts|jsx|js)$/.test(name)) {
2440
- if (/\banimate-(?:in|out)\b/.test(readFileSync(p, "utf8"))) return true;
2676
+ if (/\banimate-(?:in|out)\b/.test(readFileSync2(p, "utf8"))) return true;
2441
2677
  }
2442
2678
  }
2443
2679
  }
@@ -2447,14 +2683,14 @@ function checkAnimationPlugin(baseDirInput) {
2447
2683
  const baseDir = resolve(baseDirInput);
2448
2684
  const pkg = readPackageJson(baseDir);
2449
2685
  const config = readAxisConfigLike(baseDir);
2450
- const declared = pkg !== void 0 && hasDependency(pkg, "@axis-ds/ui-react") !== void 0;
2686
+ const declared = pkg !== void 0 && hasDependency2(pkg, "@axis-ds/ui-react") !== void 0;
2451
2687
  const copied = typeof config?.componentsDir === "string" && componentsUseAnimation(baseDir, config.componentsDir);
2452
2688
  if (!declared && !copied) return null;
2453
2689
  const by = declared ? "@axis-ds/ui-react \uC120\uC5B8" : "componentsDir \uC758 animate-in \uB958 \uD074\uB798\uC2A4";
2454
2690
  const tailwind = detectTailwind(baseDir, pkg);
2455
2691
  if (tailwind.major !== void 0 && tailwind.major >= 4) {
2456
- const file = TAILWIND_CSS_CANDIDATES.find((c) => existsSync(join(baseDir, c)));
2457
- const css = file !== void 0 ? stripCssComments(readFileSync(join(baseDir, file), "utf8")) : "";
2692
+ const file = TAILWIND_CSS_CANDIDATES.find((c) => existsSync2(join(baseDir, c)));
2693
+ const css = file !== void 0 ? stripCssComments(readFileSync2(join(baseDir, file), "utf8")) : "";
2458
2694
  const ok = new RegExp(`@import\\s+(?:url\\(\\s*)?["']${ANIMATION_PLUGIN_TAILWIND4}["']`).test(css) || new RegExp(`@plugin\\s+["']${ANIMATION_PLUGIN_TAILWIND3}["']`).test(css);
2459
2695
  return ok ? { name: "animation", severity: "pass", message: `${file}\uC5D0 \uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC788\uC2B5\uB2C8\uB2E4` } : {
2460
2696
  name: "animation",
@@ -2462,25 +2698,91 @@ function checkAnimationPlugin(baseDirInput) {
2462
2698
  message: `\uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC5C6\uC2B5\uB2C8\uB2E4(${by}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 ${ANIMATION_PLUGIN_TAILWIND4} \uC124\uCE58 \uB4A4 @import "${ANIMATION_PLUGIN_TAILWIND4}";`
2463
2699
  };
2464
2700
  }
2465
- const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync(join(baseDir, f)));
2466
- const source = configFile !== void 0 ? stripJsComments(readFileSync(join(baseDir, configFile), "utf8")) : "";
2467
- const pluginRef = new RegExp(`["']${ANIMATION_PLUGIN_TAILWIND3}["']`).test(source);
2468
- const pluginDeclared = pkg !== void 0 && hasDependency(pkg, ANIMATION_PLUGIN_TAILWIND3) !== void 0;
2469
- if (pluginRef && pluginDeclared) {
2470
- return { name: "animation", severity: "pass", message: `${configFile}\uC5D0 ${ANIMATION_PLUGIN_TAILWIND3} \uD50C\uB7EC\uADF8\uC778\uC774 \uC788\uC2B5\uB2C8\uB2E4` };
2471
- }
2472
- const why = !pluginDeclared ? `${ANIMATION_PLUGIN_TAILWIND3} \uBBF8\uC124\uCE58` : `${configFile ?? "tailwind.config"} plugins \uC5D0 \uC5C6\uC74C`;
2701
+ const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync2(join(baseDir, f)));
2702
+ const source = configFile !== void 0 ? stripJsComments(readFileSync2(join(baseDir, configFile), "utf8")) : "";
2703
+ const plugins = configFile !== void 0 ? readAnimationPluginUse(source) : "absent";
2704
+ const pluginDeclared = pkg !== void 0 && hasDependency2(pkg, ANIMATION_PLUGIN_TAILWIND3) !== void 0;
2705
+ const pluginInstalled = pluginDeclared && (isPnpProject(baseDir) || findInstalledPackage(baseDir, ANIMATION_PLUGIN_TAILWIND3) !== void 0);
2706
+ if (plugins === "found" && pluginDeclared && pluginInstalled) {
2707
+ return { name: "animation", severity: "pass", message: `${configFile}\uC758 plugins \uC5D0 ${ANIMATION_PLUGIN_TAILWIND3} \uAC00 \uC788\uC2B5\uB2C8\uB2E4` };
2708
+ }
2709
+ const cfg = configFile ?? "tailwind.config";
2710
+ const reasons = [];
2711
+ if (!pluginDeclared) reasons.push(`${ANIMATION_PLUGIN_TAILWIND3} \uC120\uC5B8 \uC5C6\uC74C`);
2712
+ else if (!pluginInstalled) reasons.push(`${ANIMATION_PLUGIN_TAILWIND3} \uBBF8\uC124\uCE58(\uC120\uC5B8\uB9CC \uC788\uC74C)`);
2713
+ if (plugins === "dynamic") reasons.push(`${cfg} plugins \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD568`);
2714
+ else if (plugins !== "found") reasons.push(`${cfg} plugins \uC5D0 \uC5C6\uC74C`);
2473
2715
  return {
2474
2716
  name: "animation",
2475
2717
  severity: "warn",
2476
- message: `\uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC5C6\uC2B5\uB2C8\uB2E4(${by}, ${why}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 ${ANIMATION_PLUGIN_TAILWIND3} \uC124\uCE58 \uB4A4 plugins \uC5D0 require("${ANIMATION_PLUGIN_TAILWIND3}")`
2718
+ message: `\uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC5C6\uC2B5\uB2C8\uB2E4(${by}, ${reasons.join(" \xB7 ")}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 ${ANIMATION_PLUGIN_TAILWIND3} \uC124\uCE58 \uB4A4 plugins \uC5D0 require("${ANIMATION_PLUGIN_TAILWIND3}")`
2477
2719
  };
2478
2720
  }
2721
+ function readAnimationPluginUse(source) {
2722
+ const name = escapeRegExp(ANIMATION_PLUGIN_TAILWIND3);
2723
+ const idents = /* @__PURE__ */ new Set();
2724
+ for (const m of source.matchAll(new RegExp(`\\bimport\\s+([A-Za-z_$][\\w$]*)\\s+from\\s*(["'])${name}\\2`, "g"))) idents.add(m[1]);
2725
+ for (const m of source.matchAll(
2726
+ new RegExp(`\\b(?:const|let|var)\\s+([A-Za-z_$][\\w$]*)\\s*=\\s*require\\s*\\(\\s*(["'])${name}\\2\\s*\\)`, "g")
2727
+ )) {
2728
+ idents.add(m[1]);
2729
+ }
2730
+ const requireCall = new RegExp(`^require\\s*\\(\\s*(["'])${name}\\1\\s*\\)(?:\\s*\\.\\s*default)?$`);
2731
+ let sawDynamic = false;
2732
+ for (const m of source.matchAll(/\bplugins\b\s*(:)?\s*/g)) {
2733
+ if (m[1] === void 0) {
2734
+ const before = source.slice(Math.max(0, (m.index ?? 0) - 1), m.index ?? 0);
2735
+ if (/[{,\s]/.test(before) || before === "") sawDynamic = true;
2736
+ continue;
2737
+ }
2738
+ const at = (m.index ?? 0) + m[0].length;
2739
+ if (source[at] !== "[") {
2740
+ sawDynamic = true;
2741
+ continue;
2742
+ }
2743
+ const block = balancedSlice(source, at);
2744
+ if (block === void 0) {
2745
+ sawDynamic = true;
2746
+ continue;
2747
+ }
2748
+ const elements = splitTopLevel(block.slice(1, -1));
2749
+ for (const el of elements) {
2750
+ const e = el.trim();
2751
+ if (e === "") continue;
2752
+ if (requireCall.test(e) || idents.has(e) || idents.has(e.replace(/\(\s*\)$/, ""))) return "found";
2753
+ if (/^require\s*\(\s*(["'])[^"']+\1\s*\)(?:\s*\.\s*default)?$/.test(e)) continue;
2754
+ sawDynamic = true;
2755
+ }
2756
+ }
2757
+ return sawDynamic ? "dynamic" : "absent";
2758
+ }
2759
+ function splitTopLevel(body) {
2760
+ const out = [];
2761
+ let depth = 0;
2762
+ let start = 0;
2763
+ for (let i = 0; i < body.length; i++) {
2764
+ const c = body[i];
2765
+ if (c === '"' || c === "'" || c === "`") {
2766
+ let j = i + 1;
2767
+ while (j < body.length && body[j] !== c) j += body[j] === "\\" ? 2 : 1;
2768
+ i = j;
2769
+ continue;
2770
+ }
2771
+ if (c === "(" || c === "[" || c === "{") depth++;
2772
+ else if (c === ")" || c === "]" || c === "}") depth--;
2773
+ else if (c === "," && depth === 0) {
2774
+ out.push(body.slice(start, i));
2775
+ start = i + 1;
2776
+ }
2777
+ }
2778
+ out.push(body.slice(start));
2779
+ return out;
2780
+ }
2479
2781
 
2480
2782
  // src/template/template-apply.ts
2481
2783
  async function templateApplyWarnings(baseDir, detail) {
2482
2784
  const warnings = [];
2483
- const pkgPath = path8.join(baseDir, "package.json");
2785
+ const pkgPath = path9.join(baseDir, "package.json");
2484
2786
  const templateRange = detail.devDependencies?.tailwindcss ?? detail.dependencies?.tailwindcss;
2485
2787
  const templateMajor = templateRange !== void 0 ? tailwindMajorFromRange(templateRange) : void 0;
2486
2788
  if (templateMajor !== void 0 && await fs8.pathExists(pkgPath)) {
@@ -2498,7 +2800,7 @@ async function templateApplyWarnings(baseDir, detail) {
2498
2800
  }
2499
2801
  }
2500
2802
  const usesRootApp = detail.files.some((f) => f.path.startsWith("app/"));
2501
- if (usesRootApp && await fs8.pathExists(path8.join(baseDir, "src", "app"))) {
2803
+ if (usesRootApp && await fs8.pathExists(path9.join(baseDir, "src", "app"))) {
2502
2804
  warnings.push(
2503
2805
  "src/app \uC774 \uC788\uB294\uB370 \uD15C\uD50C\uB9BF\uC740 \uB8E8\uD2B8 app/ \uC744 \uC501\uB2C8\uB2E4. Next.js \uB294 \uB8E8\uD2B8 app/ \uC774 \uC788\uC73C\uBA74 src/app \uC744 \uC4F0\uC9C0 \uC54A\uC544 \uAE30\uC874 \uB77C\uC6B0\uD2B8\uAC00 \uBE60\uC9D1\uB2C8\uB2E4."
2504
2806
  );
@@ -2515,13 +2817,13 @@ async function applyTemplate(slug, options) {
2515
2817
  spinner.fail(err.message);
2516
2818
  process.exit(1);
2517
2819
  }
2518
- const baseDir = path8.resolve(options.dir || ".");
2820
+ const baseDir = path9.resolve(options.dir || ".");
2519
2821
  for (const w of await templateApplyWarnings(baseDir, detail)) {
2520
2822
  console.log(chalk5.yellow(`! ${w}`));
2521
2823
  }
2522
2824
  const conflicts = [];
2523
2825
  for (const file of detail.files) {
2524
- const dest = path8.join(baseDir, file.path);
2826
+ const dest = path9.join(baseDir, file.path);
2525
2827
  if (await fs8.pathExists(dest)) {
2526
2828
  conflicts.push(file.path);
2527
2829
  }
@@ -2546,7 +2848,7 @@ async function applyTemplate(slug, options) {
2546
2848
  if (options.dryRun) {
2547
2849
  console.log(chalk5.blue("\n[\uBBF8\uB9AC\uBCF4\uAE30] \uC0DD\uC131\uB420 \uD30C\uC77C:"));
2548
2850
  for (const file of detail.files) {
2549
- const dest = path8.join(baseDir, file.path);
2851
+ const dest = path9.join(baseDir, file.path);
2550
2852
  const exists = conflicts.includes(file.path);
2551
2853
  const label = exists ? chalk5.yellow("\uB36E\uC5B4\uC4F0\uAE30") : chalk5.green("\uC0DD\uC131");
2552
2854
  console.log(` ${label} ${dest}`);
@@ -2561,8 +2863,8 @@ async function applyTemplate(slug, options) {
2561
2863
  }
2562
2864
  const writeSpinner = ora3("\uD30C\uC77C \uC0DD\uC131 \uC911...").start();
2563
2865
  for (const file of detail.files) {
2564
- const dest = path8.join(baseDir, file.path);
2565
- await fs8.ensureDir(path8.dirname(dest));
2866
+ const dest = path9.join(baseDir, file.path);
2867
+ await fs8.ensureDir(path9.dirname(dest));
2566
2868
  await fs8.writeFile(dest, file.content);
2567
2869
  }
2568
2870
  writeSpinner.succeed(`${detail.files.length}\uAC1C \uD30C\uC77C \uC0DD\uC131 \uC644\uB8CC`);
@@ -2623,7 +2925,7 @@ async function initTemplate(slug, options) {
2623
2925
  }
2624
2926
  targetDir = dir;
2625
2927
  }
2626
- const resolved = path8.resolve(targetDir);
2928
+ const resolved = path9.resolve(targetDir);
2627
2929
  if (await fs8.pathExists(resolved)) {
2628
2930
  const entries = await fs8.readdir(resolved);
2629
2931
  if (entries.length > 0) {
@@ -2639,7 +2941,7 @@ async function initTemplate(slug, options) {
2639
2941
  await fs8.ensureDir(resolved);
2640
2942
  }
2641
2943
  await applyTemplate(selectedSlug, { dir: targetDir, yes: true });
2642
- const configPath = path8.join(resolved, "axis.config.json");
2944
+ const configPath = path9.join(resolved, "axis.config.json");
2643
2945
  if (!await fs8.pathExists(configPath)) {
2644
2946
  const axisConfig = createTemplateConfig(selectedSlug);
2645
2947
  await fs8.writeJSON(configPath, axisConfig, { spaces: 2 });
@@ -2654,7 +2956,7 @@ async function initTemplate(slug, options) {
2654
2956
 
2655
2957
  // src/template/template-diff.ts
2656
2958
  import fs9 from "fs-extra";
2657
- import path9 from "path";
2959
+ import path10 from "path";
2658
2960
  import chalk6 from "chalk";
2659
2961
  import ora4 from "ora";
2660
2962
  async function diffTemplate(slug, options) {
@@ -2667,10 +2969,10 @@ async function diffTemplate(slug, options) {
2667
2969
  spinner.fail(err.message);
2668
2970
  process.exit(1);
2669
2971
  }
2670
- const baseDir = path9.resolve(options.dir || ".");
2972
+ const baseDir = path10.resolve(options.dir || ".");
2671
2973
  const entries = [];
2672
2974
  for (const file of detail.files) {
2673
- const localPath = path9.join(baseDir, file.path);
2975
+ const localPath = path10.join(baseDir, file.path);
2674
2976
  if (!await fs9.pathExists(localPath)) {
2675
2977
  entries.push({ path: file.path, status: "added" });
2676
2978
  continue;
@@ -2751,12 +3053,12 @@ async function collectLocalFiles(dir, base) {
2751
3053
  }
2752
3054
  for (const entry of entries) {
2753
3055
  if (ignore.has(entry.name)) continue;
2754
- const fullPath = path9.join(dir, entry.name);
3056
+ const fullPath = path10.join(dir, entry.name);
2755
3057
  if (entry.isDirectory()) {
2756
3058
  const nested = await collectLocalFiles(fullPath, root);
2757
3059
  results.push(...nested);
2758
3060
  } else {
2759
- results.push(path9.relative(root, fullPath).replace(/\\/g, "/"));
3061
+ results.push(path10.relative(root, fullPath).replace(/\\/g, "/"));
2760
3062
  }
2761
3063
  }
2762
3064
  return results;
@@ -2768,85 +3070,9 @@ import path11 from "path";
2768
3070
  import chalk7 from "chalk";
2769
3071
 
2770
3072
  // src/theme/brand-core.ts
2771
- import { existsSync as existsSync3, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
3073
+ import { existsSync as existsSync3, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
2772
3074
  import { createRequire } from "module";
2773
3075
  import { dirname, join as join2, relative, resolve as resolve2, sep } from "path";
2774
-
2775
- // ../axis-registry-core/src/project.ts
2776
- import { existsSync as existsSync2, statSync } from "fs";
2777
- import path10 from "path";
2778
- function detectInstallCommand(baseDir) {
2779
- if (existsSync2(path10.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
2780
- if (existsSync2(path10.join(baseDir, "yarn.lock"))) return "yarn install";
2781
- if (existsSync2(path10.join(baseDir, "package-lock.json"))) return "npm install";
2782
- return "pnpm install";
2783
- }
2784
- function hasDependency2(pkg, name) {
2785
- for (const field of ["dependencies", "devDependencies"]) {
2786
- const deps = pkg[field];
2787
- if (typeof deps === "object" && deps !== null && name in deps) {
2788
- return String(deps[name]);
2789
- }
2790
- }
2791
- return void 0;
2792
- }
2793
- function isPlainObject2(value) {
2794
- return typeof value === "object" && value !== null && !Array.isArray(value);
2795
- }
2796
- function addCommandFor(installCommand, deps) {
2797
- const specs = Object.entries(deps).map(([name, range]) => `"${name}@${range}"`).join(" ");
2798
- if (installCommand.startsWith("yarn")) return `yarn add ${specs}`;
2799
- if (installCommand.startsWith("npm")) return `npm install ${specs}`;
2800
- return `pnpm add ${specs}`;
2801
- }
2802
- var GLOBAL_CSS_CANDIDATES = [
2803
- "app/globals.css",
2804
- "src/app/globals.css",
2805
- "styles/globals.css",
2806
- "src/styles/globals.css",
2807
- "globals.css"
2808
- ];
2809
- var TAILWIND_CONFIG_CANDIDATES = [
2810
- "tailwind.config.ts",
2811
- "tailwind.config.js",
2812
- "tailwind.config.mjs",
2813
- "tailwind.config.cjs"
2814
- ];
2815
- function isFile(file) {
2816
- try {
2817
- return statSync(file).isFile();
2818
- } catch {
2819
- return false;
2820
- }
2821
- }
2822
- function isDirectory(dir) {
2823
- try {
2824
- return statSync(dir).isDirectory();
2825
- } catch {
2826
- return false;
2827
- }
2828
- }
2829
- function findFirstFile(baseDir, candidates) {
2830
- return candidates.find((c) => isFile(path10.join(baseDir, c)));
2831
- }
2832
- function detectProjectPaths(baseDirInput) {
2833
- const baseDir = path10.resolve(baseDirInput);
2834
- const hasSrc = isDirectory(path10.join(baseDir, "src"));
2835
- const css = findFirstFile(baseDir, GLOBAL_CSS_CANDIDATES);
2836
- const tw = findFirstFile(baseDir, TAILWIND_CONFIG_CANDIDATES);
2837
- return {
2838
- componentsDir: hasSrc ? "./src/components/ui" : "./components/ui",
2839
- globalCss: css !== void 0 ? `./${css}` : hasSrc ? "./src/app/globals.css" : "./app/globals.css",
2840
- globalCssSource: css !== void 0 ? "found" : "default",
2841
- tailwindConfig: tw !== void 0 ? `./${tw}` : "./tailwind.config.ts",
2842
- tailwindConfigSource: tw !== void 0 ? "found" : "default"
2843
- };
2844
- }
2845
- function projectFileExists(baseDir, relPath) {
2846
- return isFile(path10.resolve(baseDir, relPath));
2847
- }
2848
-
2849
- // src/theme/brand-core.ts
2850
3076
  var TOKENS_PACKAGE = "@axis-ds/tokens";
2851
3077
  var BRAND_NAME_PATTERN = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
2852
3078
  var MIN_BRAND_TOKENS_VERSION = "1.3.0";
@@ -2867,7 +3093,7 @@ var KEY_TOKENS = [
2867
3093
  ];
2868
3094
  var BRAND_ADJUSTMENT_REFERENCE = "WI-0025 PRD \uBD80\uB85D B (docs/workitems/WI-0025-brand-theme/prd.md)";
2869
3095
  function readJsonFile(file) {
2870
- return JSON.parse(readFileSync2(file, "utf8"));
3096
+ return JSON.parse(readFileSync3(file, "utf8"));
2871
3097
  }
2872
3098
  function errorCode(err) {
2873
3099
  return typeof err === "object" && err !== null && "code" in err ? String(err.code) : void 0;
@@ -2943,7 +3169,7 @@ var AXIS_CONFIG_FILE_NAME = "axis.config.json";
2943
3169
  function readBrandConfig(baseDir) {
2944
3170
  let parsed;
2945
3171
  try {
2946
- parsed = JSON.parse(readFileSync2(join2(resolve2(baseDir), AXIS_CONFIG_FILE_NAME), "utf8"));
3172
+ parsed = JSON.parse(readFileSync3(join2(resolve2(baseDir), AXIS_CONFIG_FILE_NAME), "utf8"));
2947
3173
  } catch {
2948
3174
  return null;
2949
3175
  }
@@ -2962,7 +3188,7 @@ function inspectBrandImport(baseDir) {
2962
3188
  return { ...base, state: "css-missing", imports: [] };
2963
3189
  }
2964
3190
  const cssFile = relative(root, location.path).split(sep).join("/");
2965
- const imports = [...new Set(findBrandImports(readFileSync2(location.path, "utf8")))];
3191
+ const imports = [...new Set(findBrandImports(readFileSync3(location.path, "utf8")))];
2966
3192
  let state;
2967
3193
  if (imports.includes(brand)) state = "match";
2968
3194
  else if (imports.length === 0) state = "import-missing";
@@ -3046,34 +3272,23 @@ function pickKeyTokens(decls) {
3046
3272
  }
3047
3273
  return out;
3048
3274
  }
3275
+ var THEME_MARKUP_BRAND_MIN_VERSION = "1.7.0";
3049
3276
  function providerExample(name) {
3050
3277
  return [
3051
- "// 1) Provider \uC5C6\uC774: \uB8E8\uD2B8 \uB808\uC774\uC544\uC6C3(app/layout.tsx)\uC758 <html> \uC5D0 \uBD99\uC785\uB2C8\uB2E4(\uCCAB \uD654\uBA74\uBD80\uD130 \uC801\uC6A9)",
3278
+ "// 1) \uB8E8\uD2B8 \uB808\uC774\uC544\uC6C3(app/layout.tsx)\uC758 <html> \uC5D0 \uBD99\uC785\uB2C8\uB2E4(\uCCAB \uD654\uBA74\uBD80\uD130 \uC801\uC6A9)",
3279
+ `// ThemeProvider \uB97C \uD568\uAED8 \uC4F0\uBA74 @axis-ds/theme ${THEME_MARKUP_BRAND_MIN_VERSION} \uC774\uC0C1\uC774 \uD544\uC694\uD569\uB2C8\uB2E4(\uADF8 \uC544\uB798\uB294 \uB9C8\uC6B4\uD2B8 \uB54C \uC18D\uC131\uC744 \uC9C0\uC6C0)`,
3052
3280
  `<html lang="ko" data-brand="${name}">`,
3053
3281
  "",
3054
- "// 2) ThemeProvider \uB97C \uC4F0\uBA74 \uB9C8\uC6B4\uD2B8 \uB54C \uBE0C\uB79C\uB4DC\uAC00 \uC5C6\uC73C\uBA74 \uC18D\uC131\uC744 \uC9C0\uC6B0\uBBC0\uB85C setBrand \uB85C \uCF2D\uB2C8\uB2E4(\uC800\uC7A5\uB3FC \uC720\uC9C0, setBrand(undefined) \uB85C \uB054)",
3282
+ `// 2) \uC0AC\uC6A9\uC790\uAC00 \uACE0\uB974\uAC8C \uD558\uB824\uBA74 setBrand \uB85C \uCF1C\uACE0 \uB055\uB2C8\uB2E4(\uC800\uC7A5\uB3FC \uC720\uC9C0, setBrand(undefined) \uB85C \uB048 \uC0C1\uD0DC \uC720\uC9C0\uB294 ${THEME_MARKUP_BRAND_MIN_VERSION} \uC774\uC0C1)`,
3055
3283
  'import { useTheme } from "@axis-ds/theme";',
3056
3284
  "const { setBrand } = useTheme();",
3057
3285
  `setBrand("${name}");`
3058
3286
  ].join("\n");
3059
3287
  }
3060
- var BRAND_ACTIVATION_FILES = [
3061
- "app/layout.tsx",
3062
- "app/layout.jsx",
3063
- "app/layout.js",
3064
- "src/app/layout.tsx",
3065
- "src/app/layout.jsx",
3066
- "src/app/layout.js",
3067
- "pages/_app.tsx",
3068
- "pages/_app.jsx",
3069
- "pages/_document.tsx",
3070
- "pages/_document.jsx",
3071
- "src/pages/_app.tsx",
3072
- "src/pages/_app.jsx",
3073
- "src/pages/_document.tsx",
3074
- "src/pages/_document.jsx"
3075
- ];
3288
+ var BRAND_ACTIVATION_FILES = ROOT_LAYOUT_FILES;
3076
3289
  var BRAND_ACTIVATION_PATTERN = /data-brand|setBrand\s*\(|defaultBrand\s*=/;
3290
+ var PROVIDER_ACTIVATION_PATTERN = /setBrand\s*\(|defaultBrand\s*=/;
3291
+ var THEME_PROVIDER_PATTERN = /<ThemeProvider\b/;
3077
3292
  function stripJsLikeComments(src) {
3078
3293
  return src.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:"'`])\/\/[^\n]*/g, "$1");
3079
3294
  }
@@ -3084,15 +3299,23 @@ function findBrandActivation(baseDir) {
3084
3299
  const file = join2(root, candidate);
3085
3300
  if (!isFile2(file)) continue;
3086
3301
  layoutFiles.push(candidate);
3087
- const text = stripJsLikeComments(readFileSync2(file, "utf8"));
3088
- if (BRAND_ACTIVATION_PATTERN.test(text)) return { found: candidate, layoutFiles };
3302
+ const text = stripJsLikeComments(readFileSync3(file, "utf8"));
3303
+ const providerTexts = [];
3089
3304
  for (const m of text.matchAll(/from\s+["']\.\/(providers?)["']/g)) {
3090
3305
  for (const ext of [".tsx", ".jsx", ".ts", ".js"]) {
3091
3306
  const rel3 = `${dirname(candidate)}/${m[1]}${ext}`;
3092
3307
  const p = join2(root, rel3);
3093
- if (isFile2(p) && BRAND_ACTIVATION_PATTERN.test(stripJsLikeComments(readFileSync2(p, "utf8")))) {
3094
- return { found: rel3, layoutFiles };
3095
- }
3308
+ if (isFile2(p)) providerTexts.push({ rel: rel3, text: stripJsLikeComments(readFileSync3(p, "utf8")) });
3309
+ }
3310
+ }
3311
+ const all = [text, ...providerTexts.map((x) => x.text)];
3312
+ const markupWithProvider = !all.some((t) => PROVIDER_ACTIVATION_PATTERN.test(t)) && all.some((t) => THEME_PROVIDER_PATTERN.test(t));
3313
+ if (BRAND_ACTIVATION_PATTERN.test(text)) {
3314
+ return markupWithProvider ? { found: candidate, layoutFiles, markupWithProvider } : { found: candidate, layoutFiles };
3315
+ }
3316
+ for (const x of providerTexts) {
3317
+ if (BRAND_ACTIVATION_PATTERN.test(x.text)) {
3318
+ return markupWithProvider ? { found: x.rel, layoutFiles, markupWithProvider } : { found: x.rel, layoutFiles };
3096
3319
  }
3097
3320
  }
3098
3321
  }
@@ -3102,7 +3325,18 @@ function inspectBrandActivation(baseDir) {
3102
3325
  const config = readBrandConfig(baseDir);
3103
3326
  const brand = config?.brand;
3104
3327
  if (typeof brand !== "string" || brand.trim() === "") return null;
3105
- return { brand, ...findBrandActivation(baseDir) };
3328
+ const location = findBrandActivation(baseDir);
3329
+ if (!location.markupWithProvider) return { brand, ...location };
3330
+ return { brand, ...location, theme: packageVersionGate(baseDir, readProjectPackageJson(baseDir), THEME_PACKAGE, THEME_MARKUP_BRAND_MIN_VERSION) };
3331
+ }
3332
+ var THEME_PACKAGE = "@axis-ds/theme";
3333
+ function readProjectPackageJson(baseDir) {
3334
+ try {
3335
+ const parsed = JSON.parse(readFileSync3(join2(resolve2(baseDir), "package.json"), "utf8"));
3336
+ return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : void 0;
3337
+ } catch {
3338
+ return void 0;
3339
+ }
3106
3340
  }
3107
3341
  function getBrand(baseDir, name) {
3108
3342
  const tokens = resolveTokens(baseDir);
@@ -3120,7 +3354,7 @@ function getBrand(baseDir, name) {
3120
3354
  try {
3121
3355
  summary = readSummary(baseDir, entry);
3122
3356
  const cssPath = projectRequire(baseDir).resolve(summary.importPath);
3123
- parsed = parseBrandCss(readFileSync2(cssPath, "utf8"), name);
3357
+ parsed = parseBrandCss(readFileSync3(cssPath, "utf8"), name);
3124
3358
  } catch (err) {
3125
3359
  if (isMissingBuildFile(err)) return { status: "not-built", version: tokens.version, brand: null, available: [] };
3126
3360
  throw err;
@@ -3138,6 +3372,57 @@ function getBrand(baseDir, name) {
3138
3372
  };
3139
3373
  }
3140
3374
 
3375
+ // ../axis-registry-core/src/template/dependencies-core.ts
3376
+ import { readFileSync as readFileSync4 } from "fs";
3377
+ import { join as join3, resolve as resolve3 } from "path";
3378
+ var REQUIRED_DEPENDENCIES = ["tailwindcss"];
3379
+ var RECOMMENDED_DEPENDENCIES = ["clsx", "tailwind-merge"];
3380
+ function declaredAxisPackages(pkg) {
3381
+ const out = [];
3382
+ for (const field of ["dependencies", "devDependencies"]) {
3383
+ const deps = pkg[field];
3384
+ if (!isPlainObject(deps)) continue;
3385
+ for (const name of Object.keys(deps)) if (name.startsWith("@axis-ds/") && !out.includes(name)) out.push(name);
3386
+ }
3387
+ return out;
3388
+ }
3389
+ function checkDependencies(baseDirInput) {
3390
+ const baseDir = resolve3(baseDirInput);
3391
+ let pkg;
3392
+ try {
3393
+ const parsed = JSON.parse(readFileSync4(join3(baseDir, "package.json"), "utf8"));
3394
+ if (!isPlainObject(parsed)) throw new Error("not object");
3395
+ pkg = parsed;
3396
+ } catch (err) {
3397
+ if (err?.code === "ENOENT") {
3398
+ return { name: "dependencies", severity: "fail", message: "package.json \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4" };
3399
+ }
3400
+ return { name: "dependencies", severity: "fail", message: "package.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(JSON \uD655\uC778)" };
3401
+ }
3402
+ const missingRequired = REQUIRED_DEPENDENCIES.filter((d) => !hasDependency(pkg, d));
3403
+ if (missingRequired.length > 0) {
3404
+ return { name: "dependencies", severity: "fail", message: `\uD544\uC218 \uC758\uC874\uC131 \uB204\uB77D: ${missingRequired.join(", ")}` };
3405
+ }
3406
+ const missingRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => !hasDependency(pkg, d));
3407
+ const targets = [
3408
+ ...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => hasDependency(pkg, d) !== void 0),
3409
+ ...declaredAxisPackages(pkg)
3410
+ ];
3411
+ const pnp = isPnpProject(baseDir);
3412
+ const notInstalled = pnp ? [] : targets.filter((d) => findInstalledPackage(baseDir, d) === void 0);
3413
+ const problems = [];
3414
+ if (missingRecommended.length > 0) problems.push(`\uAD8C\uC7A5 \uC758\uC874\uC131 \uB204\uB77D: ${missingRecommended.join(", ")}`);
3415
+ if (notInstalled.length > 0) {
3416
+ problems.push(`\uC120\uC5B8\uB410\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC740 \uC758\uC874\uC131: ${notInstalled.join(", ")} \u2192 ${detectInstallCommand(baseDir)}`);
3417
+ }
3418
+ if (problems.length > 0) return { name: "dependencies", severity: "warn", message: problems.join(" / ") };
3419
+ return {
3420
+ name: "dependencies",
3421
+ severity: "pass",
3422
+ message: pnp ? `\uD544\uC218 \uBC0F \uAD8C\uC7A5 \uC758\uC874\uC131\uC774 \uC120\uC5B8\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4 (Plug'n'Play \uB77C \uC124\uCE58\uBCF8\uC740 \uD655\uC778\uD558\uC9C0 \uC54A\uC74C, ${targets.length}\uAC1C)` : `\uD544\uC218 \uBC0F \uAD8C\uC7A5 \uC758\uC874\uC131\uC774 \uC120\uC5B8 \xB7 \uC124\uCE58\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4 (${targets.length}\uAC1C \uD655\uC778)`
3423
+ };
3424
+ }
3425
+
3141
3426
  // src/template/template-check.ts
3142
3427
  var SEVERITY_ICON = {
3143
3428
  pass: chalk7.green("PASS"),
@@ -3151,7 +3436,7 @@ async function collectCheckResults(dir) {
3151
3436
  results.push(checkTailwindSetup(baseDir));
3152
3437
  results.push(checkGlobalsCss(baseDir));
3153
3438
  results.push(await checkUtils(baseDir));
3154
- results.push(await checkDependencies(baseDir));
3439
+ results.push(checkDependencies(baseDir));
3155
3440
  const brand = checkBrand(baseDir);
3156
3441
  if (brand) results.push(brand);
3157
3442
  const activation = inspectBrandActivation(baseDir);
@@ -3229,41 +3514,6 @@ async function checkUtils(baseDir) {
3229
3514
  message: "utils.ts\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (\uCEF4\uD3EC\uB10C\uD2B8 \uC0AC\uC6A9 \uC2DC \uD544\uC694)"
3230
3515
  };
3231
3516
  }
3232
- async function checkDependencies(baseDir) {
3233
- const pkgPath = path11.join(baseDir, "package.json");
3234
- if (!await fs10.pathExists(pkgPath)) {
3235
- return {
3236
- name: "package.json",
3237
- severity: "fail",
3238
- message: "package.json \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
3239
- };
3240
- }
3241
- const pkg = await fs10.readJSON(pkgPath);
3242
- const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
3243
- const required = ["tailwindcss"];
3244
- const recommended = ["clsx", "tailwind-merge"];
3245
- const missingRequired = required.filter((d) => !allDeps[d]);
3246
- const missingRecommended = recommended.filter((d) => !allDeps[d]);
3247
- if (missingRequired.length > 0) {
3248
- return {
3249
- name: "dependencies",
3250
- severity: "fail",
3251
- message: `\uD544\uC218 \uC758\uC874\uC131 \uB204\uB77D: ${missingRequired.join(", ")}`
3252
- };
3253
- }
3254
- if (missingRecommended.length > 0) {
3255
- return {
3256
- name: "dependencies",
3257
- severity: "warn",
3258
- message: `\uAD8C\uC7A5 \uC758\uC874\uC131 \uB204\uB77D: ${missingRecommended.join(", ")}`
3259
- };
3260
- }
3261
- return {
3262
- name: "dependencies",
3263
- severity: "pass",
3264
- message: "\uD544\uC218 \uBC0F \uAD8C\uC7A5 \uC758\uC874\uC131\uC774 \uBAA8\uB450 \uC124\uCE58\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4"
3265
- };
3266
- }
3267
3517
  function checkBrand(baseDir) {
3268
3518
  const check = inspectBrandImport(baseDir);
3269
3519
  return check ? brandCheckResult(check) : null;
@@ -3299,6 +3549,15 @@ function brandCheckResult(check) {
3299
3549
  }
3300
3550
  }
3301
3551
  function brandActivationResult(check) {
3552
+ if (check.found && check.theme && check.theme.status !== "ok") {
3553
+ const label = versionGateLabel(check.theme);
3554
+ const why = check.theme.status === "below" ? `@axis-ds/theme ${label} \uC758 ThemeProvider \uAC00 \uB9C8\uC6B4\uD2B8 \uB54C \uC9C0\uC6C1\uB2C8\uB2E4` : `@axis-ds/theme \uBC84\uC804\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${label}). ${THEME_MARKUP_BRAND_MIN_VERSION} \uBBF8\uB9CC\uC774\uBA74 ThemeProvider \uAC00 \uB9C8\uC6B4\uD2B8 \uB54C \uC9C0\uC6C1\uB2C8\uB2E4`;
3555
+ return {
3556
+ name: "brand.activation",
3557
+ severity: "warn",
3558
+ message: `${check.found}\uC758 <html data-brand> \uB97C ${why} \u2192 @axis-ds/theme ${THEME_MARKUP_BRAND_MIN_VERSION} \uC774\uC0C1\uC73C\uB85C \uC62C\uB9AC\uAC70\uB098 setBrand("${check.brand}")`
3559
+ };
3560
+ }
3302
3561
  if (check.found) {
3303
3562
  return {
3304
3563
  name: "brand.activation",
@@ -3422,14 +3681,13 @@ import chalk9 from "chalk";
3422
3681
  import path13 from "path";
3423
3682
 
3424
3683
  // src/theme/theme-add.ts
3425
- import { accessSync, constants, existsSync as existsSync4, readFileSync as readFileSync3, realpathSync, unlinkSync, writeFileSync } from "fs";
3684
+ import { accessSync, constants, existsSync as existsSync4, readFileSync as readFileSync5, realpathSync, unlinkSync, writeFileSync } from "fs";
3426
3685
  import path12 from "path";
3427
3686
  var TOKENS_DEPENDENCY_RANGE = `^${TOKENS_DEPENDENCY_MIN_VERSION}`;
3428
3687
  var TAILWIND3_BASE_IMPORTS = [`${TOKENS_PACKAGE}/css`, `${TOKENS_PACKAGE}/css/shadcn`];
3429
- var THEME_PACKAGE = "@axis-ds/theme";
3430
3688
  var THEME_MIN_VERSION = "1.3.0";
3431
3689
  function readText(file) {
3432
- return existsSync4(file) ? readFileSync3(file, "utf8") : null;
3690
+ return existsSync4(file) ? readFileSync5(file, "utf8") : null;
3433
3691
  }
3434
3692
  function eolOf(text) {
3435
3693
  return text.includes("\r\n") ? "\r\n" : "\n";
@@ -3551,7 +3809,7 @@ function planThemeAdd(baseDirInput, brand) {
3551
3809
  let config;
3552
3810
  try {
3553
3811
  const parsed = JSON.parse(configText);
3554
- if (!isPlainObject2(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
3812
+ if (!isPlainObject(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
3555
3813
  config = parsed;
3556
3814
  } catch (err) {
3557
3815
  plan.errors.push({ kind: "invalid-config", message: err.message });
@@ -3563,7 +3821,7 @@ function planThemeAdd(baseDirInput, brand) {
3563
3821
  }
3564
3822
  plan.tokens = resolveTokens(baseDir);
3565
3823
  if (plan.tokens.status === "ok" && plan.tokens.indexPath) {
3566
- const data = JSON.parse(readFileSync3(plan.tokens.indexPath, "utf8"));
3824
+ const data = JSON.parse(readFileSync5(plan.tokens.indexPath, "utf8"));
3567
3825
  const entries = Array.isArray(data.brands) ? data.brands : [];
3568
3826
  const entry = entries.find((e) => e.name === brand);
3569
3827
  if (!entry) {
@@ -3585,7 +3843,7 @@ function planThemeAdd(baseDirInput, brand) {
3585
3843
  if (pkgText !== null) {
3586
3844
  try {
3587
3845
  const parsed = JSON.parse(pkgText);
3588
- if (!isPlainObject2(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
3846
+ if (!isPlainObject(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
3589
3847
  pkg = parsed;
3590
3848
  } catch (err) {
3591
3849
  plan.errors.push({ kind: "invalid-package-json", message: err.message });
@@ -3597,7 +3855,7 @@ function planThemeAdd(baseDirInput, brand) {
3597
3855
  const tailwind4 = tailwind.major !== void 0 && tailwind.major >= 4;
3598
3856
  const requiredBaseImports = tailwind4 ? [
3599
3857
  TOKENS_TAILWIND4_ENTRY,
3600
- ...TAILWIND4_COMPONENT_PACKAGES.filter((n) => pkg !== void 0 && hasDependency2(pkg, n) !== void 0).map(
3858
+ ...TAILWIND4_COMPONENT_PACKAGES.filter((n) => pkg !== void 0 && hasDependency(pkg, n) !== void 0).map(
3601
3859
  (n) => `${n}/tailwind.css`
3602
3860
  )
3603
3861
  ] : [...TAILWIND3_BASE_IMPORTS];
@@ -3614,7 +3872,7 @@ function planThemeAdd(baseDirInput, brand) {
3614
3872
  plan.writes = [];
3615
3873
  return plan;
3616
3874
  }
3617
- const before = readFileSync3(location.path, "utf8");
3875
+ const before = readFileSync5(location.path, "utf8");
3618
3876
  const imported = findBrandImports(before);
3619
3877
  const otherBrands = [...new Set(imported.filter((n) => n !== brand))];
3620
3878
  const brandAdded = !imported.includes(brand);
@@ -3651,7 +3909,7 @@ function planThemeAdd(baseDirInput, brand) {
3651
3909
  const content = inspectTailwindContent(baseDir);
3652
3910
  plan.tailwindConfig = {
3653
3911
  configFile: configFile2,
3654
- presetMissing: configFile2 === void 0 || !hasTokensPresetReference(readFileSync3(path12.join(baseDir, configFile2), "utf8")),
3912
+ presetMissing: configFile2 === void 0 || !hasTokensPresetReference(readFileSync5(path12.join(baseDir, configFile2), "utf8")),
3655
3913
  contentMissing: content?.targets.filter((t) => !t.covered) ?? [],
3656
3914
  contentUnknown: content !== null && (content.unreadable || content.dynamic)
3657
3915
  };
@@ -3664,12 +3922,12 @@ function planThemeAdd(baseDirInput, brand) {
3664
3922
  if (pkgText === null || pkg === void 0) {
3665
3923
  plan.dependency = { action: "no-package-json", upgrade, themeMissing: false, tokensAddCommand, themeAddCommand };
3666
3924
  } else {
3667
- const themeMissing = hasDependency2(pkg, THEME_PACKAGE) === void 0;
3668
- const declared = hasDependency2(pkg, TOKENS_PACKAGE);
3925
+ const themeMissing = hasDependency(pkg, THEME_PACKAGE) === void 0;
3926
+ const declared = hasDependency(pkg, TOKENS_PACKAGE);
3669
3927
  if (declared !== void 0) {
3670
3928
  plan.dependency = { action: "present", declaredRange: declared, upgrade, themeMissing, tokensAddCommand, themeAddCommand };
3671
3929
  } else {
3672
- const deps = isPlainObject2(pkg.dependencies) ? { ...pkg.dependencies } : {};
3930
+ const deps = isPlainObject(pkg.dependencies) ? { ...pkg.dependencies } : {};
3673
3931
  deps[TOKENS_PACKAGE] = TOKENS_DEPENDENCY_RANGE;
3674
3932
  const next = { ...pkg, dependencies: deps };
3675
3933
  plan.dependency = { action: "add", upgrade, themeMissing, tokensAddCommand, themeAddCommand };
@@ -3754,6 +4012,25 @@ function applyThemeAdd(plan) {
3754
4012
  }
3755
4013
 
3756
4014
  // src/theme/index.ts
4015
+ function importOffset(css, spec) {
4016
+ const escaped = spec.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4017
+ const m = new RegExp(`@import\\s+(?:url\\(\\s*)?["']${escaped}["']`).exec(css);
4018
+ return m ? m.index : -1;
4019
+ }
4020
+ function baseImportLines(after, spec, brandImportPath2, file) {
4021
+ if (spec.endsWith("/tailwind.css")) {
4022
+ return [` ${chalk9.green("\u2713")} ${file}: @import "${spec}"; \uCD94\uAC00(\uCEF4\uD3EC\uB10C\uD2B8 \uC2A4\uCE94 \uACBD\uB85C, \uC704\uCE58 \uBB34\uAD00)`];
4023
+ }
4024
+ const at = importOffset(after, spec);
4025
+ const brandAt = importOffset(after, brandImportPath2);
4026
+ if (brandAt === -1 || at !== -1 && at < brandAt) {
4027
+ return [` ${chalk9.green("\u2713")} ${file}: @import "${spec}"; \uCD94\uAC00(\uAE30\uBCF8 \uD1A0\uD070 CSS, \uBE0C\uB79C\uB4DC \uC55E)`];
4028
+ }
4029
+ return [
4030
+ ` ${chalk9.green("\u2713")} ${file}: @import "${spec}"; \uCD94\uAC00(\uAE30\uBCF8 \uD1A0\uD070 CSS)`,
4031
+ chalk9.yellow(` ! \uC774 \uC904\uC774 \uBE0C\uB79C\uB4DC import \uB4A4\uC5D0 \uB4E4\uC5B4\uAC14\uC2B5\uB2C8\uB2E4. \uBE0C\uB79C\uB4DC \uAC12\uC774 \uAE30\uBCF8 \uD1A0\uD070\uC5D0 \uB36E\uC774\uBBC0\uB85C @import "${brandImportPath2}"; \uC55E\uC73C\uB85C \uC62E\uAE30\uC138\uC694`)
4032
+ ];
4033
+ }
3757
4034
  function tokensInstallCommand(baseDir) {
3758
4035
  return addCommandFor(detectInstallCommand(baseDir), { [TOKENS_PACKAGE]: TOKENS_DEPENDENCY_RANGE });
3759
4036
  }
@@ -3941,8 +4218,9 @@ function renderThemeAdd(plan, written) {
3941
4218
  }
3942
4219
  const brandLine = `@import "${plan.importPath}";`;
3943
4220
  if (css?.action === "add" && css.file) {
4221
+ const after = plan.writes.find((w) => w.file === css.file)?.after ?? "";
3944
4222
  for (const spec of css.baseImports) {
3945
- lines.push(` ${chalk9.green("\u2713")} ${rel(plan, css.file)}: @import "${spec}"; \uCD94\uAC00(\uAE30\uBCF8 \uD1A0\uD070 CSS, \uBE0C\uB79C\uB4DC \uC55E)`);
4223
+ lines.push(...baseImportLines(after, spec, plan.importPath, rel(plan, css.file)));
3946
4224
  }
3947
4225
  if (css.brandAdded) lines.push(` ${chalk9.green("\u2713")} ${rel(plan, css.file)}: ${brandLine} \uCD94\uAC00`);
3948
4226
  else lines.push(` ${chalk9.gray("-")} ${rel(plan, css.file)}: \uBE0C\uB79C\uB4DC import \uAC00 \uC774\uBBF8 \uC788\uC5B4 \uAC74\uB108\uB700`);
@@ -4002,7 +4280,8 @@ function renderThemeAdd(plan, written) {
4002
4280
  lines.push("", chalk9.bold(`Tailwind \uC124\uC815 (${tw.configFile ?? "tailwind.config"}, \uD30C\uC77C\uC740 \uACE0\uCE58\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4)`));
4003
4281
  if (tw.presetMissing) {
4004
4282
  lines.push(
4005
- chalk9.yellow(` ! AXIS preset \uC774 \uC5C6\uC2B5\uB2C8\uB2E4. presets \uC5D0 \uB123\uC73C\uC138\uC694: presets: [require("${TOKENS_TAILWIND3_PRESET}")]`) + chalk9.gray(` (ESM \uC774\uBA74 import axisPreset from "${TOKENS_TAILWIND3_PRESET}")`)
4283
+ // WI-0072: CommonJS 는 모든 tokens 버전에서 동작하는 `.default` 형태로 안내합니다(1.6.2 이하의 bare require 는 preset 이 빠짐)
4284
+ chalk9.yellow(` ! AXIS preset \uC774 \uC5C6\uC2B5\uB2C8\uB2E4. presets \uC5D0 \uB123\uC73C\uC138\uC694: presets: [${TOKENS_TAILWIND3_CJS_REQUIRE}]`) + chalk9.gray(` (ESM \xB7 TypeScript \uC774\uBA74 import axisPreset from "${TOKENS_TAILWIND3_PRESET}" \uB4A4 presets: [axisPreset])`)
4006
4285
  );
4007
4286
  }
4008
4287
  for (const t of tw.contentMissing) {
@@ -4017,6 +4296,13 @@ function renderThemeAdd(plan, written) {
4017
4296
  lines.push("", chalk9.bold(`\uBE0C\uB79C\uB4DC \uCF1C\uAE30 (ThemeProvider \uB294 ${THEME_PACKAGE} ${THEME_MIN_VERSION} \uC774\uC0C1)`));
4018
4297
  if (act?.found) {
4019
4298
  lines.push(` ${chalk9.gray("-")} ${act.found} \uC5D0 \uBE0C\uB79C\uB4DC\uB97C \uCF1C\uB294 \uCF54\uB4DC(data-brand \xB7 setBrand \uB4F1)\uAC00 \uC788\uC2B5\uB2C8\uB2E4. "${plan.brand}" \uB85C \uCF1C\uB294\uC9C0 \uD655\uC778\uD558\uC138\uC694.`);
4299
+ if (act.markupWithProvider) {
4300
+ lines.push(
4301
+ chalk9.yellow(
4302
+ ` ! <html data-brand> \uC640 ThemeProvider \uB97C \uD568\uAED8 \uC4F0\uBA74 ${THEME_PACKAGE} ${THEME_MARKUP_BRAND_MIN_VERSION} \uC774\uC0C1\uC774\uC5B4\uC57C \uB9C8\uC6B4\uD2B8 \uB54C \uC9C0\uC6CC\uC9C0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC124\uCE58\uBCF8 \uD655\uC778: axis check`
4303
+ )
4304
+ );
4305
+ }
4020
4306
  } else {
4021
4307
  lines.push(
4022
4308
  ...providerExample(plan.brand).split("\n").map((l) => l ? ` ${l}` : ""),
@@ -4387,7 +4673,7 @@ async function fetchRegistryJson(url, options = {}) {
4387
4673
  }
4388
4674
 
4389
4675
  // src/init/init.ts
4390
- import { accessSync as accessSync2, constants as constants2, existsSync as existsSync6, lstatSync as lstatSync3, readFileSync as readFileSync4, realpathSync as realpathSync3, statSync as statSync4, writeFileSync as writeFileSync2 } from "fs";
4676
+ import { accessSync as accessSync2, constants as constants2, existsSync as existsSync6, lstatSync as lstatSync3, readFileSync as readFileSync6, realpathSync as realpathSync3, statSync as statSync4, writeFileSync as writeFileSync2 } from "fs";
4391
4677
  import path15 from "path";
4392
4678
  import chalk10 from "chalk";
4393
4679
  import fs12 from "fs-extra";
@@ -4644,7 +4930,7 @@ async function resolveInitAnswers(baseDirInput, tailwind4) {
4644
4930
  }
4645
4931
  function animationGuideLine(pkg, tailwind4, installCommand) {
4646
4932
  const name = tailwind4 ? ANIMATION_PLUGIN_TAILWIND4 : ANIMATION_PLUGIN_TAILWIND3;
4647
- if (pkg !== void 0 && (hasDependency2(pkg, ANIMATION_PLUGIN_TAILWIND3) !== void 0 || hasDependency2(pkg, ANIMATION_PLUGIN_TAILWIND4) !== void 0)) {
4933
+ if (pkg !== void 0 && (hasDependency(pkg, ANIMATION_PLUGIN_TAILWIND3) !== void 0 || hasDependency(pkg, ANIMATION_PLUGIN_TAILWIND4) !== void 0)) {
4648
4934
  return void 0;
4649
4935
  }
4650
4936
  const add = `${addCommandFor(installCommand, {}).trimEnd()} ${name}`;
@@ -4659,15 +4945,15 @@ var TAILWIND4_TOKENS_VERSION = TAILWIND4_MIN_AXIS_VERSION;
4659
4945
  var TAILWIND4_CONFLICT_LINE = " ! create-next-app \uAE30\uBCF8 globals.css \uC758 :root \xB7 @theme inline \xB7 @media (prefers-color-scheme: dark) \xB7 body \uBE14\uB85D\uC740 AXIS \uC640 \uAC19\uC740 \uC774\uB984(--background \xB7 --foreground \xB7 --color-background \xB7 --font-sans \xB7 --font-mono)\uC744 \uB2E4\uB978 \uAC12\uC73C\uB85C \uC815\uC758\uD569\uB2C8\uB2E4. \uC774 \uBE14\uB85D\uB4E4\uC744 \uC9C0\uC6B0\uC138\uC694.";
4660
4946
  function readPackageJsonSafe(baseDir) {
4661
4947
  try {
4662
- const text = readFileSync4(path15.join(baseDir, "package.json"), "utf8");
4948
+ const text = readFileSync6(path15.join(baseDir, "package.json"), "utf8");
4663
4949
  const parsed = JSON.parse(text.startsWith(BOM) ? text.slice(1) : text);
4664
- return isPlainObject2(parsed) ? parsed : void 0;
4950
+ return isPlainObject(parsed) ? parsed : void 0;
4665
4951
  } catch {
4666
4952
  return void 0;
4667
4953
  }
4668
4954
  }
4669
4955
  function tailwind4GuideLines(pkg, installCommand, globalCss, baseDir) {
4670
- const used = TAILWIND4_COMPONENT_PACKAGES.filter((name) => pkg !== void 0 && hasDependency2(pkg, name) !== void 0);
4956
+ const used = TAILWIND4_COMPONENT_PACKAGES.filter((name) => pkg !== void 0 && hasDependency(pkg, name) !== void 0);
4671
4957
  const lines = [
4672
4958
  `Tailwind 4: \uC804\uC5ED CSS(${globalCss}) \uB9E8 \uC704\uC5D0 \uB2E4\uC74C \uC904\uC744 \uB123\uC73C\uC138\uC694(\uD30C\uC77C\uC740 \uACE0\uCE58\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4).`,
4673
4959
  ' @import "tailwindcss";',
@@ -4680,7 +4966,7 @@ function tailwind4GuideLines(pkg, installCommand, globalCss, baseDir) {
4680
4966
  );
4681
4967
  }
4682
4968
  lines.push(TAILWIND4_CONFLICT_LINE);
4683
- if (pkg === void 0 || hasDependency2(pkg, TOKENS_PACKAGE) === void 0) {
4969
+ if (pkg === void 0 || hasDependency(pkg, TOKENS_PACKAGE) === void 0) {
4684
4970
  const add = addCommandFor(installCommand, { [TOKENS_PACKAGE]: `^${TAILWIND4_TOKENS_VERSION}` });
4685
4971
  lines.push(` ${TOKENS_PACKAGE} \uC124\uCE58: ${add}`);
4686
4972
  }
@@ -4743,7 +5029,7 @@ function planUtilsDependencies(baseDirInput) {
4743
5029
  if (!where.inside) return unwritable(`\uC2E4\uC81C \uC704\uCE58(${where.realPath})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`);
4744
5030
  let text;
4745
5031
  try {
4746
- text = readFileSync4(pkgFile, "utf8");
5032
+ text = readFileSync6(pkgFile, "utf8");
4747
5033
  } catch (err) {
4748
5034
  return unwritable(err.message);
4749
5035
  }
@@ -4752,7 +5038,7 @@ function planUtilsDependencies(baseDirInput) {
4752
5038
  let pkg;
4753
5039
  try {
4754
5040
  const parsed = JSON.parse(body);
4755
- if (!isPlainObject2(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
5041
+ if (!isPlainObject(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
4756
5042
  pkg = parsed;
4757
5043
  } catch (err) {
4758
5044
  return unwritable(`JSON \uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${err.message}`);
@@ -4762,14 +5048,14 @@ function planUtilsDependencies(baseDirInput) {
4762
5048
  plan.addCommand = addCommandFor(installCommand, plan.ranges);
4763
5049
  const missing = {};
4764
5050
  for (const [name, range] of Object.entries(plan.ranges)) {
4765
- const declared = hasDependency2(pkg, name);
5051
+ const declared = hasDependency(pkg, name);
4766
5052
  if (declared !== void 0) plan.present.push({ name, range: declared });
4767
5053
  else missing[name] = range;
4768
5054
  }
4769
5055
  plan.added = Object.keys(missing);
4770
5056
  plan.addCommand = addCommandFor(installCommand, plan.added.length > 0 ? missing : plan.ranges);
4771
5057
  if (plan.added.length === 0) return { ...plan, action: "present" };
4772
- if (pkg.dependencies !== void 0 && !isPlainObject2(pkg.dependencies)) {
5058
+ if (pkg.dependencies !== void 0 && !isPlainObject(pkg.dependencies)) {
4773
5059
  return unwritable("dependencies \uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
4774
5060
  }
4775
5061
  try {
@@ -4786,7 +5072,7 @@ function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile
4786
5072
  const w = plan.write;
4787
5073
  if (plan.action !== "add" || !w) return false;
4788
5074
  const baseDir = path15.resolve(baseDirInput);
4789
- const current = existsSync6(w.file) ? readFileSync4(w.file, "utf8") : null;
5075
+ const current = existsSync6(w.file) ? readFileSync6(w.file, "utf8") : null;
4790
5076
  if (current !== w.before) {
4791
5077
  throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
4792
5078
  }
@@ -4802,7 +5088,7 @@ function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile
4802
5088
  let restored;
4803
5089
  try {
4804
5090
  writeFile(w.file, w.before);
4805
- if (readFileSync4(w.file, "utf8") !== w.before) throw new Error("\uB418\uB3CC\uB9B0 \uB0B4\uC6A9\uC774 \uC6D0\uB798 \uB0B4\uC6A9\uACFC \uB2E4\uB985\uB2C8\uB2E4");
5091
+ if (readFileSync6(w.file, "utf8") !== w.before) throw new Error("\uB418\uB3CC\uB9B0 \uB0B4\uC6A9\uC774 \uC6D0\uB798 \uB0B4\uC6A9\uACFC \uB2E4\uB985\uB2C8\uB2E4");
4806
5092
  restored = "\uC6D0\uB798 \uB0B4\uC6A9\uC73C\uB85C \uB418\uB3CC\uB838\uC2B5\uB2C8\uB2E4";
4807
5093
  } catch (restoreErr) {
4808
5094
  restored = `\uC6D0\uB798 \uB0B4\uC6A9\uC73C\uB85C \uB418\uB3CC\uB9AC\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${restoreErr.message}). \uD30C\uC77C\uC774 \uC798\uB838\uAC70\uB098 \uBE44\uC5C8\uC744 \uC218 \uC788\uC73C\uB2C8 \uBC84\uC804 \uAD00\uB9AC \uB3C4\uAD6C \uB4F1\uC73C\uB85C \uBCF5\uAD6C\uD558\uC138\uC694`;
@@ -4840,7 +5126,7 @@ function reportDependencies(plan, log) {
4840
5126
  async function existingConfig(baseDir) {
4841
5127
  try {
4842
5128
  const parsed = await readAxisConfig(baseDir);
4843
- return isPlainObject2(parsed) ? parsed : null;
5129
+ return isPlainObject(parsed) ? parsed : null;
4844
5130
  } catch {
4845
5131
  return null;
4846
5132
  }
@@ -4913,7 +5199,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
4913
5199
  if (!target.isFile()) return { action: "reject", reason: `${shown} \uB9C1\uD06C \uB300\uC0C1(${real})\uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4` };
4914
5200
  let content2;
4915
5201
  try {
4916
- content2 = readFileSync4(utilsPath, "utf8");
5202
+ content2 = readFileSync6(utilsPath, "utf8");
4917
5203
  } catch (e) {
4918
5204
  return { action: "reject", reason: `${shown} \uB9C1\uD06C \uB300\uC0C1(${real})\uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
4919
5205
  }
@@ -4928,7 +5214,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
4928
5214
  if (!st.isFile()) return { action: "reject", reason: `${shown} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2C8\uB77C \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4` };
4929
5215
  let content;
4930
5216
  try {
4931
- content = readFileSync4(utilsPath, "utf8");
5217
+ content = readFileSync6(utilsPath, "utf8");
4932
5218
  } catch (e) {
4933
5219
  return { action: "reject", reason: `\uAE30\uC874 ${shown} \uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
4934
5220
  }
@@ -5129,12 +5415,12 @@ import chalk12 from "chalk";
5129
5415
  import prompts3 from "prompts";
5130
5416
 
5131
5417
  // ../axis-registry-core/src/add/add.ts
5132
- import { existsSync as existsSync8, readFileSync as readFileSync6, statSync as statSync5 } from "fs";
5418
+ import { existsSync as existsSync8, readFileSync as readFileSync8, statSync as statSync5 } from "fs";
5133
5419
  import path17 from "path";
5134
5420
  import fs13 from "fs-extra";
5135
5421
 
5136
5422
  // ../axis-registry-core/src/registry/bundled.ts
5137
- import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
5423
+ import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
5138
5424
  import path16 from "path";
5139
5425
  import { fileURLToPath } from "url";
5140
5426
  function findBundledRegistryDir(moduleUrl = import.meta.url) {
@@ -5148,7 +5434,7 @@ function readBundledJson(dir, fileName) {
5148
5434
  const file = path16.join(dir, fileName);
5149
5435
  let text;
5150
5436
  try {
5151
- text = readFileSync5(file, "utf8");
5437
+ text = readFileSync7(file, "utf8");
5152
5438
  } catch {
5153
5439
  throw new Error(`\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 ${fileName} \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4(${dir})`);
5154
5440
  }
@@ -5336,7 +5622,7 @@ function createPinnedFetch(options = {}) {
5336
5622
  const judge = options.judge ?? blockedAddressReason;
5337
5623
  const send = options.request ?? httpsRequest;
5338
5624
  const maxBytes = options.maxBytes ?? PINNED_FETCH_MAX_BYTES;
5339
- return (input, init) => new Promise((resolve3, reject) => {
5625
+ return (input, init) => new Promise((resolve4, reject) => {
5340
5626
  let url;
5341
5627
  try {
5342
5628
  url = new URL(input);
@@ -5377,7 +5663,7 @@ function createPinnedFetch(options = {}) {
5377
5663
  if (failed) return;
5378
5664
  const body = Buffer.concat(chunks).toString("utf8");
5379
5665
  const status = res.statusCode ?? 0;
5380
- resolve3({ ok: status >= 200 && status < 300, status, text: async () => body });
5666
+ resolve4({ ok: status >= 200 && status < 300, status, text: async () => body });
5381
5667
  });
5382
5668
  }
5383
5669
  );
@@ -5863,9 +6149,9 @@ function missingDependencies(root, items) {
5863
6149
  const installCommand = detectInstallCommand(root);
5864
6150
  let pkg;
5865
6151
  try {
5866
- const text = readFileSync6(path17.join(root, "package.json"), "utf8").replace(/^\uFEFF/, "");
6152
+ const text = readFileSync8(path17.join(root, "package.json"), "utf8").replace(/^\uFEFF/, "");
5867
6153
  const parsed = JSON.parse(text);
5868
- pkg = isPlainObject2(parsed) ? parsed : void 0;
6154
+ pkg = isPlainObject(parsed) ? parsed : void 0;
5869
6155
  } catch {
5870
6156
  pkg = void 0;
5871
6157
  }
@@ -5874,7 +6160,7 @@ function missingDependencies(root, items) {
5874
6160
  for (const item of items) {
5875
6161
  for (const dep of item.dependencies) {
5876
6162
  const name = dependencyName(dep);
5877
- if (pkg !== void 0 && hasDependency2(pkg, name) !== void 0) continue;
6163
+ if (pkg !== void 0 && hasDependency(pkg, name) !== void 0) continue;
5878
6164
  if (name in specs) continue;
5879
6165
  const explicit = dep.length > name.length ? dep.slice(name.length + 1) : void 0;
5880
6166
  specs[name] = explicit ?? ranges[name];
@@ -5984,7 +6270,7 @@ async function runAdd(cwd, requested, options, ctx) {
5984
6270
  continue;
5985
6271
  }
5986
6272
  try {
5987
- existing.set(file, readFileSync6(file.target, "utf8"));
6273
+ existing.set(file, readFileSync8(file.target, "utf8"));
5988
6274
  } catch (e) {
5989
6275
  readErrors.push(
5990
6276
  `${file.item.name}: \uAE30\uC874 \uD30C\uC77C ${rel2(root, file.target)} \uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${e.code ?? e.message})`