@axis-ds/cli 1.7.0 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- MonetClient
4
- } from "./chunk-LVMDBOXD.js";
3
+ GLOBAL_CSS_CANDIDATES,
4
+ MonetClient,
5
+ ROOT_LAYOUT_FILES,
6
+ addCommandFor,
7
+ addCommandPrefix,
8
+ compareExactVersions,
9
+ declaredDependency,
10
+ detectInstallCommand,
11
+ detectProjectPaths,
12
+ findInstalledPackage,
13
+ hasDependency,
14
+ isPlainObject,
15
+ isPnpProject,
16
+ projectFileExists,
17
+ resolveBaseDir,
18
+ runScriptCommand,
19
+ workspaceRootPackage,
20
+ workspaceRunCommand
21
+ } from "./chunk-YYSEFWYD.js";
5
22
  import {
6
23
  V0Client
7
24
  } from "./chunk-2PNCUPCG.js";
@@ -489,11 +506,11 @@ var ShadcnCollector = class extends BaseCollector {
489
506
  /**
490
507
  * 파일 타입 추론
491
508
  */
492
- getFileType(path18) {
493
- if (path18.includes("hook") || path18.startsWith("use")) return "hook";
494
- if (path18.includes("util") || path18.includes("lib")) return "util";
495
- if (path18.endsWith(".css")) return "style";
496
- if (path18.endsWith(".d.ts") || path18.includes("types")) return "type";
509
+ getFileType(path17) {
510
+ if (path17.includes("hook") || path17.startsWith("use")) return "hook";
511
+ if (path17.includes("util") || path17.includes("lib")) return "util";
512
+ if (path17.endsWith(".css")) return "style";
513
+ if (path17.endsWith(".d.ts") || path17.includes("types")) return "type";
497
514
  return "component";
498
515
  }
499
516
  };
@@ -1810,7 +1827,7 @@ import ora5 from "ora";
1810
1827
 
1811
1828
  // src/template/template-apply.ts
1812
1829
  import fs8 from "fs-extra";
1813
- import path9 from "path";
1830
+ import path8 from "path";
1814
1831
  import chalk5 from "chalk";
1815
1832
  import ora3 from "ora";
1816
1833
 
@@ -1907,154 +1924,10 @@ async function readAxisConfig(baseDir) {
1907
1924
  }
1908
1925
 
1909
1926
  // ../axis-registry-core/src/template/tailwind-core.ts
1910
- import { existsSync as existsSync2, lstatSync, readdirSync, readFileSync as readFileSync2 } from "fs";
1911
- import { extname, join, resolve } from "path";
1912
-
1913
- // ../axis-registry-core/src/project.ts
1914
- import { existsSync, readFileSync, statSync } from "fs";
1915
- import path8 from "path";
1916
- function detectInstallCommand(baseDir) {
1917
- if (existsSync(path8.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
1918
- if (existsSync(path8.join(baseDir, "yarn.lock"))) return "yarn install";
1919
- if (existsSync(path8.join(baseDir, "package-lock.json"))) return "npm install";
1920
- return "pnpm install";
1921
- }
1922
- function hasDependency(pkg, name) {
1923
- for (const field of ["dependencies", "devDependencies"]) {
1924
- const deps = pkg[field];
1925
- if (typeof deps === "object" && deps !== null && name in deps) {
1926
- return String(deps[name]);
1927
- }
1928
- }
1929
- return void 0;
1930
- }
1931
- function isPlainObject(value) {
1932
- return typeof value === "object" && value !== null && !Array.isArray(value);
1933
- }
1934
- function addCommandFor(installCommand, deps) {
1935
- const specs = Object.entries(deps).map(([name, range]) => `"${name}@${range}"`).join(" ");
1936
- if (installCommand.startsWith("yarn")) return `yarn add ${specs}`;
1937
- if (installCommand.startsWith("npm")) return `npm install ${specs}`;
1938
- return `pnpm add ${specs}`;
1939
- }
1940
- var GLOBAL_CSS_CANDIDATES = [
1941
- "app/globals.css",
1942
- "src/app/globals.css",
1943
- "styles/globals.css",
1944
- "src/styles/globals.css",
1945
- "globals.css"
1946
- ];
1947
- var TAILWIND_CONFIG_CANDIDATES = [
1948
- "tailwind.config.ts",
1949
- "tailwind.config.js",
1950
- "tailwind.config.mjs",
1951
- "tailwind.config.cjs"
1952
- ];
1953
- function isFile(file) {
1954
- try {
1955
- return statSync(file).isFile();
1956
- } catch {
1957
- return false;
1958
- }
1959
- }
1960
- function isDirectory(dir) {
1961
- try {
1962
- return statSync(dir).isDirectory();
1963
- } catch {
1964
- return false;
1965
- }
1966
- }
1967
- function findFirstFile(baseDir, candidates) {
1968
- return candidates.find((c) => isFile(path8.join(baseDir, c)));
1969
- }
1970
- function detectProjectPaths(baseDirInput) {
1971
- const baseDir = path8.resolve(baseDirInput);
1972
- const hasSrc = isDirectory(path8.join(baseDir, "src"));
1973
- const css = findFirstFile(baseDir, GLOBAL_CSS_CANDIDATES);
1974
- const tw = findFirstFile(baseDir, TAILWIND_CONFIG_CANDIDATES);
1975
- return {
1976
- componentsDir: hasSrc ? "./src/components/ui" : "./components/ui",
1977
- globalCss: css !== void 0 ? `./${css}` : hasSrc ? "./src/app/globals.css" : "./app/globals.css",
1978
- globalCssSource: css !== void 0 ? "found" : "default",
1979
- tailwindConfig: tw !== void 0 ? `./${tw}` : "./tailwind.config.ts",
1980
- tailwindConfigSource: tw !== void 0 ? "found" : "default"
1981
- };
1982
- }
1983
- function projectFileExists(baseDir, relPath) {
1984
- return isFile(path8.resolve(baseDir, relPath));
1985
- }
1986
- var ROOT_LAYOUT_FILES = [
1987
- "app/layout.tsx",
1988
- "app/layout.jsx",
1989
- "app/layout.js",
1990
- "src/app/layout.tsx",
1991
- "src/app/layout.jsx",
1992
- "src/app/layout.js",
1993
- "pages/_app.tsx",
1994
- "pages/_app.jsx",
1995
- "pages/_document.tsx",
1996
- "pages/_document.jsx",
1997
- "src/pages/_app.tsx",
1998
- "src/pages/_app.jsx",
1999
- "src/pages/_document.tsx",
2000
- "src/pages/_document.jsx"
2001
- ];
2002
- function exactVersionOf(version) {
2003
- if (typeof version !== "string") return void 0;
2004
- const v = version.trim();
2005
- if (!/^v?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(v) || /^v?0\.0\.0-/.test(v)) return void 0;
2006
- return v;
2007
- }
2008
- function findInstalledPackage(baseDirInput, name) {
2009
- let dir = path8.resolve(baseDirInput);
2010
- for (; ; ) {
2011
- const pkgDir = path8.join(dir, "node_modules", ...name.split("/"));
2012
- const file = path8.join(pkgDir, "package.json");
2013
- if (isFile(file)) {
2014
- let version;
2015
- try {
2016
- const parsed = JSON.parse(readFileSync(file, "utf8"));
2017
- version = isPlainObject(parsed) ? exactVersionOf(parsed.version) : void 0;
2018
- } catch {
2019
- version = void 0;
2020
- }
2021
- return { dir: pkgDir, version };
2022
- }
2023
- const parent = path8.dirname(dir);
2024
- if (parent === dir) return void 0;
2025
- dir = parent;
2026
- }
2027
- }
2028
- function isPnpProject(baseDirInput) {
2029
- let dir = path8.resolve(baseDirInput);
2030
- for (; ; ) {
2031
- if (isFile(path8.join(dir, ".pnp.cjs")) || isFile(path8.join(dir, ".pnp.js"))) return true;
2032
- const parent = path8.dirname(dir);
2033
- if (parent === dir) return false;
2034
- dir = parent;
2035
- }
2036
- }
2037
- function compareExactVersions(a, b) {
2038
- const parse = (v) => {
2039
- const m = /^v?(\d+)\.(\d+)\.(\d+)(-[0-9A-Za-z.-]+)?/.exec(v.trim());
2040
- return m ? { core: [Number(m[1]), Number(m[2]), Number(m[3])], pre: m[4] !== void 0 } : void 0;
2041
- };
2042
- const x = parse(a);
2043
- const y = parse(b);
2044
- if (!x || !y) return void 0;
2045
- for (let i = 0; i < 3; i++) if (x.core[i] !== y.core[i]) return x.core[i] - y.core[i];
2046
- return Number(y.pre) - Number(x.pre);
2047
- }
2048
-
2049
- // ../axis-registry-core/src/template/tailwind-core.ts
2050
- function hasDependency2(pkg, name) {
2051
- for (const field of ["dependencies", "devDependencies"]) {
2052
- const deps = pkg[field];
2053
- if (typeof deps === "object" && deps !== null && name in deps) {
2054
- return String(deps[name]);
2055
- }
2056
- }
2057
- return void 0;
1927
+ import { existsSync, lstatSync, readdirSync, readFileSync, realpathSync } from "fs";
1928
+ import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "path";
1929
+ function declaredRange(baseDir, pkg, name) {
1930
+ return declaredDependency(baseDir, pkg, name)?.range;
2058
1931
  }
2059
1932
  function isPlainObject2(value) {
2060
1933
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -2130,8 +2003,8 @@ function majorFromVersion(version) {
2130
2003
  return Number(m[1]);
2131
2004
  }
2132
2005
  function detectTailwind(baseDirInput, pkg) {
2133
- const baseDir = resolve(baseDirInput);
2134
- const declared = pkg ? hasDependency2(pkg, "tailwindcss") : void 0;
2006
+ const baseDir = resolveBaseDir(baseDirInput);
2007
+ const declared = pkg ? declaredRange(baseDir, pkg, "tailwindcss") : void 0;
2135
2008
  const bounds = declared !== void 0 ? tailwindMajorBounds(declared) : void 0;
2136
2009
  const declaredMajor = bounds?.lower;
2137
2010
  const version = isPnpProject(baseDir) ? void 0 : findInstalledPackage(baseDir, "tailwindcss")?.version;
@@ -2182,13 +2055,13 @@ function findTokensCssImport(css) {
2182
2055
  var TOKENS_CSS_JS_IMPORT = /(?:\bimport\s+|\bfrom\s+|\brequire\s*\(\s*)(["'])(@axis-ds\/tokens\/css(?:\/shadcn|\/tailwind4)?)\1/;
2183
2056
  var AXIS_VARIABLE_DEFINITION = /(?<![\w-])--axis-[\w-]+\s*:/;
2184
2057
  function findLayoutTokensCssImport(baseDirInput) {
2185
- const baseDir = resolve(baseDirInput);
2058
+ const baseDir = resolveBaseDir(baseDirInput);
2186
2059
  for (const candidate of ROOT_LAYOUT_FILES) {
2187
2060
  const file = join(baseDir, candidate);
2188
- if (!existsSync2(file)) continue;
2061
+ if (!existsSync(file)) continue;
2189
2062
  let text;
2190
2063
  try {
2191
- text = readFileSync2(file, "utf8");
2064
+ text = readFileSync(file, "utf8");
2192
2065
  } catch {
2193
2066
  continue;
2194
2067
  }
@@ -2198,11 +2071,11 @@ function findLayoutTokensCssImport(baseDirInput) {
2198
2071
  return void 0;
2199
2072
  }
2200
2073
  function checkGlobalsCss(baseDirInput) {
2201
- const baseDir = resolve(baseDirInput);
2074
+ const baseDir = resolveBaseDir(baseDirInput);
2202
2075
  for (const candidate of TAILWIND_CSS_CANDIDATES) {
2203
2076
  const file = join(baseDir, candidate);
2204
- if (!existsSync2(file)) continue;
2205
- const content = readFileSync2(file, "utf8");
2077
+ if (!existsSync(file)) continue;
2078
+ const content = readFileSync(file, "utf8");
2206
2079
  const css = stripCssComments(content);
2207
2080
  const imported = findTokensCssImport(content);
2208
2081
  let pass;
@@ -2290,11 +2163,11 @@ function installedAxisVersion(baseDir, name) {
2290
2163
  }
2291
2164
  function axisPackagesBelowTailwind4(pkg, baseDirInput) {
2292
2165
  if (!pkg) return [];
2293
- const baseDir = baseDirInput !== void 0 ? resolve(baseDirInput) : void 0;
2166
+ const baseDir = baseDirInput !== void 0 ? resolveBaseDir(baseDirInput) : void 0;
2294
2167
  const out = [];
2295
2168
  const min = lowerOf(TAILWIND4_MIN_AXIS_VERSION);
2296
2169
  for (const name of TAILWIND4_AXIS_PACKAGES) {
2297
- const range = hasDependency2(pkg, name);
2170
+ const range = baseDir !== void 0 ? declaredRange(baseDir, pkg, name) : hasDependency(pkg, name);
2298
2171
  if (range === void 0 || range.trim().startsWith("workspace:")) continue;
2299
2172
  const installed = baseDir !== void 0 ? installedAxisVersion(baseDir, name) : void 0;
2300
2173
  const installedLower = installed !== void 0 ? lowerOf(installed) : void 0;
@@ -2434,7 +2307,7 @@ function isCommonJsConfig(file, source) {
2434
2307
  return extname(file) === ".cjs" || /\bmodule\.exports\b/.test(source);
2435
2308
  }
2436
2309
  function packageVersionGate(baseDirInput, pkg, name, min) {
2437
- const baseDir = resolve(baseDirInput);
2310
+ const baseDir = resolveBaseDir(baseDirInput);
2438
2311
  if (!isPnpProject(baseDir)) {
2439
2312
  const installed = findInstalledPackage(baseDir, name)?.version;
2440
2313
  if (installed !== void 0) {
@@ -2442,7 +2315,7 @@ function packageVersionGate(baseDirInput, pkg, name, min) {
2442
2315
  if (cmp !== void 0) return { status: cmp >= 0 ? "ok" : "below", source: "installed", value: installed };
2443
2316
  }
2444
2317
  }
2445
- const declared = pkg ? hasDependency2(pkg, name) : void 0;
2318
+ const declared = pkg ? declaredRange(baseDir, pkg, name) : void 0;
2446
2319
  if (declared !== void 0) {
2447
2320
  const atLeast = rangeLowerAtLeast(declared, min);
2448
2321
  if (atLeast !== void 0) return { status: atLeast ? "ok" : "below", source: "declared", value: declared };
@@ -2457,18 +2330,18 @@ function versionGateLabel(gate) {
2457
2330
  }
2458
2331
  function readPackageJson(baseDir) {
2459
2332
  try {
2460
- const parsed = JSON.parse(readFileSync2(join(baseDir, "package.json"), "utf8"));
2333
+ const parsed = JSON.parse(readFileSync(join(baseDir, "package.json"), "utf8"));
2461
2334
  return isPlainObject2(parsed) ? parsed : void 0;
2462
2335
  } catch {
2463
2336
  return void 0;
2464
2337
  }
2465
2338
  }
2466
- function tailwind4Issues(css, pkg, versions) {
2339
+ function tailwind4Issues(css, pkg, versions, baseDir) {
2467
2340
  const issues = [];
2468
2341
  const hasEntry = hasTokensTailwind4Import(css);
2469
2342
  if (!hasEntry) issues.push(`AXIS \uD1A0\uD070 \uC9C4\uC785\uC810\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${TOKENS_TAILWIND4_IMPORT_LINE}`);
2470
2343
  const missing = TAILWIND4_COMPONENT_PACKAGES.filter(
2471
- (name) => pkg !== void 0 && hasDependency2(pkg, name) !== void 0 && !hasComponentTailwindImport(css, name) && !hasComponentSource(css, name)
2344
+ (name) => declaredRange(baseDir, pkg, name) !== void 0 && !hasComponentTailwindImport(css, name) && !hasComponentSource(css, name)
2472
2345
  );
2473
2346
  if (missing.length > 0) {
2474
2347
  issues.push(`\uCEF4\uD3EC\uB10C\uD2B8 \uC2A4\uCE94 \uACBD\uB85C(tailwind.css)\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${missing.map(componentTailwindImportLine).join(" ")}`);
@@ -2488,15 +2361,15 @@ function tailwind4Issues(css, pkg, versions) {
2488
2361
  return issues;
2489
2362
  }
2490
2363
  function checkTailwindSetup(baseDirInput) {
2491
- const baseDir = resolve(baseDirInput);
2364
+ const baseDir = resolveBaseDir(baseDirInput);
2492
2365
  const pkg = readPackageJson(baseDir);
2493
2366
  const tailwind = detectTailwind(baseDir, pkg);
2494
2367
  if (tailwind.major !== void 0 && tailwind.major >= 4) {
2495
2368
  const label = `Tailwind ${tailwind.major}`;
2496
2369
  for (const candidate of TAILWIND_CSS_CANDIDATES) {
2497
2370
  const file = join(baseDir, candidate);
2498
- if (!existsSync2(file)) continue;
2499
- const css = readFileSync2(file, "utf8");
2371
+ if (!existsSync(file)) continue;
2372
+ const css = readFileSync(file, "utf8");
2500
2373
  if (!hasTailwindImport(css)) {
2501
2374
  return {
2502
2375
  name: "tailwind.config",
@@ -2505,7 +2378,7 @@ function checkTailwindSetup(baseDirInput) {
2505
2378
  };
2506
2379
  }
2507
2380
  const versions = axisPackagesBelowTailwind4(pkg, baseDir);
2508
- const issues = tailwind4Issues(css, pkg, versions);
2381
+ const issues = tailwind4Issues(css, pkg, versions, baseDir);
2509
2382
  if (issues.length > 0) {
2510
2383
  return {
2511
2384
  name: "tailwind.config",
@@ -2526,9 +2399,9 @@ function checkTailwindSetup(baseDirInput) {
2526
2399
  };
2527
2400
  }
2528
2401
  for (const file of TAILWIND_CONFIG_FILES) {
2529
- const path18 = join(baseDir, file);
2530
- if (!existsSync2(path18)) continue;
2531
- const content = readFileSync2(path18, "utf8");
2402
+ const path17 = join(baseDir, file);
2403
+ if (!existsSync(path17)) continue;
2404
+ const content = readFileSync(path17, "utf8");
2532
2405
  if (hasTokensPresetReference(content)) {
2533
2406
  const code = stripJsComments(content);
2534
2407
  if (isCommonJsConfig(file, code) && hasBareCjsPresetRequire(code)) {
@@ -2555,7 +2428,7 @@ function checkTailwindSetup(baseDirInput) {
2555
2428
  }
2556
2429
  function readAxisConfigLike(baseDir) {
2557
2430
  try {
2558
- const parsed = JSON.parse(readFileSync2(join(baseDir, "axis.config.json"), "utf8"));
2431
+ const parsed = JSON.parse(readFileSync(join(baseDir, "axis.config.json"), "utf8"));
2559
2432
  return isPlainObject2(parsed) ? parsed : void 0;
2560
2433
  } catch {
2561
2434
  return void 0;
@@ -2592,6 +2465,93 @@ function contentGlobToRegExp(glob) {
2592
2465
  }
2593
2466
  return new RegExp(`^${re}$`);
2594
2467
  }
2468
+ function leadingParentSegments(p) {
2469
+ const s = p.trim().replace(/\\/g, "/").replace(/^\.\//, "");
2470
+ return (/^(?:\.\.\/)*/.exec(s)?.[0].length ?? 0) / 3;
2471
+ }
2472
+ function isAbsoluteGlob(glob) {
2473
+ const t = glob.trim();
2474
+ return t.startsWith("/") || /^[A-Za-z]:[\\/]/.test(t);
2475
+ }
2476
+ var MAX_BRACE_EXPANSION = 256;
2477
+ function expandBraces(glob) {
2478
+ const open = glob.indexOf("{");
2479
+ if (open === -1) return [glob];
2480
+ let depth = 0;
2481
+ let close = -1;
2482
+ const commas = [];
2483
+ for (let i = open; i < glob.length; i++) {
2484
+ const c = glob[i];
2485
+ if (c === "{") depth++;
2486
+ else if (c === "}") {
2487
+ depth--;
2488
+ if (depth === 0) {
2489
+ close = i;
2490
+ break;
2491
+ }
2492
+ } else if (c === "," && depth === 1) commas.push(i);
2493
+ }
2494
+ const head = glob.slice(0, open + 1);
2495
+ if (close === -1 || commas.length === 0) {
2496
+ return expandBraces(glob.slice(open + 1))?.map((r) => head + r);
2497
+ }
2498
+ const parts = [];
2499
+ let from = open + 1;
2500
+ for (const c of [...commas, close]) {
2501
+ parts.push(glob.slice(from, c));
2502
+ from = c + 1;
2503
+ }
2504
+ const prefix = glob.slice(0, open);
2505
+ const suffix = glob.slice(close + 1);
2506
+ const out = [];
2507
+ for (const part of parts) {
2508
+ const expanded = expandBraces(prefix + part + suffix);
2509
+ if (expanded === void 0) return void 0;
2510
+ out.push(...expanded);
2511
+ if (out.length > MAX_BRACE_EXPANSION) return void 0;
2512
+ }
2513
+ return out;
2514
+ }
2515
+ function realpathPosix(p) {
2516
+ let cur = p;
2517
+ const tail = [];
2518
+ for (let i = 0; i < 64; i++) {
2519
+ try {
2520
+ return [realpathSync(cur), ...tail].join(sep).split(sep).join("/");
2521
+ } catch {
2522
+ const parent = dirname(cur);
2523
+ if (parent === cur) return void 0;
2524
+ tail.unshift(basename(cur));
2525
+ cur = parent;
2526
+ }
2527
+ }
2528
+ return void 0;
2529
+ }
2530
+ function contentGlobBranchCovers(glob, sample, baseDir) {
2531
+ if (isAbsoluteGlob(glob)) {
2532
+ const re = contentGlobToRegExp(glob.trim().replace(/\\/g, "/"));
2533
+ const absSample = resolve(baseDir, sample);
2534
+ if (re.test(absSample.split(sep).join("/"))) return true;
2535
+ const real = realpathPosix(absSample);
2536
+ return real !== void 0 && re.test(real);
2537
+ }
2538
+ return leadingParentSegments(glob) === leadingParentSegments(sample) && contentGlobToRegExp(glob).test(sample);
2539
+ }
2540
+ function contentGlobCovers(glob, sample, baseDirInput) {
2541
+ const baseDir = resolveBaseDir(baseDirInput);
2542
+ const branches = expandBraces(glob.trim()) ?? [glob];
2543
+ return branches.some((b) => contentGlobBranchCovers(b, sample, baseDir));
2544
+ }
2545
+ var CONTENT_PARENT_PATH_NOTE = "\uC0C1\uC704 \uACBD\uB85C\uB294 Tailwind 3 \uAC00 \uBE4C\uB4DC\uB97C \uC2E4\uD589\uD55C \uB514\uB809\uD130\uB9AC \uAE30\uC900\uC73C\uB85C \uD480\uB824\uC694. \uBAA8\uB178\uB808\uD3EC \uB8E8\uD2B8 \uB4F1 \uC571 \uB514\uB809\uD130\uB9AC \uBC16\uC5D0\uC11C \uBE4C\uB4DC\uD558\uBA74 content: { relative: true, files: [...] } \uB85C \uC124\uC815 \uD30C\uC77C \uAE30\uC900\uC73C\uB85C \uBC14\uAFB8\uC138\uC694";
2546
+ function packageContentTarget(baseDir, name) {
2547
+ const found = isPnpProject(baseDir) ? void 0 : findInstalledPackage(baseDir, name);
2548
+ const rel3 = found === void 0 ? void 0 : relative(baseDir, found.dir);
2549
+ const relDir = rel3 === void 0 || rel3 === "" || isAbsolute(rel3) ? `node_modules/${name}` : rel3.split(sep).join("/");
2550
+ return {
2551
+ sample: `${relDir}/dist/index.js`,
2552
+ suggest: `${relDir.startsWith("../") ? "" : "./"}${relDir}/dist/**/*.{js,mjs}`
2553
+ };
2554
+ }
2595
2555
  function balancedSlice(src, start) {
2596
2556
  const open = src[start];
2597
2557
  const close = open === "[" ? "]" : "}";
@@ -2639,11 +2599,11 @@ function normalizeRel(p) {
2639
2599
  return s;
2640
2600
  }
2641
2601
  function inspectTailwindContent(baseDirInput) {
2642
- const baseDir = resolve(baseDirInput);
2602
+ const baseDir = resolveBaseDir(baseDirInput);
2643
2603
  const pkg = readPackageJson(baseDir);
2644
2604
  const tailwind = detectTailwind(baseDir, pkg);
2645
2605
  if (tailwind.major !== void 0 && tailwind.major >= 4) return null;
2646
- const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync2(join(baseDir, f)));
2606
+ const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync(join(baseDir, f)));
2647
2607
  if (configFile === void 0) return null;
2648
2608
  const targets = [];
2649
2609
  const componentsDir = readAxisConfigLike(baseDir)?.componentsDir;
@@ -2652,18 +2612,18 @@ function inspectTailwindContent(baseDirInput) {
2652
2612
  targets.push({ label: `componentsDir(${componentsDir})`, sample: `${rel3}/button.tsx`, suggest: `./${rel3}/**/*.{ts,tsx}` });
2653
2613
  }
2654
2614
  for (const name of TAILWIND4_COMPONENT_PACKAGES) {
2655
- if (pkg !== void 0 && hasDependency2(pkg, name) !== void 0) {
2656
- targets.push({ label: name, sample: `node_modules/${name}/dist/index.js`, suggest: `./node_modules/${name}/dist/**/*.{js,mjs}` });
2615
+ if (declaredRange(baseDir, pkg, name) !== void 0) {
2616
+ targets.push({ label: name, ...packageContentTarget(baseDir, name) });
2657
2617
  }
2658
2618
  }
2659
2619
  if (targets.length === 0) return null;
2660
- const read = readTailwindContent(readFileSync2(join(baseDir, configFile), "utf8"));
2661
- const patterns = (read?.globs ?? []).filter((g) => !g.trim().startsWith("!")).map(contentGlobToRegExp);
2620
+ const read = readTailwindContent(readFileSync(join(baseDir, configFile), "utf8"));
2621
+ const globs = (read?.globs ?? []).filter((g) => !g.trim().startsWith("!"));
2662
2622
  return {
2663
2623
  configFile,
2664
2624
  unreadable: read === void 0,
2665
2625
  dynamic: read?.dynamic ?? false,
2666
- targets: targets.map((t) => ({ ...t, covered: patterns.some((re) => re.test(t.sample)) }))
2626
+ targets: targets.map((t) => ({ ...t, covered: globs.some((g) => contentGlobCovers(g, t.sample, baseDir)) }))
2667
2627
  };
2668
2628
  }
2669
2629
  function checkTailwindContent(baseDir) {
@@ -2678,17 +2638,18 @@ function checkTailwindContent(baseDir) {
2678
2638
  };
2679
2639
  }
2680
2640
  const list = missing.map((t) => `${t.label} \u2192 "${t.suggest}"`).join(" \xB7 ");
2641
+ const note = missing.some((t) => t.suggest.startsWith("../")) ? ` (${CONTENT_PARENT_PATH_NOTE})` : "";
2681
2642
  if (r.unreadable || r.dynamic) {
2682
2643
  return {
2683
2644
  name: "tailwind.content",
2684
2645
  severity: "warn",
2685
- message: `${r.configFile}\uC758 content \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${list}`
2646
+ message: `${r.configFile}\uC758 content \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${list}${note}`
2686
2647
  };
2687
2648
  }
2688
2649
  return {
2689
2650
  name: "tailwind.content",
2690
2651
  severity: "fail",
2691
- message: `${r.configFile}\uC758 content \uAC00 \uCEF4\uD3EC\uB10C\uD2B8 \uACBD\uB85C\uB97C \uB36E\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uD074\uB798\uC2A4\uAC00 \uC0DD\uC131\uB418\uC9C0 \uC54A\uC74C): ${list}`
2652
+ message: `${r.configFile}\uC758 content \uAC00 \uCEF4\uD3EC\uB10C\uD2B8 \uACBD\uB85C\uB97C \uB36E\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uD074\uB798\uC2A4\uAC00 \uC0DD\uC131\uB418\uC9C0 \uC54A\uC74C): ${list}${note}`
2692
2653
  };
2693
2654
  }
2694
2655
  var ANIMATION_PLUGIN_TAILWIND3 = "tailwindcss-animate";
@@ -2722,24 +2683,24 @@ function componentsUseAnimation(baseDir, componentsDir) {
2722
2683
  if (st.isDirectory()) {
2723
2684
  if (name !== "node_modules" && depth < ANIMATION_SCAN_DEPTH_LIMIT) stack.push([p, depth + 1]);
2724
2685
  } else if (st.isFile() && st.size <= ANIMATION_SCAN_FILE_BYTES && /\.(tsx|ts|jsx|js)$/.test(name)) {
2725
- if (/\banimate-(?:in|out)\b/.test(readFileSync2(p, "utf8"))) return true;
2686
+ if (/\banimate-(?:in|out)\b/.test(readFileSync(p, "utf8"))) return true;
2726
2687
  }
2727
2688
  }
2728
2689
  }
2729
2690
  return false;
2730
2691
  }
2731
2692
  function checkAnimationPlugin(baseDirInput) {
2732
- const baseDir = resolve(baseDirInput);
2693
+ const baseDir = resolveBaseDir(baseDirInput);
2733
2694
  const pkg = readPackageJson(baseDir);
2734
2695
  const config = readAxisConfigLike(baseDir);
2735
- const declared = pkg !== void 0 && hasDependency2(pkg, "@axis-ds/ui-react") !== void 0;
2696
+ const declared = declaredRange(baseDir, pkg, "@axis-ds/ui-react") !== void 0;
2736
2697
  const copied = typeof config?.componentsDir === "string" && componentsUseAnimation(baseDir, config.componentsDir);
2737
2698
  if (!declared && !copied) return null;
2738
2699
  const by = declared ? "@axis-ds/ui-react \uC120\uC5B8" : "componentsDir \uC758 animate-in \uB958 \uD074\uB798\uC2A4";
2739
2700
  const tailwind = detectTailwind(baseDir, pkg);
2740
2701
  if (tailwind.major !== void 0 && tailwind.major >= 4) {
2741
- const file = TAILWIND_CSS_CANDIDATES.find((c) => existsSync2(join(baseDir, c)));
2742
- const css = file !== void 0 ? stripCssComments(readFileSync2(join(baseDir, file), "utf8")) : "";
2702
+ const file = TAILWIND_CSS_CANDIDATES.find((c) => existsSync(join(baseDir, c)));
2703
+ const css = file !== void 0 ? stripCssComments(readFileSync(join(baseDir, file), "utf8")) : "";
2743
2704
  const ok = new RegExp(`@import\\s+(?:url\\(\\s*)?["']${ANIMATION_PLUGIN_TAILWIND4}["']`).test(css) || new RegExp(`@plugin\\s+["']${ANIMATION_PLUGIN_TAILWIND3}["']`).test(css);
2744
2705
  return ok ? { name: "animation", severity: "pass", message: `${file}\uC5D0 \uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC788\uC2B5\uB2C8\uB2E4` } : {
2745
2706
  name: "animation",
@@ -2747,10 +2708,10 @@ function checkAnimationPlugin(baseDirInput) {
2747
2708
  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}";`
2748
2709
  };
2749
2710
  }
2750
- const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync2(join(baseDir, f)));
2751
- const source = configFile !== void 0 ? stripJsComments(readFileSync2(join(baseDir, configFile), "utf8")) : "";
2711
+ const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync(join(baseDir, f)));
2712
+ const source = configFile !== void 0 ? stripJsComments(readFileSync(join(baseDir, configFile), "utf8")) : "";
2752
2713
  const plugins = configFile !== void 0 ? readAnimationPluginUse(source) : "absent";
2753
- const pluginDeclared = pkg !== void 0 && hasDependency2(pkg, ANIMATION_PLUGIN_TAILWIND3) !== void 0;
2714
+ const pluginDeclared = declaredRange(baseDir, pkg, ANIMATION_PLUGIN_TAILWIND3) !== void 0;
2754
2715
  const pluginInstalled = pluginDeclared && (isPnpProject(baseDir) || findInstalledPackage(baseDir, ANIMATION_PLUGIN_TAILWIND3) !== void 0);
2755
2716
  if (plugins === "found" && pluginDeclared && pluginInstalled) {
2756
2717
  return { name: "animation", severity: "pass", message: `${configFile}\uC758 plugins \uC5D0 ${ANIMATION_PLUGIN_TAILWIND3} \uAC00 \uC788\uC2B5\uB2C8\uB2E4` };
@@ -2829,9 +2790,21 @@ function splitTopLevel(body) {
2829
2790
  }
2830
2791
 
2831
2792
  // src/template/template-apply.ts
2793
+ function templateDependencyCommands(installCommand, detail) {
2794
+ const lines = [];
2795
+ const deps = detail.dependencies ?? {};
2796
+ const devDeps = detail.devDependencies ?? {};
2797
+ if (Object.keys(deps).length > 0) lines.push(addCommandFor(installCommand, deps));
2798
+ if (Object.keys(devDeps).length > 0) lines.push(addCommandFor(installCommand, devDeps, { dev: true }));
2799
+ return lines;
2800
+ }
2801
+ function templateInitNextSteps(projectDir) {
2802
+ const installCommand = detectInstallCommand(projectDir);
2803
+ return [installCommand, runScriptCommand(installCommand, "dev")];
2804
+ }
2832
2805
  async function templateApplyWarnings(baseDir, detail) {
2833
2806
  const warnings = [];
2834
- const pkgPath = path9.join(baseDir, "package.json");
2807
+ const pkgPath = path8.join(baseDir, "package.json");
2835
2808
  const templateRange = detail.devDependencies?.tailwindcss ?? detail.dependencies?.tailwindcss;
2836
2809
  const templateMajor = templateRange !== void 0 ? tailwindMajorFromRange(templateRange) : void 0;
2837
2810
  if (templateMajor !== void 0 && await fs8.pathExists(pkgPath)) {
@@ -2849,7 +2822,7 @@ async function templateApplyWarnings(baseDir, detail) {
2849
2822
  }
2850
2823
  }
2851
2824
  const usesRootApp = detail.files.some((f) => f.path.startsWith("app/"));
2852
- if (usesRootApp && await fs8.pathExists(path9.join(baseDir, "src", "app"))) {
2825
+ if (usesRootApp && await fs8.pathExists(path8.join(baseDir, "src", "app"))) {
2853
2826
  warnings.push(
2854
2827
  "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."
2855
2828
  );
@@ -2866,13 +2839,14 @@ async function applyTemplate(slug, options) {
2866
2839
  spinner.fail(err.message);
2867
2840
  process.exit(1);
2868
2841
  }
2869
- const baseDir = path9.resolve(options.dir || ".");
2842
+ const baseDir = path8.resolve(options.dir || ".");
2843
+ const installCommand = detectInstallCommand(baseDir);
2870
2844
  for (const w of await templateApplyWarnings(baseDir, detail)) {
2871
2845
  console.log(chalk5.yellow(`! ${w}`));
2872
2846
  }
2873
2847
  const conflicts = [];
2874
2848
  for (const file of detail.files) {
2875
- const dest = path9.join(baseDir, file.path);
2849
+ const dest = path8.join(baseDir, file.path);
2876
2850
  if (await fs8.pathExists(dest)) {
2877
2851
  conflicts.push(file.path);
2878
2852
  }
@@ -2908,7 +2882,7 @@ async function applyTemplate(slug, options) {
2908
2882
  if (options.dryRun) {
2909
2883
  console.log(chalk5.blue("\n[\uBBF8\uB9AC\uBCF4\uAE30] \uC0DD\uC131\uB420 \uD30C\uC77C:"));
2910
2884
  for (const file of detail.files) {
2911
- const dest = path9.join(baseDir, file.path);
2885
+ const dest = path8.join(baseDir, file.path);
2912
2886
  const exists = conflicts.includes(file.path);
2913
2887
  const label = exists ? chalk5.yellow("\uB36E\uC5B4\uC4F0\uAE30") : chalk5.green("\uC0DD\uC131");
2914
2888
  console.log(` ${label} ${dest}`);
@@ -2923,8 +2897,8 @@ async function applyTemplate(slug, options) {
2923
2897
  }
2924
2898
  const writeSpinner = ora3("\uD30C\uC77C \uC0DD\uC131 \uC911...").start();
2925
2899
  for (const file of detail.files) {
2926
- const dest = path9.join(baseDir, file.path);
2927
- await fs8.ensureDir(path9.dirname(dest));
2900
+ const dest = path8.join(baseDir, file.path);
2901
+ await fs8.ensureDir(path8.dirname(dest));
2928
2902
  await fs8.writeFile(dest, file.content);
2929
2903
  }
2930
2904
  writeSpinner.succeed(`${detail.files.length}\uAC1C \uD30C\uC77C \uC0DD\uC131 \uC644\uB8CC`);
@@ -2933,18 +2907,10 @@ async function applyTemplate(slug, options) {
2933
2907
  await runPostInstall(detail.postInstall, baseDir);
2934
2908
  }
2935
2909
  if (!options.skipDeps) {
2936
- const allDeps = { ...detail.dependencies, ...detail.devDependencies };
2937
- const depList = Object.entries(allDeps);
2938
- if (depList.length > 0) {
2910
+ const commands = templateDependencyCommands(installCommand, detail);
2911
+ if (commands.length > 0) {
2939
2912
  console.log(chalk5.yellow("\n\uD544\uC694\uD55C \uC758\uC874\uC131:"));
2940
- const deps = Object.entries(detail.dependencies || {}).map(([k, v]) => `${k}@${v}`).join(" ");
2941
- const devDeps = Object.entries(detail.devDependencies || {}).map(([k, v]) => `${k}@${v}`).join(" ");
2942
- if (deps) {
2943
- console.log(chalk5.cyan(` pnpm add ${deps}`));
2944
- }
2945
- if (devDeps) {
2946
- console.log(chalk5.cyan(` pnpm add -D ${devDeps}`));
2947
- }
2913
+ for (const command of commands) console.log(chalk5.cyan(` ${command}`));
2948
2914
  }
2949
2915
  }
2950
2916
  console.log(chalk5.green(`
@@ -3005,7 +2971,7 @@ async function initTemplate(slug, options) {
3005
2971
  }
3006
2972
  targetDir = dir;
3007
2973
  }
3008
- const resolved = path9.resolve(targetDir);
2974
+ const resolved = path8.resolve(targetDir);
3009
2975
  if (await fs8.pathExists(resolved)) {
3010
2976
  const entries = await fs8.readdir(resolved);
3011
2977
  if (entries.length > 0) {
@@ -3033,8 +2999,9 @@ async function initTemplate(slug, options) {
3033
2999
  } else {
3034
3000
  await fs8.ensureDir(resolved);
3035
3001
  }
3002
+ const nextSteps = templateInitNextSteps(resolved);
3036
3003
  await applyTemplate(selectedSlug, { dir: targetDir, yes: true });
3037
- const configPath = path9.join(resolved, "axis.config.json");
3004
+ const configPath = path8.join(resolved, "axis.config.json");
3038
3005
  if (!await fs8.pathExists(configPath)) {
3039
3006
  const axisConfig = createTemplateConfig(selectedSlug);
3040
3007
  await fs8.writeJSON(configPath, axisConfig, { spaces: 2 });
@@ -3043,13 +3010,12 @@ async function initTemplate(slug, options) {
3043
3010
  console.log(chalk5.blue(`
3044
3011
  \uB2E4\uC74C \uB2E8\uACC4:`));
3045
3012
  console.log(chalk5.cyan(` cd ${targetDir}`));
3046
- console.log(chalk5.cyan(` pnpm install`));
3047
- console.log(chalk5.cyan(` pnpm dev`));
3013
+ for (const command of nextSteps) console.log(chalk5.cyan(` ${command}`));
3048
3014
  }
3049
3015
 
3050
3016
  // src/template/template-diff.ts
3051
3017
  import fs9 from "fs-extra";
3052
- import path10 from "path";
3018
+ import path9 from "path";
3053
3019
  import chalk6 from "chalk";
3054
3020
  import ora4 from "ora";
3055
3021
  async function diffTemplate(slug, options) {
@@ -3062,10 +3028,10 @@ async function diffTemplate(slug, options) {
3062
3028
  spinner.fail(err.message);
3063
3029
  process.exit(1);
3064
3030
  }
3065
- const baseDir = path10.resolve(options.dir || ".");
3031
+ const baseDir = path9.resolve(options.dir || ".");
3066
3032
  const entries = [];
3067
3033
  for (const file of detail.files) {
3068
- const localPath = path10.join(baseDir, file.path);
3034
+ const localPath = path9.join(baseDir, file.path);
3069
3035
  if (!await fs9.pathExists(localPath)) {
3070
3036
  entries.push({ path: file.path, status: "added" });
3071
3037
  continue;
@@ -3146,12 +3112,12 @@ async function collectLocalFiles(dir, base) {
3146
3112
  }
3147
3113
  for (const entry of entries) {
3148
3114
  if (ignore.has(entry.name)) continue;
3149
- const fullPath = path10.join(dir, entry.name);
3115
+ const fullPath = path9.join(dir, entry.name);
3150
3116
  if (entry.isDirectory()) {
3151
3117
  const nested = await collectLocalFiles(fullPath, root);
3152
3118
  results.push(...nested);
3153
3119
  } else {
3154
- results.push(path10.relative(root, fullPath).replace(/\\/g, "/"));
3120
+ results.push(path9.relative(root, fullPath).replace(/\\/g, "/"));
3155
3121
  }
3156
3122
  }
3157
3123
  return results;
@@ -3159,13 +3125,13 @@ async function collectLocalFiles(dir, base) {
3159
3125
 
3160
3126
  // src/template/template-check.ts
3161
3127
  import fs10 from "fs-extra";
3162
- import path11 from "path";
3128
+ import path10 from "path";
3163
3129
  import chalk7 from "chalk";
3164
3130
 
3165
3131
  // src/theme/brand-core.ts
3166
- import { existsSync as existsSync3, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
3132
+ import { existsSync as existsSync2, readFileSync as readFileSync2, statSync } from "fs";
3167
3133
  import { createRequire } from "module";
3168
- import { dirname, join as join2, relative, resolve as resolve2, sep } from "path";
3134
+ import { dirname as dirname2, join as join2, relative as relative2, resolve as resolve2, sep as sep2 } from "path";
3169
3135
  var TOKENS_PACKAGE = "@axis-ds/tokens";
3170
3136
  var BRAND_NAME_PATTERN = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
3171
3137
  var MIN_BRAND_TOKENS_VERSION = "1.3.0";
@@ -3186,7 +3152,7 @@ var KEY_TOKENS = [
3186
3152
  ];
3187
3153
  var BRAND_ADJUSTMENT_REFERENCE = "WI-0025 PRD \uBD80\uB85D B (docs/workitems/WI-0025-brand-theme/prd.md)";
3188
3154
  function readJsonFile(file) {
3189
- return JSON.parse(readFileSync3(file, "utf8"));
3155
+ return JSON.parse(readFileSync2(file, "utf8"));
3190
3156
  }
3191
3157
  function errorCode(err) {
3192
3158
  return typeof err === "object" && err !== null && "code" in err ? String(err.code) : void 0;
@@ -3195,8 +3161,8 @@ function findTokensPackageJson(baseDir) {
3195
3161
  let dir = resolve2(baseDir);
3196
3162
  for (; ; ) {
3197
3163
  const candidate = join2(dir, "node_modules", TOKENS_PACKAGE, "package.json");
3198
- if (existsSync3(candidate)) return candidate;
3199
- const parent = dirname(dir);
3164
+ if (existsSync2(candidate)) return candidate;
3165
+ const parent = dirname2(dir);
3200
3166
  if (parent === dir) return void 0;
3201
3167
  dir = parent;
3202
3168
  }
@@ -3225,9 +3191,9 @@ function resolveTokens(baseDir) {
3225
3191
  function brandImportPath(entry) {
3226
3192
  return tokensSpecifier(entry.css);
3227
3193
  }
3228
- function isFile2(file) {
3194
+ function isFile(file) {
3229
3195
  try {
3230
- return statSync2(file).isFile();
3196
+ return statSync(file).isFile();
3231
3197
  } catch {
3232
3198
  return false;
3233
3199
  }
@@ -3238,12 +3204,12 @@ function findGlobalCss(baseDir, config) {
3238
3204
  const configured = config?.globalCss;
3239
3205
  if (typeof configured === "string" && configured.trim() !== "") {
3240
3206
  const file = resolve2(root, configured);
3241
- if (isFile2(file)) return { path: file };
3207
+ if (isFile(file)) return { path: file };
3242
3208
  result.configuredMissing = configured;
3243
3209
  }
3244
3210
  for (const candidate of GLOBAL_CSS_CANDIDATES) {
3245
3211
  const file = join2(root, candidate);
3246
- if (isFile2(file)) {
3212
+ if (isFile(file)) {
3247
3213
  result.path = file;
3248
3214
  break;
3249
3215
  }
@@ -3262,7 +3228,7 @@ var AXIS_CONFIG_FILE_NAME = "axis.config.json";
3262
3228
  function readBrandConfig(baseDir) {
3263
3229
  let parsed;
3264
3230
  try {
3265
- parsed = JSON.parse(readFileSync3(join2(resolve2(baseDir), AXIS_CONFIG_FILE_NAME), "utf8"));
3231
+ parsed = JSON.parse(readFileSync2(join2(resolve2(baseDir), AXIS_CONFIG_FILE_NAME), "utf8"));
3266
3232
  } catch {
3267
3233
  return null;
3268
3234
  }
@@ -3280,8 +3246,8 @@ function inspectBrandImport(baseDir) {
3280
3246
  if (!location.path) {
3281
3247
  return { ...base, state: "css-missing", imports: [] };
3282
3248
  }
3283
- const cssFile = relative(root, location.path).split(sep).join("/");
3284
- const imports = [...new Set(findBrandImports(readFileSync3(location.path, "utf8")))];
3249
+ const cssFile = relative2(root, location.path).split(sep2).join("/");
3250
+ const imports = [...new Set(findBrandImports(readFileSync2(location.path, "utf8")))];
3285
3251
  let state;
3286
3252
  if (imports.includes(brand)) state = "match";
3287
3253
  else if (imports.length === 0) state = "import-missing";
@@ -3390,15 +3356,15 @@ function findBrandActivation(baseDir) {
3390
3356
  const layoutFiles = [];
3391
3357
  for (const candidate of BRAND_ACTIVATION_FILES) {
3392
3358
  const file = join2(root, candidate);
3393
- if (!isFile2(file)) continue;
3359
+ if (!isFile(file)) continue;
3394
3360
  layoutFiles.push(candidate);
3395
- const text = stripJsLikeComments(readFileSync3(file, "utf8"));
3361
+ const text = stripJsLikeComments(readFileSync2(file, "utf8"));
3396
3362
  const providerTexts = [];
3397
3363
  for (const m of text.matchAll(/from\s+["']\.\/(providers?)["']/g)) {
3398
3364
  for (const ext of [".tsx", ".jsx", ".ts", ".js"]) {
3399
- const rel3 = `${dirname(candidate)}/${m[1]}${ext}`;
3365
+ const rel3 = `${dirname2(candidate)}/${m[1]}${ext}`;
3400
3366
  const p = join2(root, rel3);
3401
- if (isFile2(p)) providerTexts.push({ rel: rel3, text: stripJsLikeComments(readFileSync3(p, "utf8")) });
3367
+ if (isFile(p)) providerTexts.push({ rel: rel3, text: stripJsLikeComments(readFileSync2(p, "utf8")) });
3402
3368
  }
3403
3369
  }
3404
3370
  const all = [text, ...providerTexts.map((x) => x.text)];
@@ -3425,7 +3391,7 @@ function inspectBrandActivation(baseDir) {
3425
3391
  var THEME_PACKAGE = "@axis-ds/theme";
3426
3392
  function readProjectPackageJson(baseDir) {
3427
3393
  try {
3428
- const parsed = JSON.parse(readFileSync3(join2(resolve2(baseDir), "package.json"), "utf8"));
3394
+ const parsed = JSON.parse(readFileSync2(join2(resolve2(baseDir), "package.json"), "utf8"));
3429
3395
  return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : void 0;
3430
3396
  } catch {
3431
3397
  return void 0;
@@ -3447,7 +3413,7 @@ function getBrand(baseDir, name) {
3447
3413
  try {
3448
3414
  summary = readSummary(baseDir, entry);
3449
3415
  const cssPath = projectRequire(baseDir).resolve(summary.importPath);
3450
- parsed = parseBrandCss(readFileSync3(cssPath, "utf8"), name);
3416
+ parsed = parseBrandCss(readFileSync2(cssPath, "utf8"), name);
3451
3417
  } catch (err) {
3452
3418
  if (isMissingBuildFile(err)) return { status: "not-built", version: tokens.version, brand: null, available: [] };
3453
3419
  throw err;
@@ -3466,8 +3432,8 @@ function getBrand(baseDir, name) {
3466
3432
  }
3467
3433
 
3468
3434
  // ../axis-registry-core/src/template/dependencies-core.ts
3469
- import { readFileSync as readFileSync4 } from "fs";
3470
- import { join as join3, resolve as resolve3 } from "path";
3435
+ import { readFileSync as readFileSync3 } from "fs";
3436
+ import { join as join3 } from "path";
3471
3437
  var REQUIRED_DEPENDENCIES = ["tailwindcss"];
3472
3438
  var RECOMMENDED_DEPENDENCIES = ["clsx", "tailwind-merge"];
3473
3439
  function declaredAxisPackages(pkg) {
@@ -3480,10 +3446,10 @@ function declaredAxisPackages(pkg) {
3480
3446
  return out;
3481
3447
  }
3482
3448
  function checkDependencies(baseDirInput) {
3483
- const baseDir = resolve3(baseDirInput);
3449
+ const baseDir = resolveBaseDir(baseDirInput);
3484
3450
  let pkg;
3485
3451
  try {
3486
- const parsed = JSON.parse(readFileSync4(join3(baseDir, "package.json"), "utf8"));
3452
+ const parsed = JSON.parse(readFileSync3(join3(baseDir, "package.json"), "utf8"));
3487
3453
  if (!isPlainObject(parsed)) throw new Error("not object");
3488
3454
  pkg = parsed;
3489
3455
  } catch (err) {
@@ -3492,13 +3458,18 @@ function checkDependencies(baseDirInput) {
3492
3458
  }
3493
3459
  return { name: "dependencies", severity: "fail", message: "package.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(JSON \uD655\uC778)" };
3494
3460
  }
3495
- const missingRequired = REQUIRED_DEPENDENCIES.filter((d) => !hasDependency(pkg, d));
3461
+ const rootPkg = workspaceRootPackage(baseDir) ?? null;
3462
+ const declared = (d) => declaredDependency(baseDir, pkg, d, rootPkg);
3463
+ const fromRoot = (d) => declared(d)?.source === "root";
3464
+ const missingRequired = REQUIRED_DEPENDENCIES.filter((d) => declared(d) === void 0);
3496
3465
  if (missingRequired.length > 0) {
3497
3466
  return { name: "dependencies", severity: "fail", message: `\uD544\uC218 \uC758\uC874\uC131 \uB204\uB77D: ${missingRequired.join(", ")}` };
3498
3467
  }
3499
- const missingRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => !hasDependency(pkg, d));
3468
+ const missingRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => declared(d) === void 0);
3469
+ const rootDeclared = [...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => fromRoot(d));
3470
+ const rootNote = rootDeclared.length > 0 ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8: ${rootDeclared.join(", ")}` : void 0;
3500
3471
  const targets = [
3501
- ...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => hasDependency(pkg, d) !== void 0),
3472
+ ...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => declared(d) !== void 0),
3502
3473
  ...declaredAxisPackages(pkg)
3503
3474
  ];
3504
3475
  const pnp = isPnpProject(baseDir);
@@ -3508,11 +3479,14 @@ function checkDependencies(baseDirInput) {
3508
3479
  if (notInstalled.length > 0) {
3509
3480
  problems.push(`\uC120\uC5B8\uB410\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC740 \uC758\uC874\uC131: ${notInstalled.join(", ")} \u2192 ${detectInstallCommand(baseDir)}`);
3510
3481
  }
3511
- if (problems.length > 0) return { name: "dependencies", severity: "warn", message: problems.join(" / ") };
3482
+ if (problems.length > 0) {
3483
+ return { name: "dependencies", severity: "warn", message: problems.join(" / ") + (rootNote ? ` (${rootNote})` : "") };
3484
+ }
3485
+ const note = rootNote ? `, ${rootNote}` : "";
3512
3486
  return {
3513
3487
  name: "dependencies",
3514
3488
  severity: "pass",
3515
- 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)`
3489
+ 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${note})` : `\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${note})`
3516
3490
  };
3517
3491
  }
3518
3492
 
@@ -3523,7 +3497,7 @@ var SEVERITY_ICON = {
3523
3497
  fail: chalk7.red("FAIL")
3524
3498
  };
3525
3499
  async function collectCheckResults(dir) {
3526
- const baseDir = path11.resolve(dir || ".");
3500
+ const baseDir = path10.resolve(dir || ".");
3527
3501
  const results = [];
3528
3502
  results.push(await checkFileExists(baseDir, "axis.config.json", "axis.config.json"));
3529
3503
  results.push(checkTailwindSetup(baseDir));
@@ -3574,7 +3548,7 @@ async function runCheck(dir) {
3574
3548
  return { pass: passCount, warn: warnCount, fail: failCount };
3575
3549
  }
3576
3550
  async function checkFileExists(baseDir, fileName, label) {
3577
- const exists = await fs10.pathExists(path11.join(baseDir, fileName));
3551
+ const exists = await fs10.pathExists(path10.join(baseDir, fileName));
3578
3552
  return {
3579
3553
  name: label,
3580
3554
  severity: exists ? "pass" : "fail",
@@ -3590,7 +3564,7 @@ async function checkUtils(baseDir) {
3590
3564
  "utils.ts"
3591
3565
  ];
3592
3566
  for (const candidate of candidates) {
3593
- const fullPath = path11.join(baseDir, candidate);
3567
+ const fullPath = path10.join(baseDir, candidate);
3594
3568
  if (await fs10.pathExists(fullPath)) {
3595
3569
  const content = await fs10.readFile(fullPath, "utf-8");
3596
3570
  const hasCn = content.includes("function cn");
@@ -3772,16 +3746,16 @@ function registerCheckCommand(program2) {
3772
3746
 
3773
3747
  // src/theme/index.ts
3774
3748
  import chalk9 from "chalk";
3775
- import path13 from "path";
3749
+ import path12 from "path";
3776
3750
 
3777
3751
  // src/theme/theme-add.ts
3778
- import { accessSync, constants, existsSync as existsSync4, readFileSync as readFileSync5, realpathSync, unlinkSync, writeFileSync } from "fs";
3779
- import path12 from "path";
3752
+ import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync4, realpathSync as realpathSync2, unlinkSync, writeFileSync } from "fs";
3753
+ import path11 from "path";
3780
3754
  var TOKENS_DEPENDENCY_RANGE = `^${TOKENS_DEPENDENCY_MIN_VERSION}`;
3781
3755
  var TAILWIND3_BASE_IMPORTS = [`${TOKENS_PACKAGE}/css`, `${TOKENS_PACKAGE}/css/shadcn`];
3782
3756
  var THEME_MIN_VERSION = "1.3.0";
3783
3757
  function readText(file) {
3784
- return existsSync4(file) ? readFileSync5(file, "utf8") : null;
3758
+ return existsSync3(file) ? readFileSync4(file, "utf8") : null;
3785
3759
  }
3786
3760
  function eolOf(text) {
3787
3761
  return text.includes("\r\n") ? "\r\n" : "\n";
@@ -3872,17 +3846,17 @@ function compareVersions(a, b) {
3872
3846
  return 0;
3873
3847
  }
3874
3848
  function realPathInside(baseDir, file) {
3875
- const realBase = realpathSync(baseDir);
3876
- const realPath = realpathSync(file);
3877
- const relPath = path12.relative(realBase, realPath);
3878
- const inside = relPath !== "" && !relPath.startsWith("..") && !path12.isAbsolute(relPath);
3849
+ const realBase = realpathSync2(baseDir);
3850
+ const realPath = realpathSync2(file);
3851
+ const relPath = path11.relative(realBase, realPath);
3852
+ const inside = relPath !== "" && !relPath.startsWith("..") && !path11.isAbsolute(relPath);
3879
3853
  return { inside, realPath };
3880
3854
  }
3881
3855
  function isStylesheet(realPath) {
3882
- return path12.extname(realPath).toLowerCase() === ".css";
3856
+ return path11.extname(realPath).toLowerCase() === ".css";
3883
3857
  }
3884
3858
  function planThemeAdd(baseDirInput, brand) {
3885
- const baseDir = path12.resolve(baseDirInput);
3859
+ const baseDir = path11.resolve(baseDirInput);
3886
3860
  const plan = {
3887
3861
  baseDir,
3888
3862
  brand,
@@ -3894,7 +3868,7 @@ function planThemeAdd(baseDirInput, brand) {
3894
3868
  installCommand: detectInstallCommand(baseDir),
3895
3869
  writes: []
3896
3870
  };
3897
- const configFile = path12.join(baseDir, AXIS_CONFIG_FILE);
3871
+ const configFile = path11.join(baseDir, AXIS_CONFIG_FILE);
3898
3872
  const configText = readText(configFile);
3899
3873
  if (configText === null) {
3900
3874
  plan.errors.push({ kind: "no-config" });
@@ -3915,7 +3889,7 @@ function planThemeAdd(baseDirInput, brand) {
3915
3889
  }
3916
3890
  plan.tokens = resolveTokens(baseDir);
3917
3891
  if (plan.tokens.status === "ok" && plan.tokens.indexPath) {
3918
- const data = JSON.parse(readFileSync5(plan.tokens.indexPath, "utf8"));
3892
+ const data = JSON.parse(readFileSync4(plan.tokens.indexPath, "utf8"));
3919
3893
  const entries = Array.isArray(data.brands) ? data.brands : [];
3920
3894
  const entry = entries.find((e) => e.name === brand);
3921
3895
  if (!entry) {
@@ -3931,7 +3905,7 @@ function planThemeAdd(baseDirInput, brand) {
3931
3905
  } else {
3932
3906
  plan.unverifiedBrand = true;
3933
3907
  }
3934
- const pkgFile = path12.join(baseDir, "package.json");
3908
+ const pkgFile = path11.join(baseDir, "package.json");
3935
3909
  const pkgText = readText(pkgFile);
3936
3910
  let pkg;
3937
3911
  if (pkgText !== null) {
@@ -3966,7 +3940,7 @@ function planThemeAdd(baseDirInput, brand) {
3966
3940
  plan.writes = [];
3967
3941
  return plan;
3968
3942
  }
3969
- const before = readFileSync5(location.path, "utf8");
3943
+ const before = readFileSync4(location.path, "utf8");
3970
3944
  const imported = findBrandImports(before);
3971
3945
  const otherBrands = [...new Set(imported.filter((n) => n !== brand))];
3972
3946
  const brandAdded = !imported.includes(brand);
@@ -3999,11 +3973,11 @@ function planThemeAdd(baseDirInput, brand) {
3999
3973
  };
4000
3974
  }
4001
3975
  if (!tailwind4) {
4002
- const configFile2 = TAILWIND_CONFIG_FILES.find((f) => existsSync4(path12.join(baseDir, f)));
3976
+ const configFile2 = TAILWIND_CONFIG_FILES.find((f) => existsSync3(path11.join(baseDir, f)));
4003
3977
  const content = inspectTailwindContent(baseDir);
4004
3978
  plan.tailwindConfig = {
4005
3979
  configFile: configFile2,
4006
- presetMissing: configFile2 === void 0 || !hasTokensPresetReference(readFileSync5(path12.join(baseDir, configFile2), "utf8")),
3980
+ presetMissing: configFile2 === void 0 || !hasTokensPresetReference(readFileSync4(path11.join(baseDir, configFile2), "utf8")),
4007
3981
  contentMissing: content?.targets.filter((t) => !t.covered) ?? [],
4008
3982
  contentUnknown: content !== null && (content.unreadable || content.dynamic)
4009
3983
  };
@@ -4059,8 +4033,8 @@ function applyThemeAdd(plan) {
4059
4033
  if (current !== w.before) {
4060
4034
  throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
4061
4035
  }
4062
- const where = realPathInside(plan.baseDir, w.before === null ? path12.dirname(w.file) : w.file);
4063
- if (!where.inside && !(w.before === null && path12.dirname(w.file) === plan.baseDir)) {
4036
+ const where = realPathInside(plan.baseDir, w.before === null ? path11.dirname(w.file) : w.file);
4037
+ if (!where.inside && !(w.before === null && path11.dirname(w.file) === plan.baseDir)) {
4064
4038
  throw new Error(`${w.file} \uC758 \uC2E4\uC81C \uC704\uCE58(${where.realPath})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`);
4065
4039
  }
4066
4040
  if (!w.file.endsWith(".json") && !isStylesheet(where.realPath)) {
@@ -4072,7 +4046,7 @@ function applyThemeAdd(plan) {
4072
4046
  throw new Error(`${w.file}: \uBE0C\uB79C\uB4DC import \uAC00 \uC815\uD655\uD788 1\uC904\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
4073
4047
  }
4074
4048
  try {
4075
- accessSync(w.before === null ? path12.dirname(w.file) : w.file, constants.W_OK);
4049
+ accessSync(w.before === null ? path11.dirname(w.file) : w.file, constants.W_OK);
4076
4050
  } catch (err) {
4077
4051
  throw new Error(`${w.file} \uC5D0 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errorMessage(err)}).`);
4078
4052
  }
@@ -4148,7 +4122,7 @@ function tokensStatusGuide(status, version, installCommand = TOKENS_INSTALL_COMM
4148
4122
  chalk9.yellow(
4149
4123
  `${TOKENS_PACKAGE}${version ? ` ${version}` : ""} \uB294 \uC788\uC9C0\uB9CC \uBE4C\uB4DC \uC0B0\uCD9C\uBB3C\uC774 \uC5C6\uC5B4 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`
4150
4124
  ),
4151
- ` \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 ${chalk9.cyan(`pnpm --filter ${TOKENS_PACKAGE} build`)}, \uC544\uB2C8\uBA74 \uC7AC\uC124\uCE58: ${chalk9.cyan(installCommand)}`
4125
+ ` \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 ${chalk9.cyan(workspaceRunCommand(installCommand, TOKENS_PACKAGE, "build"))}, \uC544\uB2C8\uBA74 \uC7AC\uC124\uCE58: ${chalk9.cyan(installCommand)}`
4152
4126
  ];
4153
4127
  }
4154
4128
  }
@@ -4245,7 +4219,7 @@ function renderThemeInfo(result, name, installCommand) {
4245
4219
  return { lines, exitCode: 0 };
4246
4220
  }
4247
4221
  function rel(plan, file) {
4248
- return path13.relative(plan.baseDir, file) || file;
4222
+ return path12.relative(plan.baseDir, file) || file;
4249
4223
  }
4250
4224
  function renderThemeAdd(plan, written) {
4251
4225
  const error = plan.errors[0];
@@ -4385,6 +4359,7 @@ function renderThemeAdd(plan, written) {
4385
4359
  )
4386
4360
  );
4387
4361
  }
4362
+ if (tw.contentMissing.some((t) => t.suggest.startsWith("../"))) lines.push(chalk9.gray(` ${CONTENT_PARENT_PATH_NOTE}`));
4388
4363
  }
4389
4364
  const act = plan.activation;
4390
4365
  lines.push("", chalk9.bold(`\uBE0C\uB79C\uB4DC \uCF1C\uAE30 (ThemeProvider \uB294 ${THEME_PACKAGE} ${THEME_MIN_VERSION} \uC774\uC0C1)`));
@@ -4439,15 +4414,15 @@ function print(output) {
4439
4414
  function registerThemeCommand(program2) {
4440
4415
  const themeCmd = program2.command("theme").description("\uBE0C\uB79C\uB4DC \uD14C\uB9C8 (@axis-ds/tokens \uBE0C\uB79C\uB4DC)");
4441
4416
  themeCmd.command("list").alias("ls").description("\uC124\uCE58\uB41C @axis-ds/tokens \uC758 \uBE0C\uB79C\uB4DC \uBAA9\uB85D").option("-d, --dir <path>", "\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC").action((options) => {
4442
- const baseDir = path13.resolve(options.dir || ".");
4417
+ const baseDir = path12.resolve(options.dir || ".");
4443
4418
  print(renderThemeList(listBrands(baseDir), tokensInstallCommand(baseDir)));
4444
4419
  });
4445
4420
  themeCmd.command("info <brand>").description("\uBE0C\uB79C\uB4DC \uC0C1\uC138: import \uACBD\uB85C \xB7 Provider \uC608\uC2DC \xB7 \uC8FC\uC694 \uD1A0\uD070 \xB7 \uBCF4\uC815 \uB0B4\uC5ED").option("-d, --dir <path>", "\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC").action((name, options) => {
4446
- const baseDir = path13.resolve(options.dir || ".");
4421
+ const baseDir = path12.resolve(options.dir || ".");
4447
4422
  print(renderThemeInfo(getBrand(baseDir, name), name, tokensInstallCommand(baseDir)));
4448
4423
  });
4449
4424
  themeCmd.command("add <brand>").description("\uBE0C\uB79C\uB4DC \uC801\uC6A9: CSS import \xB7 package.json \uC758\uC874\uC131 \xB7 axis.config.json brand (\uC124\uCE58\uB294 \uC548\uB0B4\uB9CC)").option("-d, --dir <path>", "\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC").action((name, options) => {
4450
- const baseDir = path13.resolve(options.dir || ".");
4425
+ const baseDir = path12.resolve(options.dir || ".");
4451
4426
  const plan = planThemeAdd(baseDir, name);
4452
4427
  let written = [];
4453
4428
  if (plan.errors.length === 0) {
@@ -4766,14 +4741,14 @@ async function fetchRegistryJson(url, options = {}) {
4766
4741
  }
4767
4742
 
4768
4743
  // src/init/init.ts
4769
- 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";
4770
- import path15 from "path";
4744
+ import { accessSync as accessSync2, constants as constants2, existsSync as existsSync5, lstatSync as lstatSync3, readFileSync as readFileSync5, realpathSync as realpathSync4, statSync as statSync3, writeFileSync as writeFileSync2 } from "fs";
4745
+ import path14 from "path";
4771
4746
  import chalk10 from "chalk";
4772
4747
  import fs12 from "fs-extra";
4773
4748
 
4774
4749
  // ../axis-registry-core/src/add/safe-write.ts
4775
- import { constants as fsConstants, existsSync as existsSync5, lstatSync as lstatSync2, realpathSync as realpathSync2, statSync as statSync3 } from "fs";
4776
- import path14 from "path";
4750
+ import { constants as fsConstants, existsSync as existsSync4, lstatSync as lstatSync2, realpathSync as realpathSync3, statSync as statSync2 } from "fs";
4751
+ import path13 from "path";
4777
4752
  import fs11 from "fs-extra";
4778
4753
  var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
4779
4754
  var OVERWRITE_FLAGS = fsConstants.O_WRONLY | (fsConstants.O_NOFOLLOW ?? 0);
@@ -4784,27 +4759,27 @@ function codedError(code, message) {
4784
4759
  e.code = code;
4785
4760
  return e;
4786
4761
  }
4787
- function isSameOrInside(parent, child, impl = path14) {
4762
+ function isSameOrInside(parent, child, impl = path13) {
4788
4763
  const rel3 = impl.relative(parent, child);
4789
4764
  if (rel3 === "") return true;
4790
4765
  return !(rel3 === ".." || rel3.startsWith(`..${impl.sep}`) || impl.isAbsolute(rel3));
4791
4766
  }
4792
4767
  function nearestExisting(p) {
4793
4768
  let cur = p;
4794
- while (!existsSync5(cur)) {
4795
- const up = path14.dirname(cur);
4769
+ while (!existsSync4(cur)) {
4770
+ const up = path13.dirname(cur);
4796
4771
  if (up === cur) return cur;
4797
4772
  cur = up;
4798
4773
  }
4799
4774
  return cur;
4800
4775
  }
4801
4776
  function escapeReason(root, target, options = {}) {
4802
- const realRoot = realpathSync2(root);
4803
- if (!isSameOrInside(path14.resolve(root), path14.resolve(target)) || path14.resolve(target) === path14.resolve(root)) {
4777
+ const realRoot = realpathSync3(root);
4778
+ if (!isSameOrInside(path13.resolve(root), path13.resolve(target)) || path13.resolve(target) === path13.resolve(root)) {
4804
4779
  return `\uACBD\uB85C\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4(${target})`;
4805
4780
  }
4806
- const anchor = nearestExisting(path14.dirname(target));
4807
- const realAnchor = realpathSync2(anchor);
4781
+ const anchor = nearestExisting(path13.dirname(target));
4782
+ const realAnchor = realpathSync3(anchor);
4808
4783
  if (!isSameOrInside(realRoot, realAnchor)) {
4809
4784
  return `\uC0C1\uC704 \uB514\uB809\uD130\uB9AC\uC758 \uC2E4\uC81C \uC704\uCE58(${realAnchor})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`;
4810
4785
  }
@@ -4816,10 +4791,10 @@ function escapeReason(root, target, options = {}) {
4816
4791
  }
4817
4792
  if (st) {
4818
4793
  if (st.isDirectory()) return `\uAC19\uC740 \uC774\uB984\uC758 \uB514\uB809\uD130\uB9AC\uAC00 \uC788\uC2B5\uB2C8\uB2E4(${target})`;
4819
- const shown = path14.relative(path14.resolve(root), path14.resolve(target)).split(path14.sep).join("/");
4794
+ const shown = path13.relative(path13.resolve(root), path13.resolve(target)).split(path13.sep).join("/");
4820
4795
  let realTarget;
4821
4796
  try {
4822
- realTarget = realpathSync2(target);
4797
+ realTarget = realpathSync3(target);
4823
4798
  } catch {
4824
4799
  return `\uAE30\uC874 \uD30C\uC77C ${shown} \uC774 \uAE68\uC9C4 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB77C \uB530\uB77C\uAC08 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(\uB9C1\uD06C\uB97C \uC9C0\uC6B0\uAC70\uB098 \uACE0\uCE5C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694)`;
4825
4800
  }
@@ -4828,7 +4803,7 @@ function escapeReason(root, target, options = {}) {
4828
4803
  }
4829
4804
  let followed;
4830
4805
  try {
4831
- followed = statSync3(realTarget);
4806
+ followed = statSync2(realTarget);
4832
4807
  } catch {
4833
4808
  return `\uAE30\uC874 \uD30C\uC77C \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${target})`;
4834
4809
  }
@@ -4852,8 +4827,8 @@ function isSymlink(p) {
4852
4827
  function outsideLinkTarget(root, target) {
4853
4828
  if (!isSymlink(target)) return null;
4854
4829
  try {
4855
- const realTarget = realpathSync2(target);
4856
- return isSameOrInside(realpathSync2(root), realTarget) ? null : realTarget;
4830
+ const realTarget = realpathSync3(target);
4831
+ return isSameOrInside(realpathSync3(root), realTarget) ? null : realTarget;
4857
4832
  } catch {
4858
4833
  return null;
4859
4834
  }
@@ -4870,10 +4845,10 @@ function hardLinkMessage(shownPath, nlink) {
4870
4845
  return `\uAE30\uC874 \uD30C\uC77C ${shownPath} \uC774 \uB2E4\uB978 \uACBD\uB85C\uC640 \uD558\uB4DC\uB9C1\uD06C\uB85C \uC774\uC5B4\uC9C4 \uD30C\uC77C\uC774\uB77C(\uB9C1\uD06C \uC218 ${nlink}) \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB36E\uC5B4\uC4F0\uBA74 \uC774\uC5B4\uC9C4 \uB2E4\uB978 \uACBD\uB85C\uC758 \uB0B4\uC6A9\uB3C4 \uBC14\uB01D\uB2C8\uB2E4. \uD558\uB4DC\uB9C1\uD06C\uB97C \uB04A\uC740(\uD30C\uC77C\uC744 \uBCF5\uC0AC\uD574 \uBC14\uAFBC) \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694`;
4871
4846
  }
4872
4847
  function writtenOutside(root, target) {
4873
- const realRoot = realpathSync2(root);
4848
+ const realRoot = realpathSync3(root);
4874
4849
  let realTarget;
4875
4850
  try {
4876
- realTarget = realpathSync2(target);
4851
+ realTarget = realpathSync3(target);
4877
4852
  } catch {
4878
4853
  return target;
4879
4854
  }
@@ -4919,8 +4894,8 @@ async function overwriteFollowingLinks(target, content) {
4919
4894
  }
4920
4895
  }
4921
4896
  function checkParentInside(root, target) {
4922
- const realRoot = realpathSync2(root);
4923
- const realParent = realpathSync2(path14.dirname(target));
4897
+ const realRoot = realpathSync3(root);
4898
+ const realParent = realpathSync3(path13.dirname(target));
4924
4899
  if (!isSameOrInside(realRoot, realParent)) {
4925
4900
  return `\uBD80\uBAA8 \uB514\uB809\uD130\uB9AC\uC758 \uC2E4\uC81C \uC704\uCE58(${realParent})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`;
4926
4901
  }
@@ -4992,7 +4967,7 @@ export function cn(...inputs: ClassValue[]) {
4992
4967
  }
4993
4968
  `;
4994
4969
  async function resolveInitAnswers(baseDirInput, tailwind4) {
4995
- const baseDir = path15.resolve(baseDirInput);
4970
+ const baseDir = path14.resolve(baseDirInput);
4996
4971
  const tw4 = tailwind4 ?? isTailwind4(planUtilsDependencies(baseDir).tailwind);
4997
4972
  const current = await existingConfig(baseDir);
4998
4973
  const found = detectProjectPaths(baseDir);
@@ -5038,7 +5013,7 @@ var TAILWIND4_TOKENS_VERSION = TAILWIND4_MIN_AXIS_VERSION;
5038
5013
  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.";
5039
5014
  function readPackageJsonSafe(baseDir) {
5040
5015
  try {
5041
- const text = readFileSync6(path15.join(baseDir, "package.json"), "utf8");
5016
+ const text = readFileSync5(path14.join(baseDir, "package.json"), "utf8");
5042
5017
  const parsed = JSON.parse(text.startsWith(BOM) ? text.slice(1) : text);
5043
5018
  return isPlainObject(parsed) ? parsed : void 0;
5044
5019
  } catch {
@@ -5046,7 +5021,8 @@ function readPackageJsonSafe(baseDir) {
5046
5021
  }
5047
5022
  }
5048
5023
  function tailwind4GuideLines(pkg, installCommand, globalCss, baseDir) {
5049
- const used = TAILWIND4_COMPONENT_PACKAGES.filter((name) => pkg !== void 0 && hasDependency(pkg, name) !== void 0);
5024
+ const declared = (name) => pkg !== void 0 && (baseDir !== void 0 ? declaredDependency(baseDir, pkg, name) : hasDependency(pkg, name)) !== void 0;
5025
+ const used = TAILWIND4_COMPONENT_PACKAGES.filter((name) => declared(name));
5050
5026
  const lines = [
5051
5027
  `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).`,
5052
5028
  ' @import "tailwindcss";',
@@ -5059,7 +5035,7 @@ function tailwind4GuideLines(pkg, installCommand, globalCss, baseDir) {
5059
5035
  );
5060
5036
  }
5061
5037
  lines.push(TAILWIND4_CONFLICT_LINE);
5062
- if (pkg === void 0 || hasDependency(pkg, TOKENS_PACKAGE) === void 0) {
5038
+ if (!declared(TOKENS_PACKAGE)) {
5063
5039
  const add = addCommandFor(installCommand, { [TOKENS_PACKAGE]: `^${TAILWIND4_TOKENS_VERSION}` });
5064
5040
  lines.push(` ${TOKENS_PACKAGE} \uC124\uCE58: ${add}`);
5065
5041
  }
@@ -5097,7 +5073,7 @@ function tailwind4GuideLines(pkg, installCommand, globalCss, baseDir) {
5097
5073
  }
5098
5074
  var BOM = "\uFEFF";
5099
5075
  function planUtilsDependencies(baseDirInput) {
5100
- const baseDir = path15.resolve(baseDirInput);
5076
+ const baseDir = path14.resolve(baseDirInput);
5101
5077
  const installCommand = detectInstallCommand(baseDir);
5102
5078
  const tailwind0 = detectTailwind(baseDir);
5103
5079
  const ranges0 = selectUtilsDependencies(tailwind0);
@@ -5110,8 +5086,8 @@ function planUtilsDependencies(baseDirInput) {
5110
5086
  installCommand,
5111
5087
  addCommand: addCommandFor(installCommand, ranges0)
5112
5088
  };
5113
- const pkgFile = path15.join(baseDir, "package.json");
5114
- if (!existsSync6(pkgFile)) return plan;
5089
+ const pkgFile = path14.join(baseDir, "package.json");
5090
+ if (!existsSync5(pkgFile)) return plan;
5115
5091
  const unwritable = (reason) => ({ ...plan, action: "unwritable", reason });
5116
5092
  let where;
5117
5093
  try {
@@ -5122,7 +5098,7 @@ function planUtilsDependencies(baseDirInput) {
5122
5098
  if (!where.inside) return unwritable(`\uC2E4\uC81C \uC704\uCE58(${where.realPath})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`);
5123
5099
  let text;
5124
5100
  try {
5125
- text = readFileSync6(pkgFile, "utf8");
5101
+ text = readFileSync5(pkgFile, "utf8");
5126
5102
  } catch (err) {
5127
5103
  return unwritable(err.message);
5128
5104
  }
@@ -5141,8 +5117,8 @@ function planUtilsDependencies(baseDirInput) {
5141
5117
  plan.addCommand = addCommandFor(installCommand, plan.ranges);
5142
5118
  const missing = {};
5143
5119
  for (const [name, range] of Object.entries(plan.ranges)) {
5144
- const declared = hasDependency(pkg, name);
5145
- if (declared !== void 0) plan.present.push({ name, range: declared });
5120
+ const declared = declaredDependency(baseDir, pkg, name);
5121
+ if (declared !== void 0) plan.present.push({ name, range: declared.range, source: declared.source });
5146
5122
  else missing[name] = range;
5147
5123
  }
5148
5124
  plan.added = Object.keys(missing);
@@ -5164,8 +5140,8 @@ var defaultWriteFile = (file, data) => writeFileSync2(file, data);
5164
5140
  function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile) {
5165
5141
  const w = plan.write;
5166
5142
  if (plan.action !== "add" || !w) return false;
5167
- const baseDir = path15.resolve(baseDirInput);
5168
- const current = existsSync6(w.file) ? readFileSync6(w.file, "utf8") : null;
5143
+ const baseDir = path14.resolve(baseDirInput);
5144
+ const current = existsSync5(w.file) ? readFileSync5(w.file, "utf8") : null;
5169
5145
  if (current !== w.before) {
5170
5146
  throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
5171
5147
  }
@@ -5181,7 +5157,7 @@ function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile
5181
5157
  let restored;
5182
5158
  try {
5183
5159
  writeFile(w.file, w.before);
5184
- 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");
5160
+ if (readFileSync5(w.file, "utf8") !== w.before) throw new Error("\uB418\uB3CC\uB9B0 \uB0B4\uC6A9\uC774 \uC6D0\uB798 \uB0B4\uC6A9\uACFC \uB2E4\uB985\uB2C8\uB2E4");
5185
5161
  restored = "\uC6D0\uB798 \uB0B4\uC6A9\uC73C\uB85C \uB418\uB3CC\uB838\uC2B5\uB2C8\uB2E4";
5186
5162
  } catch (restoreErr) {
5187
5163
  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`;
@@ -5192,6 +5168,8 @@ function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile
5192
5168
  }
5193
5169
  function reportDependencies(plan, log) {
5194
5170
  const presentText = plan.present.map((p) => `${p.name} (${p.range})`).join(", ");
5171
+ const rootPresent = plan.present.filter((p) => p.source === "root").map((p) => p.name);
5172
+ const rootNote = rootPresent.length > 0 ? ` (\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8: ${rootPresent.join(", ")})` : "";
5195
5173
  const basis = ` tailwind-merge \uBC94\uC704 \uAE30\uC900: ${describeTailwindBasis(plan.tailwind)}`;
5196
5174
  const logBasis = () => {
5197
5175
  log(chalk10.gray(basis));
@@ -5200,11 +5178,11 @@ function reportDependencies(plan, log) {
5200
5178
  if (plan.action === "add") {
5201
5179
  const addedText = plan.added.map((n) => `${n}@${plan.ranges[n]}`).join(", ");
5202
5180
  log(chalk10.green(`\u2713 package.json dependencies \uC5D0 \uCD94\uAC00: ${addedText}`));
5203
- if (plan.present.length > 0) log(chalk10.gray(` \uC774\uBBF8 \uC788\uC74C(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
5181
+ if (plan.present.length > 0) log(chalk10.gray(` \uC774\uBBF8 \uC788\uC74C(\uBC84\uC804 \uC720\uC9C0): ${presentText}${rootNote}`));
5204
5182
  if (plan.added.includes("tailwind-merge")) logBasis();
5205
5183
  log(chalk10.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk10.cyan(plan.installCommand)}`));
5206
5184
  } else if (plan.action === "present") {
5207
- log(chalk10.green(`\u2713 utils.ts \uC758\uC874\uC131\uC774 package.json \uC5D0 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
5185
+ log(chalk10.green(`\u2713 utils.ts \uC758\uC874\uC131\uC774 package.json \uC5D0 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4(\uBC84\uC804 \uC720\uC9C0): ${presentText}${rootNote}`));
5208
5186
  log(chalk10.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk10.cyan(plan.installCommand)}`));
5209
5187
  } else if (plan.action === "no-package-json") {
5210
5188
  log(chalk10.yellow("! package.json \uC774 \uC5C6\uC5B4 utils.ts \uC758\uC874\uC131(clsx, tailwind-merge)\uC744 \uCD94\uAC00\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."));
@@ -5260,8 +5238,8 @@ function errCode(e) {
5260
5238
  return e.code ?? e.message;
5261
5239
  }
5262
5240
  function planUtilsWrite(baseDirInput, utilsPath) {
5263
- const baseDir = path15.resolve(baseDirInput);
5264
- const shown = path15.relative(baseDir, utilsPath).split(path15.sep).join("/") || utilsPath;
5241
+ const baseDir = path14.resolve(baseDirInput);
5242
+ const shown = path14.relative(baseDir, utilsPath).split(path14.sep).join("/") || utilsPath;
5265
5243
  let st;
5266
5244
  try {
5267
5245
  st = lstatSync3(utilsPath);
@@ -5272,19 +5250,19 @@ function planUtilsWrite(baseDirInput, utilsPath) {
5272
5250
  if (st.isSymbolicLink()) {
5273
5251
  let real;
5274
5252
  try {
5275
- real = realpathSync3(utilsPath);
5253
+ real = realpathSync4(utilsPath);
5276
5254
  } catch {
5277
5255
  return { action: "reject", reason: `${shown} \uC774 \uAE68\uC9C4 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB77C \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB9C1\uD06C\uB97C \uC9C0\uC6B0\uAC70\uB098 \uACE0\uCE5C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694` };
5278
5256
  }
5279
5257
  let outside = null;
5280
5258
  try {
5281
- outside = isSameOrInside(realpathSync3(baseDir), real) ? null : real;
5259
+ outside = isSameOrInside(realpathSync4(baseDir), real) ? null : real;
5282
5260
  } catch {
5283
5261
  outside = null;
5284
5262
  }
5285
5263
  let target;
5286
5264
  try {
5287
- target = statSync4(real);
5265
+ target = statSync3(real);
5288
5266
  } catch (e) {
5289
5267
  return { action: "reject", reason: `${shown} \uB9C1\uD06C \uB300\uC0C1(${real})\uC758 \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
5290
5268
  }
@@ -5292,7 +5270,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
5292
5270
  if (!target.isFile()) return { action: "reject", reason: `${shown} \uB9C1\uD06C \uB300\uC0C1(${real})\uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4` };
5293
5271
  let content2;
5294
5272
  try {
5295
- content2 = readFileSync6(utilsPath, "utf8");
5273
+ content2 = readFileSync5(utilsPath, "utf8");
5296
5274
  } catch (e) {
5297
5275
  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)})` };
5298
5276
  }
@@ -5307,7 +5285,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
5307
5285
  if (!st.isFile()) return { action: "reject", reason: `${shown} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2C8\uB77C \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4` };
5308
5286
  let content;
5309
5287
  try {
5310
- content = readFileSync6(utilsPath, "utf8");
5288
+ content = readFileSync5(utilsPath, "utf8");
5311
5289
  } catch (e) {
5312
5290
  return { action: "reject", reason: `\uAE30\uC874 ${shown} \uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
5313
5291
  }
@@ -5322,7 +5300,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
5322
5300
  return { action: "overwrite" };
5323
5301
  }
5324
5302
  async function runInit(baseDirInput, answers, registryUrl, log = console.log, options = {}) {
5325
- const baseDir = path15.resolve(baseDirInput);
5303
+ const baseDir = path14.resolve(baseDirInput);
5326
5304
  const current = await existingConfig(baseDir);
5327
5305
  const existingRegistry = nonEmptyString(current?.registry);
5328
5306
  const migratedRegistry = existingRegistry !== void 0 && isLegacyDefaultRegistryUrl(existingRegistry);
@@ -5339,7 +5317,7 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log, op
5339
5317
  },
5340
5318
  registry
5341
5319
  );
5342
- const configPath = path15.join(baseDir, "axis.config.json");
5320
+ const configPath = path14.join(baseDir, "axis.config.json");
5343
5321
  const rejects = [];
5344
5322
  let previousText = null;
5345
5323
  try {
@@ -5360,16 +5338,16 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log, op
5360
5338
  }
5361
5339
  if (previousText !== null && previousText !== nextText) {
5362
5340
  try {
5363
- const st = statSync4(configPath);
5341
+ const st = statSync3(configPath);
5364
5342
  if (st.isFile() && st.nlink >= 2) rejects.push(hardLinkMessage("axis.config.json", st.nlink));
5365
5343
  } catch {
5366
5344
  }
5367
5345
  }
5368
- const utilsPath = path15.resolve(baseDir, answers.componentsDir, "utils.ts");
5346
+ const utilsPath = path14.resolve(baseDir, answers.componentsDir, "utils.ts");
5369
5347
  const utilsPlan = planUtilsWrite(baseDir, utilsPath);
5370
5348
  if (utilsPlan.action === "reject") rejects.push(utilsPlan.reason);
5371
5349
  if (utilsPlan.action === "overwrite" && options.allowOverwrite === false) {
5372
- const shown = path15.relative(baseDir, utilsPath).split(path15.sep).join("/") || utilsPath;
5350
+ const shown = path14.relative(baseDir, utilsPath).split(path14.sep).join("/") || utilsPath;
5373
5351
  rejects.push(
5374
5352
  `\uBE44\uB300\uD654\uD615 \uC2E4\uD589\uC774\uB77C \uB0B4\uC6A9\uC774 \uB2E4\uB978 \uAE30\uC874 ${shown} \uB97C \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB36E\uC5B4\uC368\uB3C4 \uB418\uBA74 axis init -y \uB85C \uB2E4\uC2DC \uC2E4\uD589\uD558\uAC70\uB098 \uB300\uD654\uD615 \uD130\uBBF8\uB110\uC5D0\uC11C \uC2E4\uD589\uD558\uC138\uC694`
5375
5353
  );
@@ -5428,7 +5406,7 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log, op
5428
5406
  } else {
5429
5407
  let actual;
5430
5408
  try {
5431
- await fs12.ensureDir(path15.dirname(utilsPath));
5409
+ await fs12.ensureDir(path14.dirname(utilsPath));
5432
5410
  actual = await writeNoFollow(utilsPath, UTILS_TS_CONTENT, utilsPlan.action === "create" ? "new" : "overwrite");
5433
5411
  } catch (err) {
5434
5412
  const code = err.code;
@@ -5519,26 +5497,26 @@ function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL, deps
5519
5497
  import chalk12 from "chalk";
5520
5498
 
5521
5499
  // ../axis-registry-core/src/add/add.ts
5522
- import { existsSync as existsSync8, readFileSync as readFileSync8, statSync as statSync5 } from "fs";
5523
- import path17 from "path";
5500
+ import { existsSync as existsSync7, readFileSync as readFileSync7, statSync as statSync4 } from "fs";
5501
+ import path16 from "path";
5524
5502
  import fs13 from "fs-extra";
5525
5503
 
5526
5504
  // ../axis-registry-core/src/registry/bundled.ts
5527
- import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
5528
- import path16 from "path";
5505
+ import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
5506
+ import path15 from "path";
5529
5507
  import { fileURLToPath } from "url";
5530
5508
  function findBundledRegistryDir(moduleUrl = import.meta.url) {
5531
- const here = path16.dirname(fileURLToPath(moduleUrl));
5532
- for (const dir of [path16.join(here, "registry"), path16.join(here, "..", "registry")]) {
5533
- if (existsSync7(path16.join(dir, "index.json"))) return dir;
5509
+ const here = path15.dirname(fileURLToPath(moduleUrl));
5510
+ for (const dir of [path15.join(here, "registry"), path15.join(here, "..", "registry")]) {
5511
+ if (existsSync6(path15.join(dir, "index.json"))) return dir;
5534
5512
  }
5535
5513
  return null;
5536
5514
  }
5537
5515
  function readBundledJson(dir, fileName) {
5538
- const file = path16.join(dir, fileName);
5516
+ const file = path15.join(dir, fileName);
5539
5517
  let text;
5540
5518
  try {
5541
- text = readFileSync7(file, "utf8");
5519
+ text = readFileSync6(file, "utf8");
5542
5520
  } catch {
5543
5521
  throw new Error(`\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 ${fileName} \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4(${dir})`);
5544
5522
  }
@@ -5726,7 +5704,7 @@ function createPinnedFetch(options = {}) {
5726
5704
  const judge = options.judge ?? blockedAddressReason;
5727
5705
  const send = options.request ?? httpsRequest;
5728
5706
  const maxBytes = options.maxBytes ?? PINNED_FETCH_MAX_BYTES;
5729
- return (input, init) => new Promise((resolve4, reject) => {
5707
+ return (input, init) => new Promise((resolve3, reject) => {
5730
5708
  let url;
5731
5709
  try {
5732
5710
  url = new URL(input);
@@ -5767,7 +5745,7 @@ function createPinnedFetch(options = {}) {
5767
5745
  if (failed) return;
5768
5746
  const body = Buffer.concat(chunks).toString("utf8");
5769
5747
  const status = res.statusCode ?? 0;
5770
- resolve4({ ok: status >= 200 && status < 300, status, text: async () => body });
5748
+ resolve3({ ok: status >= 200 && status < 300, status, text: async () => body });
5771
5749
  });
5772
5750
  }
5773
5751
  );
@@ -6030,10 +6008,10 @@ function layoutFromConfig(root, config) {
6030
6008
  throw new Error("axis.config.json \uC758 agenticDir \uAC00 \uBB38\uC790\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4");
6031
6009
  }
6032
6010
  const componentsDir = componentsRaw.replace(/\\/g, "/");
6033
- const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") : path17.posix.join(path17.posix.dirname(componentsDir), "agentic");
6034
- return { root: path17.resolve(root), componentsDir, agenticDir };
6011
+ const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") : path16.posix.join(path16.posix.dirname(componentsDir), "agentic");
6012
+ return { root: path16.resolve(root), componentsDir, agenticDir };
6035
6013
  }
6036
- function toPosix(p, impl = path17) {
6014
+ function toPosix(p, impl = path16) {
6037
6015
  return p.split(impl.sep).join("/");
6038
6016
  }
6039
6017
  function itemKind(item) {
@@ -6055,12 +6033,12 @@ function placeFile(layout, item, filePath, target) {
6055
6033
  const problem = registryPathProblem(p);
6056
6034
  if (problem) throw new Error(`${item.name}: \uD30C\uC77C \uACBD\uB85C\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${JSON.stringify(p)}, ${problem})`);
6057
6035
  }
6058
- const base = path17.posix.basename(filePath);
6036
+ const base = path16.posix.basename(filePath);
6059
6037
  if (!INSTALL_FILE_NAME_PATTERN.test(base)) {
6060
6038
  throw new Error(`${item.name}: \uD30C\uC77C \uACBD\uB85C\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${JSON.stringify(filePath)}, \uD30C\uC77C \uC774\uB984\uC740 .ts \xB7 .tsx \uB9CC \uC124\uCE58\uD569\uB2C8\uB2E4)`);
6061
6039
  }
6062
6040
  const dir = itemKind(item) === "agentic" ? layout.agenticDir : layout.componentsDir;
6063
- return path17.resolve(layout.root, dir, base);
6041
+ return path16.resolve(layout.root, dir, base);
6064
6042
  }
6065
6043
  function stripExt(p) {
6066
6044
  return p.replace(/\.(?:tsx?|jsx?|mjs|cjs)$/, "");
@@ -6071,7 +6049,7 @@ function buildImportTargets(entries) {
6071
6049
  for (const { item, file, target } of entries) {
6072
6050
  const rel3 = stripExt(file.path.replace(/\\/g, "/").replace(/^\.?\//, ""));
6073
6051
  exact.set(`@/${rel3}`, target);
6074
- if (itemKind(item) === "lib") lib.set(path17.posix.basename(rel3), target);
6052
+ if (itemKind(item) === "lib") lib.set(path16.posix.basename(rel3), target);
6075
6053
  }
6076
6054
  return { exact, lib };
6077
6055
  }
@@ -6147,7 +6125,7 @@ function insideRanges(ranges, at) {
6147
6125
  }
6148
6126
  var SPECIFIER_PATTERN = /(\bfrom\s*|\bimport\s*\(\s*|\bimport\s+|\brequire\s*\(\s*)(["'])(@\/[^"'\n]+)\2/g;
6149
6127
  var STANDARD_LIB_PATTERN = /^@\/registry\/[^/]+\/lib\/(.+)$/;
6150
- function relativeSpecifier(fromFile, toFile, impl = path17) {
6128
+ function relativeSpecifier(fromFile, toFile, impl = path16) {
6151
6129
  let rel3 = toPosix(impl.relative(impl.dirname(fromFile), stripExt(toFile)), impl);
6152
6130
  if (!rel3.startsWith(".")) rel3 = `./${rel3}`;
6153
6131
  return rel3;
@@ -6175,10 +6153,10 @@ function rewriteImports(content, fileTarget, targets) {
6175
6153
  }
6176
6154
  var RESOLVE_EXTS = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", "/index.ts", "/index.tsx", "/index.js"];
6177
6155
  function relativeSpecifierResolves(fromFile, spec) {
6178
- const base = path17.resolve(path17.dirname(fromFile), spec);
6156
+ const base = path16.resolve(path16.dirname(fromFile), spec);
6179
6157
  return RESOLVE_EXTS.some((ext) => {
6180
6158
  try {
6181
- return statSync5(base + ext).isFile();
6159
+ return statSync4(base + ext).isFile();
6182
6160
  } catch {
6183
6161
  return false;
6184
6162
  }
@@ -6227,7 +6205,7 @@ function planFiles(layout, items) {
6227
6205
  }
6228
6206
  const prev = byTarget.get(target);
6229
6207
  if (prev !== void 0) {
6230
- errors.push(`${item.name}: ${toPosix(path17.relative(layout.root, target))} \uB97C ${prev} \uC640 \uD568\uAED8 \uC501\uB2C8\uB2E4(\uAC19\uC740 \uC704\uCE58)`);
6208
+ errors.push(`${item.name}: ${toPosix(path16.relative(layout.root, target))} \uB97C ${prev} \uC640 \uD568\uAED8 \uC501\uB2C8\uB2E4(\uAC19\uC740 \uC704\uCE58)`);
6231
6209
  continue;
6232
6210
  }
6233
6211
  byTarget.set(target, item.name);
@@ -6253,18 +6231,19 @@ function missingDependencies(root, items) {
6253
6231
  const installCommand = detectInstallCommand(root);
6254
6232
  let pkg;
6255
6233
  try {
6256
- const text = readFileSync8(path17.join(root, "package.json"), "utf8").replace(/^\uFEFF/, "");
6234
+ const text = readFileSync7(path16.join(root, "package.json"), "utf8").replace(/^\uFEFF/, "");
6257
6235
  const parsed = JSON.parse(text);
6258
6236
  pkg = isPlainObject(parsed) ? parsed : void 0;
6259
6237
  } catch {
6260
6238
  pkg = void 0;
6261
6239
  }
6262
6240
  const ranges = selectUtilsDependencies(detectTailwind(root, pkg));
6241
+ const rootPkg = pkg !== void 0 ? workspaceRootPackage(root) ?? null : null;
6263
6242
  const specs = {};
6264
6243
  for (const item of items) {
6265
6244
  for (const dep of item.dependencies) {
6266
6245
  const name = dependencyName(dep);
6267
- if (pkg !== void 0 && hasDependency(pkg, name) !== void 0) continue;
6246
+ if (declaredDependency(root, pkg, name, rootPkg) !== void 0) continue;
6268
6247
  if (name in specs) continue;
6269
6248
  const explicit = dep.length > name.length ? dep.slice(name.length + 1) : void 0;
6270
6249
  specs[name] = explicit ?? ranges[name];
@@ -6280,18 +6259,16 @@ function dependencyName(spec) {
6280
6259
  }
6281
6260
  function addCommandForSpecs(installCommand, specs) {
6282
6261
  const args = Object.entries(specs).map(([name, range]) => range ? `"${name}@${range}"` : name).join(" ");
6283
- if (installCommand.startsWith("yarn")) return `yarn add ${args}`;
6284
- if (installCommand.startsWith("npm")) return `npm install ${args}`;
6285
- return `pnpm add ${args}`;
6262
+ return `${addCommandPrefix(installCommand)} ${args}`;
6286
6263
  }
6287
6264
  function rel2(root, p) {
6288
- return toPosix(path17.relative(root, p));
6265
+ return toPosix(path16.relative(root, p));
6289
6266
  }
6290
6267
  async function runAdd(cwd, requested, options, ctx) {
6291
6268
  const log = ctx.log ?? console.log;
6292
6269
  const error = ctx.error ?? console.error;
6293
6270
  const hints = { ...CLI_ADD_HINTS, ...ctx.hints };
6294
- const root = path17.resolve(cwd);
6271
+ const root = path16.resolve(cwd);
6295
6272
  const result = { exitCode: 1, written: [], overwritten: [], unchanged: [], skipped: [] };
6296
6273
  if (requested.length === 0) {
6297
6274
  error(`\uCD94\uAC00\uD560 \uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984\uC744 \uD558\uB098 \uC774\uC0C1 \uC801\uC73C\uC138\uC694. \uBAA9\uB85D: ${hints.listCommand}`);
@@ -6369,12 +6346,12 @@ async function runAdd(cwd, requested, options, ctx) {
6369
6346
  const existing = /* @__PURE__ */ new Map();
6370
6347
  const readErrors = [];
6371
6348
  for (const file of plan.files) {
6372
- if (!existsSync8(file.target)) {
6349
+ if (!existsSync7(file.target)) {
6373
6350
  existing.set(file, null);
6374
6351
  continue;
6375
6352
  }
6376
6353
  try {
6377
- existing.set(file, readFileSync8(file.target, "utf8"));
6354
+ existing.set(file, readFileSync7(file.target, "utf8"));
6378
6355
  } catch (e) {
6379
6356
  readErrors.push(
6380
6357
  `${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})`
@@ -6448,7 +6425,7 @@ async function runAdd(cwd, requested, options, ctx) {
6448
6425
  try {
6449
6426
  const before = escapeReason(root, d.file.target);
6450
6427
  if (before) return stopWriting(p, before);
6451
- await fs13.ensureDir(path17.dirname(d.file.target));
6428
+ await fs13.ensureDir(path16.dirname(d.file.target));
6452
6429
  const after = checkParentInside(root, d.file.target);
6453
6430
  if (after) return stopWriting(p, after);
6454
6431
  actual = await writeNoFollow(d.file.target, d.file.content, actual);
@@ -6535,7 +6512,7 @@ async function createClientFor(cwd, notify, env = process.env, clientOptions = {
6535
6512
  const { guardConfigRegistry, ...options } = clientOptions;
6536
6513
  let config = null;
6537
6514
  try {
6538
- config = await readAxisConfig(path17.resolve(cwd));
6515
+ config = await readAxisConfig(path16.resolve(cwd));
6539
6516
  } catch {
6540
6517
  config = null;
6541
6518
  }