@axis-ds/cli 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,6 +44,13 @@ axis theme add ontology
44
44
  - `@axis-ds/tokens` 가 없거나 1.3.0 미만이면 목록 대신 설치 · 업그레이드 안내를 내고 종료 코드 1 로 끝납니다.
45
45
  - `axis check` 는 `axis.config.json` 의 `brand` 와 CSS 의 브랜드 import 가 맞는지도 봅니다.
46
46
 
47
+ ## 프로젝트 검증 (`axis check`)
48
+
49
+ - Tailwind 구성 항목: Tailwind 4 이상(설치본, 없으면 `package.json` 선언으로 판정)은 설정 파일 대신 전역 CSS(`globals.css` · `app/globals.css` · `src/app/globals.css` · `src/globals.css` · `styles/globals.css` 순)의 `@import "tailwindcss"` 를 봅니다. Tailwind 3 이하는 `tailwind.config.ts` · `.js` · `.mjs` · `.cjs` 를 찾습니다.
50
+ - 이 항목은 Tailwind 진입 import 만 봅니다. `@axis-ds/tokens` 의 Tailwind 연동은 Tailwind 3 preset(`@axis-ds/tokens/tailwind`)뿐이라, Tailwind 4 에서 PASS 여도 `bg-primary` 같은 AXIS 색 클래스가 만들어진다는 뜻은 아닙니다.
51
+ - FAIL 이 하나라도 있으면 종료 코드 1 로 끝납니다. WARN 만 있으면 0 입니다(1.3.0 부터, 이전에는 결과와 관계없이 0).
52
+ - MCP `axis.check_project` 도 같은 항목 · 문구를 냅니다.
53
+
47
54
  ## 문서
48
55
 
49
56
  자세한 사용법은 [AXIS Design System 문서](https://axis.minu.best)를 참고하세요.
@@ -84,7 +84,7 @@ ${result}`;
84
84
  console.log(chalk.bold("\uBC29\uBC95 3: \uCF54\uB4DC \uBCF5\uC0AC"));
85
85
  console.log(chalk.gray(" 1. v0.app\uC5D0\uC11C \uCF54\uB4DC \uD0ED \uC5F4\uAE30"));
86
86
  console.log(chalk.gray(" 2. \uD30C\uC77C\uBCC4\uB85C \uCF54\uB4DC \uBCF5\uC0AC"));
87
- console.log(chalk.gray(" 3. axis-cli v0 convert\uB85C \uBCC0\uD658\n"));
87
+ console.log(chalk.gray(" 3. npx @axis-ds/cli v0 convert\uB85C \uBCC0\uD658\n"));
88
88
  const { method } = await prompts({
89
89
  type: "select",
90
90
  name: "method",
@@ -118,7 +118,7 @@ ${result}`;
118
118
  console.log(chalk.bold("3. \uB85C\uCEEC\uC5D0\uC11C \uD074\uB860:"));
119
119
  console.log(chalk.cyan(" git clone https://github.com/your-org/v0-project.git\n"));
120
120
  console.log(chalk.bold("4. AXIS \uBCC0\uD658:"));
121
- console.log(chalk.cyan(" axis-cli v0 convert ./v0-project/components/*.tsx\n"));
121
+ console.log(chalk.cyan(" npx @axis-ds/cli v0 convert ./v0-project/components/*.tsx\n"));
122
122
  console.log(chalk.gray("\uD301: GitHub Actions\uB85C \uC790\uB3D9 \uBCC0\uD658 \uC6CC\uD06C\uD50C\uB85C\uB3C4 \uC124\uC815 \uAC00\uB2A5\uD569\uB2C8\uB2E4.\n"));
123
123
  }
124
124
  // ZIP 파일에서 변환
@@ -134,7 +134,7 @@ ${result}`;
134
134
  console.log(chalk.yellow("\nZIP \uBCC0\uD658 \uAE30\uB2A5\uC740 \uCD94\uD6C4 \uAD6C\uD604 \uC608\uC815\uC785\uB2C8\uB2E4."));
135
135
  console.log(chalk.gray("\uD604\uC7AC\uB294 \uC218\uB3D9\uC73C\uB85C \uC555\uCD95 \uD574\uC81C \uD6C4 convert \uBA85\uB839\uC5B4\uB97C \uC0AC\uC6A9\uD558\uC138\uC694:\n"));
136
136
  console.log(chalk.cyan(" unzip v0-project.zip -d ./v0-project"));
137
- console.log(chalk.cyan(" axis-cli v0 convert ./v0-project/components/*.tsx\n"));
137
+ console.log(chalk.cyan(" npx @axis-ds/cli v0 convert ./v0-project/components/*.tsx\n"));
138
138
  }
139
139
  // 클립보드에서 변환
140
140
  async convertFromClipboard() {
@@ -185,7 +185,7 @@ ${result}`;
185
185
  console.log(chalk.gray(" AI/LLM \uAD00\uB828 UI\uC5D0\uB294 @axis-ds/agentic-ui \uC0AC\uC6A9:"));
186
186
  console.log(chalk.cyan(" import { StreamingText } from '@axis-ds/agentic-ui'\n"));
187
187
  console.log(chalk.bold("5. \uC790\uB3D9 \uBCC0\uD658"));
188
- console.log(chalk.cyan(" axis-cli v0 convert <file.tsx>\n"));
188
+ console.log(chalk.cyan(" npx @axis-ds/cli v0 convert <file.tsx>\n"));
189
189
  }
190
190
  };
191
191
  function getV0Url(path2 = "") {
@@ -852,7 +852,7 @@ async function initSync(owner, repo, projectNumber) {
852
852
  console.log(chalk.gray(` \uD504\uB85C\uC81D\uD2B8: #${projectNumber}`));
853
853
  console.log();
854
854
  console.log(chalk.cyan("\uB2E4\uC74C \uBA85\uB839\uC5B4\uB85C \uB3D9\uAE30\uD654\uB97C \uC2DC\uC791\uD558\uC138\uC694:"));
855
- console.log(chalk.cyan(" npx axis-cli sync"));
855
+ console.log(chalk.cyan(" npx @axis-ds/cli sync"));
856
856
  console.log();
857
857
  } catch (error) {
858
858
  spinner.fail(`\uC624\uB958: ${error.message}`);
@@ -35,8 +35,8 @@ var MonetClient = class {
35
35
  );
36
36
  }
37
37
  console.log(chalk.gray("\n\uC0AC\uC6A9\uBC95:"));
38
- console.log(chalk.gray(" axis-cli monet browse <category> # \uCE74\uD14C\uACE0\uB9AC \uCEF4\uD3EC\uB10C\uD2B8 \uBCF4\uAE30"));
39
- console.log(chalk.gray(" axis-cli monet search <query> # \uCEF4\uD3EC\uB10C\uD2B8 \uAC80\uC0C9\n"));
38
+ console.log(chalk.gray(" npx @axis-ds/cli monet browse <category> # \uCE74\uD14C\uACE0\uB9AC \uCEF4\uD3EC\uB10C\uD2B8 \uBCF4\uAE30"));
39
+ console.log(chalk.gray(" npx @axis-ds/cli monet search <query> # \uCEF4\uD3EC\uB10C\uD2B8 \uAC80\uC0C9\n"));
40
40
  }
41
41
  // 컴포넌트 검색 (웹 URL 안내)
42
42
  async searchComponents(query) {
@@ -82,7 +82,7 @@ var MonetClient = class {
82
82
  console.log(chalk.gray("\n\uCEF4\uD3EC\uB10C\uD2B8 \uAC00\uC838\uC624\uAE30:"));
83
83
  console.log(chalk.gray(" 1. \uC6F9\uC5D0\uC11C \uCEF4\uD3EC\uB10C\uD2B8 \uC120\uD0DD"));
84
84
  console.log(chalk.gray(" 2. Copy Code \uBC84\uD2BC \uD074\uB9AD"));
85
- console.log(chalk.gray(" 3. axis-cli monet import \uC2E4\uD589\n"));
85
+ console.log(chalk.gray(" 3. npx @axis-ds/cli monet import \uC2E4\uD589\n"));
86
86
  }
87
87
  // 카테고리별 예시 컴포넌트
88
88
  getCategoryExamples(category) {
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  MonetClient
4
- } from "./chunk-WRDOGNSG.js";
4
+ } from "./chunk-ZVVACWEW.js";
5
5
  import {
6
6
  V0Client
7
- } from "./chunk-GCOWKKXG.js";
7
+ } from "./chunk-AHQT77FJ.js";
8
8
  import {
9
9
  registerSyncCommand
10
- } from "./chunk-D26GW2HO.js";
10
+ } from "./chunk-QORBOSUA.js";
11
11
  import {
12
12
  fetchTemplateDetail,
13
13
  fetchTemplateIndex
@@ -15,12 +15,12 @@ import {
15
15
 
16
16
  // src/index.ts
17
17
  import { Command } from "commander";
18
- import chalk9 from "chalk";
18
+ import chalk11 from "chalk";
19
19
  import ora6 from "ora";
20
- import fs10 from "fs-extra";
21
- import path11 from "path";
20
+ import fs11 from "fs-extra";
21
+ import path12 from "path";
22
22
  import { createRequire as createRequire2 } from "module";
23
- import prompts2 from "prompts";
23
+ import prompts3 from "prompts";
24
24
 
25
25
  // src/library/base-collector.ts
26
26
  import crypto from "crypto";
@@ -484,11 +484,11 @@ var ShadcnCollector = class extends BaseCollector {
484
484
  /**
485
485
  * 파일 타입 추론
486
486
  */
487
- getFileType(path12) {
488
- if (path12.includes("hook") || path12.startsWith("use")) return "hook";
489
- if (path12.includes("util") || path12.includes("lib")) return "util";
490
- if (path12.endsWith(".css")) return "style";
491
- if (path12.endsWith(".d.ts") || path12.includes("types")) return "type";
487
+ getFileType(path13) {
488
+ if (path13.includes("hook") || path13.startsWith("use")) return "hook";
489
+ if (path13.includes("util") || path13.includes("lib")) return "util";
490
+ if (path13.endsWith(".css")) return "style";
491
+ if (path13.endsWith(".d.ts") || path13.includes("types")) return "type";
492
492
  return "component";
493
493
  }
494
494
  };
@@ -1474,7 +1474,7 @@ var LibraryCurator = class {
1474
1474
  const index = await this.loadIndex();
1475
1475
  if (!index) {
1476
1476
  console.log(chalk2.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
1477
- console.log(chalk2.gray(" axis-cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
1477
+ console.log(chalk2.gray(" npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
1478
1478
  return;
1479
1479
  }
1480
1480
  console.log(chalk2.blue("\n\u{1F4CA} Library Curator - \uD1B5\uACC4\n"));
@@ -2099,6 +2099,178 @@ function getBrand(baseDir, name) {
2099
2099
  };
2100
2100
  }
2101
2101
 
2102
+ // src/template/tailwind-core.ts
2103
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
2104
+ import { join as join2, resolve as resolve2 } from "path";
2105
+ function hasDependency(pkg, name) {
2106
+ for (const field of ["dependencies", "devDependencies"]) {
2107
+ const deps = pkg[field];
2108
+ if (typeof deps === "object" && deps !== null && name in deps) {
2109
+ return String(deps[name]);
2110
+ }
2111
+ }
2112
+ return void 0;
2113
+ }
2114
+ function isPlainObject(value) {
2115
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2116
+ }
2117
+ var VERSION = String.raw`v?(\d+)(?:\.(\d+|[xX*]))?(?:\.(\d+|[xX*]))?(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?`;
2118
+ function versionParts(token) {
2119
+ const m = new RegExp(`^${VERSION}$`).exec(token);
2120
+ if (!m) return void 0;
2121
+ if (/^v?0\.0\.0-/.test(token)) return void 0;
2122
+ return { major: Number(m[1]), minor: m[2], patch: m[3] };
2123
+ }
2124
+ var isWild = (part) => part === void 0 || /^[xX*]$/.test(part);
2125
+ function comparatorBounds(op, v) {
2126
+ switch (op) {
2127
+ case ">=":
2128
+ return { lower: v.major };
2129
+ case ">":
2130
+ return { lower: isWild(v.minor) ? v.major + 1 : v.major };
2131
+ case "<=":
2132
+ return { upper: v.major };
2133
+ case "<": {
2134
+ const zeroOrWild = (part) => isWild(part) || Number(part) === 0;
2135
+ return { upper: zeroOrWild(v.minor) && zeroOrWild(v.patch) ? v.major - 1 : v.major };
2136
+ }
2137
+ default:
2138
+ return { lower: v.major, upper: v.major };
2139
+ }
2140
+ }
2141
+ function tailwindMajorBounds(range) {
2142
+ const r = range.trim();
2143
+ if (r === "" || r.includes("||")) return void 0;
2144
+ const simple = new RegExp(`^(?:\\^|~|=)?\\s*(${VERSION})$`).exec(r);
2145
+ if (simple) {
2146
+ const v = versionParts(simple[1]);
2147
+ return v ? { lower: v.major, upper: v.major } : void 0;
2148
+ }
2149
+ const hyphen = new RegExp(`^(${VERSION})\\s+-\\s+(${VERSION})$`).exec(r);
2150
+ if (hyphen) {
2151
+ const tokens2 = r.split(/\s+-\s+/);
2152
+ const a = versionParts(tokens2[0]);
2153
+ const b = versionParts(tokens2[1]);
2154
+ return a && b && a.major <= b.major ? { lower: a.major, upper: b.major } : void 0;
2155
+ }
2156
+ const tokens = r.replace(/(>=|<=|>|<|=)\s+/g, "$1").split(/\s+/);
2157
+ const lowers = [];
2158
+ const uppers = [];
2159
+ for (const t of tokens) {
2160
+ const c = /^(>=|<=|>|<|=)(.+)$/.exec(t);
2161
+ if (!c) return void 0;
2162
+ const v = versionParts(c[2]);
2163
+ if (v === void 0) return void 0;
2164
+ const b = comparatorBounds(c[1], v);
2165
+ if (b.lower !== void 0) lowers.push(b.lower);
2166
+ if (b.upper !== void 0) uppers.push(b.upper);
2167
+ }
2168
+ if (lowers.length === 0) return void 0;
2169
+ const lower = Math.max(...lowers);
2170
+ const upper = uppers.length > 0 ? Math.min(...uppers) : void 0;
2171
+ if (upper !== void 0 && upper < lower) return void 0;
2172
+ return upper !== void 0 ? { lower, upper } : { lower };
2173
+ }
2174
+ function majorWithin(major, bounds) {
2175
+ return major >= bounds.lower && (bounds.upper === void 0 || major <= bounds.upper);
2176
+ }
2177
+ function majorFromVersion(version) {
2178
+ if (typeof version !== "string") return void 0;
2179
+ const v = version.trim();
2180
+ const m = /^v?(\d+)\.\d+\.\d+(?:[-+][0-9A-Za-z.+-]*)?$/.exec(v);
2181
+ if (!m || /^v?0\.0\.0-/.test(v)) return void 0;
2182
+ return Number(m[1]);
2183
+ }
2184
+ function detectTailwind(baseDirInput, pkg) {
2185
+ const baseDir = resolve2(baseDirInput);
2186
+ const installedFile = join2(baseDir, "node_modules", "tailwindcss", "package.json");
2187
+ const declared = pkg ? hasDependency(pkg, "tailwindcss") : void 0;
2188
+ const bounds = declared !== void 0 ? tailwindMajorBounds(declared) : void 0;
2189
+ const declaredMajor = bounds?.lower;
2190
+ try {
2191
+ const installed = JSON.parse(readFileSync2(installedFile, "utf8"));
2192
+ const version = isPlainObject(installed) ? installed.version : void 0;
2193
+ const major = majorFromVersion(version);
2194
+ if (major !== void 0) {
2195
+ const found = { major, source: "installed", value: String(version) };
2196
+ if (declared !== void 0 && bounds !== void 0 && !majorWithin(major, bounds)) {
2197
+ found.mismatch = { declared, declaredMajor: bounds.lower };
2198
+ }
2199
+ return found;
2200
+ }
2201
+ } catch {
2202
+ }
2203
+ if (declared !== void 0) {
2204
+ if (declaredMajor !== void 0) return { major: declaredMajor, source: "declared", value: declared };
2205
+ return { source: "none", value: declared };
2206
+ }
2207
+ return { source: "none" };
2208
+ }
2209
+ var TAILWIND_CONFIG_FILES = [
2210
+ "tailwind.config.ts",
2211
+ "tailwind.config.js",
2212
+ "tailwind.config.mjs",
2213
+ "tailwind.config.cjs"
2214
+ ];
2215
+ var TAILWIND_CSS_CANDIDATES = [
2216
+ "globals.css",
2217
+ "app/globals.css",
2218
+ "src/app/globals.css",
2219
+ "src/globals.css",
2220
+ "styles/globals.css"
2221
+ ];
2222
+ var TAILWIND_IMPORT = /@import\s+(?:url\(\s*)?["']tailwindcss["']/;
2223
+ function hasTailwindImport(css) {
2224
+ return TAILWIND_IMPORT.test(css.replace(/\/\*[\s\S]*?\*\//g, ""));
2225
+ }
2226
+ function readPackageJson(baseDir) {
2227
+ try {
2228
+ const parsed = JSON.parse(readFileSync2(join2(baseDir, "package.json"), "utf8"));
2229
+ return isPlainObject(parsed) ? parsed : void 0;
2230
+ } catch {
2231
+ return void 0;
2232
+ }
2233
+ }
2234
+ function checkTailwindSetup(baseDirInput) {
2235
+ const baseDir = resolve2(baseDirInput);
2236
+ const tailwind = detectTailwind(baseDir, readPackageJson(baseDir));
2237
+ if (tailwind.major !== void 0 && tailwind.major >= 4) {
2238
+ const label = `Tailwind ${tailwind.major}`;
2239
+ for (const candidate of TAILWIND_CSS_CANDIDATES) {
2240
+ const file = join2(baseDir, candidate);
2241
+ if (!existsSync2(file)) continue;
2242
+ const found = hasTailwindImport(readFileSync2(file, "utf8"));
2243
+ return {
2244
+ name: "tailwind.config",
2245
+ severity: found ? "pass" : "warn",
2246
+ message: found ? `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uAC00 \uC788\uC2B5\uB2C8\uB2E4` : `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4`
2247
+ };
2248
+ }
2249
+ return {
2250
+ name: "tailwind.config",
2251
+ severity: "warn",
2252
+ message: `${label}: @import "tailwindcss" \uB97C \uD655\uC778\uD560 CSS \uD30C\uC77C\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4`
2253
+ };
2254
+ }
2255
+ const [tsFile, ...otherFiles] = TAILWIND_CONFIG_FILES;
2256
+ const tsPath = join2(baseDir, tsFile);
2257
+ if (existsSync2(tsPath)) {
2258
+ const content = readFileSync2(tsPath, "utf8");
2259
+ const hasTokens = content.includes("--background") || content.includes("hsl(var(");
2260
+ return {
2261
+ name: "tailwind.config",
2262
+ severity: hasTokens ? "pass" : "warn",
2263
+ message: hasTokens ? "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070\uC774 \uC124\uC815\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4" : "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070 \uC124\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
2264
+ };
2265
+ }
2266
+ for (const file of otherFiles) {
2267
+ if (existsSync2(join2(baseDir, file))) {
2268
+ return { name: "tailwind.config", severity: "warn", message: `${file} \uC874\uC7AC (TypeScript \uAD8C\uC7A5)` };
2269
+ }
2270
+ }
2271
+ return { name: "tailwind.config", severity: "fail", message: "tailwind.config \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4" };
2272
+ }
2273
+
2102
2274
  // src/template/template-check.ts
2103
2275
  var SEVERITY_ICON = {
2104
2276
  pass: chalk6.green("PASS"),
@@ -2109,7 +2281,7 @@ async function collectCheckResults(dir) {
2109
2281
  const baseDir = path8.resolve(dir || ".");
2110
2282
  const results = [];
2111
2283
  results.push(await checkFileExists(baseDir, "axis.config.json", "axis.config.json"));
2112
- results.push(await checkTailwindConfig(baseDir));
2284
+ results.push(checkTailwindSetup(baseDir));
2113
2285
  results.push(await checkGlobalsCss(baseDir));
2114
2286
  results.push(await checkUtils(baseDir));
2115
2287
  results.push(await checkDependencies(baseDir));
@@ -2148,6 +2320,7 @@ async function runCheck(dir) {
2148
2320
  } else {
2149
2321
  console.log(chalk6.green("\n\uBAA8\uB4E0 \uAC80\uC99D\uC744 \uD1B5\uACFC\uD588\uC2B5\uB2C8\uB2E4!"));
2150
2322
  }
2323
+ return { pass: passCount, warn: warnCount, fail: failCount };
2151
2324
  }
2152
2325
  async function checkFileExists(baseDir, fileName, label) {
2153
2326
  const exists = await fs9.pathExists(path8.join(baseDir, fileName));
@@ -2157,31 +2330,6 @@ async function checkFileExists(baseDir, fileName, label) {
2157
2330
  message: exists ? `${label} \uD30C\uC77C\uC774 \uC874\uC7AC\uD569\uB2C8\uB2E4` : `${label} \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 'axis init'\uC744 \uC2E4\uD589\uD558\uC138\uC694`
2158
2331
  };
2159
2332
  }
2160
- async function checkTailwindConfig(baseDir) {
2161
- const tsPath = path8.join(baseDir, "tailwind.config.ts");
2162
- const jsPath = path8.join(baseDir, "tailwind.config.js");
2163
- if (await fs9.pathExists(tsPath)) {
2164
- const content = await fs9.readFile(tsPath, "utf-8");
2165
- const hasTokens = content.includes("--background") || content.includes("hsl(var(");
2166
- return {
2167
- name: "tailwind.config",
2168
- severity: hasTokens ? "pass" : "warn",
2169
- message: hasTokens ? "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070\uC774 \uC124\uC815\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4" : "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070 \uC124\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
2170
- };
2171
- }
2172
- if (await fs9.pathExists(jsPath)) {
2173
- return {
2174
- name: "tailwind.config",
2175
- severity: "warn",
2176
- message: "tailwind.config.js \uC874\uC7AC (TypeScript \uAD8C\uC7A5)"
2177
- };
2178
- }
2179
- return {
2180
- name: "tailwind.config",
2181
- severity: "fail",
2182
- message: "tailwind.config \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
2183
- };
2184
- }
2185
2333
  async function checkGlobalsCss(baseDir) {
2186
2334
  const candidates = [
2187
2335
  "globals.css",
@@ -2402,7 +2550,8 @@ function registerTemplateCommand(program2) {
2402
2550
  }
2403
2551
  function registerCheckCommand(program2) {
2404
2552
  program2.command("check").description("AXIS \uD504\uB85C\uC81D\uD2B8 \uC124\uC815 \uAC80\uC99D").option("-d, --dir <path>", "\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC").action(async (options) => {
2405
- await runCheck(options.dir);
2553
+ const summary = await runCheck(options.dir);
2554
+ if (summary.fail > 0) process.exitCode = 1;
2406
2555
  });
2407
2556
  }
2408
2557
 
@@ -2411,12 +2560,12 @@ import chalk8 from "chalk";
2411
2560
  import path10 from "path";
2412
2561
 
2413
2562
  // src/theme/theme-add.ts
2414
- import { accessSync, constants, existsSync as existsSync2, readFileSync as readFileSync2, realpathSync, unlinkSync, writeFileSync } from "fs";
2563
+ import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync3, realpathSync, unlinkSync, writeFileSync } from "fs";
2415
2564
  import path9 from "path";
2416
2565
  var TOKENS_DEPENDENCY_RANGE = `^${MIN_BRAND_TOKENS_VERSION}`;
2417
2566
  var THEME_PACKAGE = "@axis-ds/theme";
2418
2567
  function readText(file) {
2419
- return existsSync2(file) ? readFileSync2(file, "utf8") : null;
2568
+ return existsSync3(file) ? readFileSync3(file, "utf8") : null;
2420
2569
  }
2421
2570
  function eolOf(text) {
2422
2571
  return text.includes("\r\n") ? "\r\n" : "\n";
@@ -2492,12 +2641,12 @@ function isStylesheet(realPath) {
2492
2641
  return path9.extname(realPath).toLowerCase() === ".css";
2493
2642
  }
2494
2643
  function detectInstallCommand(baseDir) {
2495
- if (existsSync2(path9.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
2496
- if (existsSync2(path9.join(baseDir, "yarn.lock"))) return "yarn install";
2497
- if (existsSync2(path9.join(baseDir, "package-lock.json"))) return "npm install";
2644
+ if (existsSync3(path9.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
2645
+ if (existsSync3(path9.join(baseDir, "yarn.lock"))) return "yarn install";
2646
+ if (existsSync3(path9.join(baseDir, "package-lock.json"))) return "npm install";
2498
2647
  return "pnpm install";
2499
2648
  }
2500
- function hasDependency(pkg, name) {
2649
+ function hasDependency2(pkg, name) {
2501
2650
  for (const field of ["dependencies", "devDependencies"]) {
2502
2651
  const deps = pkg[field];
2503
2652
  if (typeof deps === "object" && deps !== null && name in deps) {
@@ -2506,7 +2655,7 @@ function hasDependency(pkg, name) {
2506
2655
  }
2507
2656
  return void 0;
2508
2657
  }
2509
- function isPlainObject(value) {
2658
+ function isPlainObject2(value) {
2510
2659
  return typeof value === "object" && value !== null && !Array.isArray(value);
2511
2660
  }
2512
2661
  function planThemeAdd(baseDirInput, brand) {
@@ -2531,7 +2680,7 @@ function planThemeAdd(baseDirInput, brand) {
2531
2680
  let config;
2532
2681
  try {
2533
2682
  const parsed = JSON.parse(configText);
2534
- if (!isPlainObject(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
2683
+ if (!isPlainObject2(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
2535
2684
  config = parsed;
2536
2685
  } catch (err) {
2537
2686
  plan.errors.push({ kind: "invalid-config", message: err.message });
@@ -2543,7 +2692,7 @@ function planThemeAdd(baseDirInput, brand) {
2543
2692
  }
2544
2693
  plan.tokens = resolveTokens(baseDir);
2545
2694
  if (plan.tokens.status === "ok" && plan.tokens.indexPath) {
2546
- const data = JSON.parse(readFileSync2(plan.tokens.indexPath, "utf8"));
2695
+ const data = JSON.parse(readFileSync3(plan.tokens.indexPath, "utf8"));
2547
2696
  const entries = Array.isArray(data.brands) ? data.brands : [];
2548
2697
  const entry = entries.find((e) => e.name === brand);
2549
2698
  if (!entry) {
@@ -2572,7 +2721,7 @@ function planThemeAdd(baseDirInput, brand) {
2572
2721
  plan.writes = [];
2573
2722
  return plan;
2574
2723
  }
2575
- const before = readFileSync2(location.path, "utf8");
2724
+ const before = readFileSync3(location.path, "utf8");
2576
2725
  const imported = findBrandImports(before);
2577
2726
  const otherBrands = [...new Set(imported.filter((n) => n !== brand))];
2578
2727
  if (imported.includes(brand)) {
@@ -2598,19 +2747,19 @@ function planThemeAdd(baseDirInput, brand) {
2598
2747
  let pkg;
2599
2748
  try {
2600
2749
  const parsed = JSON.parse(pkgText);
2601
- if (!isPlainObject(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
2750
+ if (!isPlainObject2(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
2602
2751
  pkg = parsed;
2603
2752
  } catch (err) {
2604
2753
  plan.errors.push({ kind: "invalid-package-json", message: err.message });
2605
2754
  plan.writes = [];
2606
2755
  return plan;
2607
2756
  }
2608
- const themeMissing = hasDependency(pkg, THEME_PACKAGE) === void 0;
2609
- const declared = hasDependency(pkg, TOKENS_PACKAGE);
2757
+ const themeMissing = hasDependency2(pkg, THEME_PACKAGE) === void 0;
2758
+ const declared = hasDependency2(pkg, TOKENS_PACKAGE);
2610
2759
  if (declared !== void 0) {
2611
2760
  plan.dependency = { action: "present", declaredRange: declared, upgrade, themeMissing };
2612
2761
  } else {
2613
- const deps = isPlainObject(pkg.dependencies) ? { ...pkg.dependencies } : {};
2762
+ const deps = isPlainObject2(pkg.dependencies) ? { ...pkg.dependencies } : {};
2614
2763
  deps[TOKENS_PACKAGE] = TOKENS_DEPENDENCY_RANGE;
2615
2764
  const next = { ...pkg, dependencies: deps };
2616
2765
  plan.dependency = { action: "add", upgrade, themeMissing };
@@ -2985,74 +3134,265 @@ function registerThemeCommand(program2) {
2985
3134
  });
2986
3135
  }
2987
3136
 
2988
- // src/index.ts
2989
- var { version: CLI_VERSION } = createRequire2(import.meta.url)("../package.json");
2990
- var REGISTRY_URL = process.env.AXIS_REGISTRY_URL || "https://axis.minu.best/r";
2991
- var program = new Command();
2992
- program.name("axis").description("AXIS Design System CLI - shadcn \uD638\uD658 \uCEF4\uD3EC\uB10C\uD2B8 \uC124\uCE58 \uB3C4\uAD6C").version(CLI_VERSION);
2993
- program.command("init").description("\uD504\uB85C\uC81D\uD2B8\uC5D0 AXIS Design System \uCD08\uAE30\uD654").option("-y, --yes", "\uAE30\uBCF8\uAC12\uC73C\uB85C \uC790\uB3D9 \uC124\uC815").action(async (options) => {
2994
- console.log(chalk9.blue("\n\u{1F3A8} AXIS Design System \uCD08\uAE30\uD654\n"));
2995
- const config = options.yes ? {
2996
- componentsDir: "./src/components/ui",
2997
- tailwindConfig: "./tailwind.config.ts",
2998
- globalCss: "./src/app/globals.css"
2999
- } : await prompts2([
3000
- {
3001
- type: "text",
3002
- name: "componentsDir",
3003
- message: "\uCEF4\uD3EC\uB10C\uD2B8 \uB514\uB809\uD1A0\uB9AC:",
3004
- initial: "./src/components/ui"
3005
- },
3006
- {
3007
- type: "text",
3008
- name: "tailwindConfig",
3009
- message: "Tailwind \uC124\uC815 \uD30C\uC77C:",
3010
- initial: "./tailwind.config.ts"
3011
- },
3012
- {
3013
- type: "text",
3014
- name: "globalCss",
3015
- message: "\uAE00\uB85C\uBC8C CSS \uD30C\uC77C:",
3016
- initial: "./src/app/globals.css"
3017
- }
3018
- ]);
3137
+ // src/init/index.ts
3138
+ import chalk10 from "chalk";
3139
+ import prompts2 from "prompts";
3140
+
3141
+ // src/init/init.ts
3142
+ import { accessSync as accessSync2, constants as constants2, existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
3143
+ import path11 from "path";
3144
+ import chalk9 from "chalk";
3145
+ import fs10 from "fs-extra";
3146
+ var CLSX_RANGE = "^2.1.1";
3147
+ var TAILWIND_MERGE_RANGES = {
3148
+ tailwind4: "^3.4.0",
3149
+ tailwind3: "^2.6.0"
3150
+ };
3151
+ function selectUtilsDependencies(tailwind) {
3152
+ return {
3153
+ clsx: CLSX_RANGE,
3154
+ "tailwind-merge": tailwind.major !== void 0 && tailwind.major >= 4 ? TAILWIND_MERGE_RANGES.tailwind4 : TAILWIND_MERGE_RANGES.tailwind3
3155
+ };
3156
+ }
3157
+ function tailwindWarnings(tailwind, installCommand) {
3158
+ const out = [];
3159
+ if (tailwind.source === "none" && tailwind.value !== void 0) {
3160
+ out.push(
3161
+ `! tailwindcss \uC120\uC5B8(${tailwind.value})\uC740 \uD310\uC815 \uBD88\uAC00 - \uAE30\uBCF8\uAC12 \uC0AC\uC6A9(Tailwind 3, tailwind-merge ${TAILWIND_MERGE_RANGES.tailwind3}). Tailwind 4 \uC774\uC0C1\uC774\uBA74 tailwind-merge \uB97C ${TAILWIND_MERGE_RANGES.tailwind4} \uC73C\uB85C \uBC14\uAFB8\uC138\uC694.`
3162
+ );
3163
+ }
3164
+ if (tailwind.mismatch) {
3165
+ out.push(
3166
+ `! \uC124\uCE58\uBCF8 tailwindcss ${tailwind.value}(major ${tailwind.major})\uC640 package.json \uC120\uC5B8 ${tailwind.mismatch.declared}(major ${tailwind.mismatch.declaredMajor})\uAC00 \uB2E4\uB984 - \uC124\uCE58\uBCF8\uC744 \uB530\uB790\uC2B5\uB2C8\uB2E4. ${installCommand} \uB4A4 tailwind-merge \uBC94\uC704\uB97C \uB2E4\uC2DC \uD655\uC778\uD558\uC138\uC694.`
3167
+ );
3168
+ }
3169
+ return out;
3170
+ }
3171
+ function describeTailwindBasis(tailwind) {
3172
+ if (tailwind.source === "installed") return `\uC124\uCE58\uB41C tailwindcss ${tailwind.value}`;
3173
+ if (tailwind.source === "declared") return `package.json \uC758 tailwindcss ${tailwind.value}`;
3174
+ if (tailwind.value !== void 0) {
3175
+ return `package.json \uC758 tailwindcss ${tailwind.value} \uB85C \uBC84\uC804\uC744 \uD310\uC815\uD558\uC9C0 \uBABB\uD574 \uAE30\uBCF8\uAC12(Tailwind 3)`;
3176
+ }
3177
+ return "tailwindcss \uB97C \uCC3E\uC9C0 \uBABB\uD574 \uAE30\uBCF8\uAC12(Tailwind 3)";
3178
+ }
3179
+ var UTILS_TS_CONTENT = `import { type ClassValue, clsx } from "clsx";
3180
+ import { twMerge } from "tailwind-merge";
3181
+
3182
+ export function cn(...inputs: ClassValue[]) {
3183
+ return twMerge(clsx(inputs));
3184
+ }
3185
+ `;
3186
+ var INIT_DEFAULTS = {
3187
+ componentsDir: "./src/components/ui",
3188
+ tailwindConfig: "./tailwind.config.ts",
3189
+ globalCss: "./src/app/globals.css"
3190
+ };
3191
+ var INIT_NEXT_STEP_COMMAND = "npx @axis-ds/cli add button";
3192
+ var BOM = "\uFEFF";
3193
+ function addCommandFor(installCommand, deps) {
3194
+ const specs = Object.entries(deps).map(([name, range]) => `"${name}@${range}"`).join(" ");
3195
+ if (installCommand.startsWith("yarn")) return `yarn add ${specs}`;
3196
+ if (installCommand.startsWith("npm")) return `npm install ${specs}`;
3197
+ return `pnpm add ${specs}`;
3198
+ }
3199
+ function planUtilsDependencies(baseDirInput) {
3200
+ const baseDir = path11.resolve(baseDirInput);
3201
+ const installCommand = detectInstallCommand(baseDir);
3202
+ const tailwind0 = detectTailwind(baseDir);
3203
+ const ranges0 = selectUtilsDependencies(tailwind0);
3204
+ const plan = {
3205
+ action: "no-package-json",
3206
+ added: [],
3207
+ present: [],
3208
+ ranges: ranges0,
3209
+ tailwind: tailwind0,
3210
+ installCommand,
3211
+ addCommand: addCommandFor(installCommand, ranges0)
3212
+ };
3213
+ const pkgFile = path11.join(baseDir, "package.json");
3214
+ if (!existsSync4(pkgFile)) return plan;
3215
+ const unwritable = (reason) => ({ ...plan, action: "unwritable", reason });
3216
+ let where;
3217
+ try {
3218
+ where = realPathInside(baseDir, pkgFile);
3219
+ } catch (err) {
3220
+ return unwritable(err.message);
3221
+ }
3222
+ if (!where.inside) return unwritable(`\uC2E4\uC81C \uC704\uCE58(${where.realPath})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`);
3223
+ let text;
3224
+ try {
3225
+ text = readFileSync4(pkgFile, "utf8");
3226
+ } catch (err) {
3227
+ return unwritable(err.message);
3228
+ }
3229
+ const bom = text.startsWith(BOM) ? BOM : "";
3230
+ const body = bom ? text.slice(1) : text;
3231
+ let pkg;
3232
+ try {
3233
+ const parsed = JSON.parse(body);
3234
+ if (!isPlainObject2(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
3235
+ pkg = parsed;
3236
+ } catch (err) {
3237
+ return unwritable(`JSON \uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${err.message}`);
3238
+ }
3239
+ plan.tailwind = detectTailwind(baseDir, pkg);
3240
+ plan.ranges = selectUtilsDependencies(plan.tailwind);
3241
+ plan.addCommand = addCommandFor(installCommand, plan.ranges);
3242
+ const missing = {};
3243
+ for (const [name, range] of Object.entries(plan.ranges)) {
3244
+ const declared = hasDependency2(pkg, name);
3245
+ if (declared !== void 0) plan.present.push({ name, range: declared });
3246
+ else missing[name] = range;
3247
+ }
3248
+ plan.added = Object.keys(missing);
3249
+ plan.addCommand = addCommandFor(installCommand, plan.added.length > 0 ? missing : plan.ranges);
3250
+ if (plan.added.length === 0) return { ...plan, action: "present" };
3251
+ if (pkg.dependencies !== void 0 && !isPlainObject2(pkg.dependencies)) {
3252
+ return unwritable("dependencies \uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
3253
+ }
3254
+ try {
3255
+ accessSync2(pkgFile, constants2.W_OK);
3256
+ } catch (err) {
3257
+ return unwritable(`\uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${err.message})`);
3258
+ }
3259
+ const deps = { ...pkg.dependencies ?? {}, ...missing };
3260
+ const after = bom + formatJsonLike(body, { ...pkg, dependencies: deps });
3261
+ return { ...plan, action: "add", write: { file: pkgFile, before: text, after } };
3262
+ }
3263
+ var defaultWriteFile = (file, data) => writeFileSync2(file, data);
3264
+ function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile) {
3265
+ const w = plan.write;
3266
+ if (plan.action !== "add" || !w) return false;
3267
+ const baseDir = path11.resolve(baseDirInput);
3268
+ const current = existsSync4(w.file) ? readFileSync4(w.file, "utf8") : null;
3269
+ if (current !== w.before) {
3270
+ throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
3271
+ }
3272
+ const where = realPathInside(baseDir, w.file);
3273
+ if (!where.inside) {
3274
+ 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. \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`);
3275
+ }
3276
+ JSON.parse(w.after.startsWith(BOM) ? w.after.slice(1) : w.after);
3277
+ try {
3278
+ writeFile(w.file, w.after);
3279
+ } catch (err) {
3280
+ const cause = err.message;
3281
+ let restored;
3282
+ try {
3283
+ writeFile(w.file, w.before);
3284
+ 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");
3285
+ restored = "\uC6D0\uB798 \uB0B4\uC6A9\uC73C\uB85C \uB418\uB3CC\uB838\uC2B5\uB2C8\uB2E4";
3286
+ } catch (restoreErr) {
3287
+ 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`;
3288
+ }
3289
+ throw new Error(`${w.file} \uC744 \uC4F0\uB294 \uB3C4\uC911 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4(${cause}). ${restored}.`);
3290
+ }
3291
+ return true;
3292
+ }
3293
+ function reportDependencies(plan, log) {
3294
+ const presentText = plan.present.map((p) => `${p.name} (${p.range})`).join(", ");
3295
+ const basis = ` tailwind-merge \uBC94\uC704 \uAE30\uC900: ${describeTailwindBasis(plan.tailwind)}`;
3296
+ const logBasis = () => {
3297
+ log(chalk9.gray(basis));
3298
+ for (const w of tailwindWarnings(plan.tailwind, plan.installCommand)) log(chalk9.yellow(` ${w}`));
3299
+ };
3300
+ if (plan.action === "add") {
3301
+ const addedText = plan.added.map((n) => `${n}@${plan.ranges[n]}`).join(", ");
3302
+ log(chalk9.green(`\u2713 package.json dependencies \uC5D0 \uCD94\uAC00: ${addedText}`));
3303
+ if (plan.present.length > 0) log(chalk9.gray(` \uC774\uBBF8 \uC788\uC74C(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
3304
+ if (plan.added.includes("tailwind-merge")) logBasis();
3305
+ log(chalk9.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk9.cyan(plan.installCommand)}`));
3306
+ } else if (plan.action === "present") {
3307
+ log(chalk9.green(`\u2713 utils.ts \uC758\uC874\uC131\uC774 package.json \uC5D0 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
3308
+ log(chalk9.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk9.cyan(plan.installCommand)}`));
3309
+ } else if (plan.action === "no-package-json") {
3310
+ log(chalk9.yellow("! package.json \uC774 \uC5C6\uC5B4 utils.ts \uC758\uC874\uC131(clsx, tailwind-merge)\uC744 \uCD94\uAC00\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."));
3311
+ log(chalk9.yellow(` \uC124\uCE58: ${chalk9.cyan(plan.addCommand)}`));
3312
+ logBasis();
3313
+ } else {
3314
+ log(chalk9.yellow(`! package.json \uC744 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(${plan.reason}).`));
3315
+ log(chalk9.yellow(` utils.ts \uC758\uC874\uC131 \uC124\uCE58: ${chalk9.cyan(plan.addCommand)}`));
3316
+ if (plan.addCommand.includes('"tailwind-merge@')) logBasis();
3317
+ }
3318
+ }
3319
+ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
3320
+ const baseDir = path11.resolve(baseDirInput);
3019
3321
  const axisConfig = createInitConfig(
3020
3322
  {
3021
- componentsDir: config.componentsDir,
3022
- tailwindConfig: config.tailwindConfig,
3023
- globalCss: config.globalCss
3323
+ componentsDir: answers.componentsDir,
3324
+ tailwindConfig: answers.tailwindConfig,
3325
+ globalCss: answers.globalCss
3024
3326
  },
3025
- REGISTRY_URL
3327
+ registryUrl
3026
3328
  );
3027
- await fs10.writeJSON("axis.config.json", axisConfig, { spaces: 2 });
3028
- console.log(chalk9.green("\u2713 axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
3029
- const utilsPath = path11.join(config.componentsDir, "utils.ts");
3329
+ await fs10.writeJSON(path11.join(baseDir, "axis.config.json"), axisConfig, { spaces: 2 });
3330
+ log(chalk9.green("\u2713 axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
3331
+ const utilsPath = path11.resolve(baseDir, answers.componentsDir, "utils.ts");
3030
3332
  await fs10.ensureDir(path11.dirname(utilsPath));
3031
- await fs10.writeFile(
3032
- utilsPath,
3033
- `import { type ClassValue, clsx } from "clsx";
3034
- import { twMerge } from "tailwind-merge";
3333
+ await fs10.writeFile(utilsPath, UTILS_TS_CONTENT);
3334
+ log(chalk9.green("\u2713 utils.ts \uC0DD\uC131 \uC644\uB8CC"));
3335
+ const plan = planUtilsDependencies(baseDir);
3336
+ try {
3337
+ applyUtilsDependencies(baseDir, plan);
3338
+ } catch (err) {
3339
+ log(chalk9.red(`\u2717 package.json \uC744 \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${err.message}`));
3340
+ log(chalk9.yellow(" axis.config.json \uACFC utils.ts \uB294 \uC774\uBBF8 \uB9CC\uB4E4\uC5B4\uC84C\uC2B5\uB2C8\uB2E4."));
3341
+ log(chalk9.yellow(` utils.ts \uC758\uC874\uC131 \uC124\uCE58: ${chalk9.cyan(plan.addCommand)}`));
3342
+ process.exitCode = 1;
3343
+ return;
3344
+ }
3345
+ reportDependencies(plan, log);
3346
+ log(chalk9.blue("\n\uCD08\uAE30\uD654 \uC644\uB8CC! \uC774\uC81C \uB2E4\uC74C \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD558\uC138\uC694:"));
3347
+ log(chalk9.cyan(` ${INIT_NEXT_STEP_COMMAND}
3348
+ `));
3349
+ }
3035
3350
 
3036
- export function cn(...inputs: ClassValue[]) {
3037
- return twMerge(clsx(inputs));
3351
+ // src/init/index.ts
3352
+ function registerInitCommand(program2, registryUrl) {
3353
+ program2.command("init").description("\uD504\uB85C\uC81D\uD2B8\uC5D0 AXIS Design System \uCD08\uAE30\uD654").option("-y, --yes", "\uAE30\uBCF8\uAC12\uC73C\uB85C \uC790\uB3D9 \uC124\uC815").action(async (options) => {
3354
+ console.log(chalk10.blue("\n\u{1F3A8} AXIS Design System \uCD08\uAE30\uD654\n"));
3355
+ const config = options.yes ? { ...INIT_DEFAULTS } : await prompts2([
3356
+ {
3357
+ type: "text",
3358
+ name: "componentsDir",
3359
+ message: "\uCEF4\uD3EC\uB10C\uD2B8 \uB514\uB809\uD1A0\uB9AC:",
3360
+ initial: INIT_DEFAULTS.componentsDir
3361
+ },
3362
+ {
3363
+ type: "text",
3364
+ name: "tailwindConfig",
3365
+ message: "Tailwind \uC124\uC815 \uD30C\uC77C:",
3366
+ initial: INIT_DEFAULTS.tailwindConfig
3367
+ },
3368
+ {
3369
+ type: "text",
3370
+ name: "globalCss",
3371
+ message: "\uAE00\uB85C\uBC8C CSS \uD30C\uC77C:",
3372
+ initial: INIT_DEFAULTS.globalCss
3373
+ }
3374
+ ]);
3375
+ await runInit(process.cwd(), config, registryUrl);
3376
+ });
3038
3377
  }
3039
- `
3040
- );
3041
- console.log(chalk9.green("\u2713 utils.ts \uC0DD\uC131 \uC644\uB8CC"));
3042
- console.log(chalk9.blue("\n\uCD08\uAE30\uD654 \uC644\uB8CC! \uC774\uC81C \uB2E4\uC74C \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD558\uC138\uC694:"));
3043
- console.log(chalk9.cyan(" npx axis-cli add button\n"));
3044
- });
3378
+
3379
+ // src/index.ts
3380
+ var { version: CLI_VERSION } = createRequire2(import.meta.url)("../package.json");
3381
+ var REGISTRY_URL = process.env.AXIS_REGISTRY_URL || "https://axis.minu.best/r";
3382
+ var program = new Command();
3383
+ program.name("axis").description("AXIS Design System CLI - shadcn \uD638\uD658 \uCEF4\uD3EC\uB10C\uD2B8 \uC124\uCE58 \uB3C4\uAD6C").version(CLI_VERSION);
3384
+ registerInitCommand(program, REGISTRY_URL);
3045
3385
  program.command("add <component>").description("\uCEF4\uD3EC\uB10C\uD2B8 \uCD94\uAC00").option("--agentic", "Agentic UI \uCEF4\uD3EC\uB10C\uD2B8 \uCD94\uAC00").option("-y, --yes", "\uD655\uC778 \uC5C6\uC774 \uB36E\uC5B4\uC4F0\uAE30").action(async (component, options) => {
3046
3386
  const spinner = ora6(`${component} \uCEF4\uD3EC\uB10C\uD2B8 \uAC00\uC838\uC624\uB294 \uC911...`).start();
3047
3387
  try {
3048
- const configPath = path11.resolve("axis.config.json");
3049
- if (!await fs10.pathExists(configPath)) {
3388
+ const configPath = path12.resolve("axis.config.json");
3389
+ if (!await fs11.pathExists(configPath)) {
3050
3390
  spinner.fail(
3051
3391
  "axis.config.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.\n \uD574\uACB0: \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0\uC11C 'npx @axis-ds/cli init'\uC744 \uC2E4\uD589\uD558\uC138\uC694.\n \uCC38\uACE0: https://axis.minu.best/docs/guides/quick-start"
3052
3392
  );
3053
3393
  process.exit(1);
3054
3394
  }
3055
- const config = await fs10.readJSON(configPath);
3395
+ const config = await fs11.readJSON(configPath);
3056
3396
  const category = options.agentic ? "agentic" : "ui";
3057
3397
  const componentInfo = await getComponentInfo(component, category);
3058
3398
  if (!componentInfo) {
@@ -3065,10 +3405,10 @@ program.command("add <component>").description("\uCEF4\uD3EC\uB10C\uD2B8 \uCD94\
3065
3405
  }
3066
3406
  spinner.text = `${component} \uCEF4\uD3EC\uB10C\uD2B8 \uC124\uCE58 \uC911...`;
3067
3407
  for (const file of componentInfo.files) {
3068
- const filePath = path11.join(config.componentsDir, file.path);
3069
- if (await fs10.pathExists(filePath)) {
3408
+ const filePath = path12.join(config.componentsDir, file.path);
3409
+ if (await fs11.pathExists(filePath)) {
3070
3410
  if (!options.yes) {
3071
- const { overwrite } = await prompts2({
3411
+ const { overwrite } = await prompts3({
3072
3412
  type: "confirm",
3073
3413
  name: "overwrite",
3074
3414
  message: `${file.path}\uC774(\uAC00) \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4. \uB36E\uC5B4\uC4F0\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`,
@@ -3077,13 +3417,13 @@ program.command("add <component>").description("\uCEF4\uD3EC\uB10C\uD2B8 \uCD94\
3077
3417
  if (!overwrite) continue;
3078
3418
  }
3079
3419
  }
3080
- await fs10.ensureDir(path11.dirname(filePath));
3081
- await fs10.writeFile(filePath, file.content);
3420
+ await fs11.ensureDir(path12.dirname(filePath));
3421
+ await fs11.writeFile(filePath, file.content);
3082
3422
  }
3083
- spinner.succeed(chalk9.green(`${component} \uCEF4\uD3EC\uB10C\uD2B8 \uCD94\uAC00 \uC644\uB8CC`));
3423
+ spinner.succeed(chalk11.green(`${component} \uCEF4\uD3EC\uB10C\uD2B8 \uCD94\uAC00 \uC644\uB8CC`));
3084
3424
  if (componentInfo.dependencies.length > 0) {
3085
- console.log(chalk9.yellow("\n\uD544\uC694\uD55C \uC758\uC874\uC131:"));
3086
- console.log(chalk9.cyan(` pnpm add ${componentInfo.dependencies.join(" ")}`));
3425
+ console.log(chalk11.yellow("\n\uD544\uC694\uD55C \uC758\uC874\uC131:"));
3426
+ console.log(chalk11.cyan(` pnpm add ${componentInfo.dependencies.join(" ")}`));
3087
3427
  }
3088
3428
  } catch (error) {
3089
3429
  spinner.fail(
@@ -3095,7 +3435,7 @@ program.command("add <component>").description("\uCEF4\uD3EC\uB10C\uD2B8 \uCD94\
3095
3435
  }
3096
3436
  });
3097
3437
  program.command("list").description("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uCEF4\uD3EC\uB10C\uD2B8 \uBAA9\uB85D").option("--category <type>", "\uCE74\uD14C\uACE0\uB9AC \uD544\uD130 (ui, agentic)").action(async (options) => {
3098
- console.log(chalk9.blue("\n\u{1F4E6} AXIS Design System \uCEF4\uD3EC\uB10C\uD2B8\n"));
3438
+ console.log(chalk11.blue("\n\u{1F4E6} AXIS Design System \uCEF4\uD3EC\uB10C\uD2B8\n"));
3099
3439
  const components = {
3100
3440
  ui: [
3101
3441
  { name: "button", description: "\uAE30\uBCF8 \uBC84\uD2BC \uCEF4\uD3EC\uB10C\uD2B8" },
@@ -3123,9 +3463,9 @@ program.command("list").description("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uCEF4\uD3E
3123
3463
  ]
3124
3464
  };
3125
3465
  const showCategory = (category, items) => {
3126
- console.log(chalk9.bold(category === "ui" ? "Core UI" : "Agentic UI"));
3466
+ console.log(chalk11.bold(category === "ui" ? "Core UI" : "Agentic UI"));
3127
3467
  items.forEach((c) => {
3128
- console.log(` ${chalk9.cyan(c.name.padEnd(20))} ${chalk9.gray(c.description)}`);
3468
+ console.log(` ${chalk11.cyan(c.name.padEnd(20))} ${chalk11.gray(c.description)}`);
3129
3469
  });
3130
3470
  console.log();
3131
3471
  };
@@ -3135,8 +3475,8 @@ program.command("list").description("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uCEF4\uD3E
3135
3475
  if (!options.category || options.category === "agentic") {
3136
3476
  showCategory("agentic", components.agentic);
3137
3477
  }
3138
- console.log(chalk9.gray("\uC0AC\uC6A9\uBC95: npx axis-cli add <component-name>"));
3139
- console.log(chalk9.gray("Agentic: npx axis-cli add <component-name> --agentic\n"));
3478
+ console.log(chalk11.gray("\uC0AC\uC6A9\uBC95: npx @axis-ds/cli add <component-name>"));
3479
+ console.log(chalk11.gray("Agentic: npx @axis-ds/cli add <component-name> --agentic\n"));
3140
3480
  });
3141
3481
  var monetCmd = program.command("monet").description("Monet Design \uCEF4\uD3EC\uB10C\uD2B8 \uAD00\uB9AC (https://monet.design)");
3142
3482
  monetCmd.command("list").alias("ls").description("Monet \uCE74\uD14C\uACE0\uB9AC \uBAA9\uB85D").action(async () => {
@@ -3156,24 +3496,24 @@ monetCmd.command("import").alias("i").description("\uD074\uB9BD\uBCF4\uB4DC\uC5D
3156
3496
  await client.importFromClipboard();
3157
3497
  });
3158
3498
  monetCmd.command("setup").description("Monet MCP \uC11C\uBC84 \uC124\uC815 \uC548\uB0B4").action(() => {
3159
- console.log(chalk9.blue("\n\u{1F527} Monet MCP \uC11C\uBC84 \uC124\uC815\n"));
3160
- console.log(chalk9.bold("1. API \uD0A4 \uBC1C\uAE09:"));
3161
- console.log(chalk9.cyan(" https://monet.design/mcp\n"));
3162
- console.log(chalk9.bold("2. \uD658\uACBD \uBCC0\uC218 \uC124\uC815:"));
3163
- console.log(chalk9.gray(" .env \uD30C\uC77C\uC5D0 \uCD94\uAC00:"));
3164
- console.log(chalk9.cyan(" MONET_API_KEY=your-api-key-here\n"));
3165
- console.log(chalk9.bold("3. Claude Code MCP \uC124\uC815:"));
3166
- console.log(chalk9.gray(" .claude/mcp.json\uC5D0\uC11C monet \uC11C\uBC84 \uD65C\uC131\uD654:\n"));
3499
+ console.log(chalk11.blue("\n\u{1F527} Monet MCP \uC11C\uBC84 \uC124\uC815\n"));
3500
+ console.log(chalk11.bold("1. API \uD0A4 \uBC1C\uAE09:"));
3501
+ console.log(chalk11.cyan(" https://monet.design/mcp\n"));
3502
+ console.log(chalk11.bold("2. \uD658\uACBD \uBCC0\uC218 \uC124\uC815:"));
3503
+ console.log(chalk11.gray(" .env \uD30C\uC77C\uC5D0 \uCD94\uAC00:"));
3504
+ console.log(chalk11.cyan(" MONET_API_KEY=your-api-key-here\n"));
3505
+ console.log(chalk11.bold("3. Claude Code MCP \uC124\uC815:"));
3506
+ console.log(chalk11.gray(" .claude/mcp.json\uC5D0\uC11C monet \uC11C\uBC84 \uD65C\uC131\uD654:\n"));
3167
3507
  console.log(
3168
- chalk9.cyan(` "monet": {
3508
+ chalk11.cyan(` "monet": {
3169
3509
  "url": "https://www.monet.design/api/remote/mcp",
3170
3510
  "headers": { "Authorization": "Bearer \${MONET_API_KEY}" },
3171
3511
  "disabled": false
3172
3512
  }
3173
3513
  `)
3174
3514
  );
3175
- console.log(chalk9.bold("4. Claude Code \uC7AC\uC2DC\uC791 \uD6C4 \uC0AC\uC6A9:"));
3176
- console.log(chalk9.gray(' "monet\uC5D0\uC11C hero \uCEF4\uD3EC\uB10C\uD2B8 \uCC3E\uC544\uC918"\n'));
3515
+ console.log(chalk11.bold("4. Claude Code \uC7AC\uC2DC\uC791 \uD6C4 \uC0AC\uC6A9:"));
3516
+ console.log(chalk11.gray(' "monet\uC5D0\uC11C hero \uCEF4\uD3EC\uB10C\uD2B8 \uCC3E\uC544\uC918"\n'));
3177
3517
  });
3178
3518
  var v0Cmd = program.command("v0").description("V0 (v0.app) \uCF54\uB4DC \uBCC0\uD658 \uBC0F \uD1B5\uD569");
3179
3519
  v0Cmd.command("convert <file>").alias("c").description("V0 \uCF54\uB4DC\uB97C AXIS \uC2A4\uD0C0\uC77C\uB85C \uBCC0\uD658").option("-o, --output <path>", "\uCD9C\uB825 \uD30C\uC77C \uACBD\uB85C").action(async (file, options) => {
@@ -3210,18 +3550,18 @@ libraryCmd.command("collect").alias("c").description("\uC678\uBD80 \uC18C\uC2A4\
3210
3550
  total += result.collected;
3211
3551
  failed += result.failed;
3212
3552
  }
3213
- console.log(chalk9.blue(`
3553
+ console.log(chalk11.blue(`
3214
3554
  \u{1F4CA} \uC218\uC9D1 \uC644\uB8CC: ${total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8`));
3215
3555
  if (failed > 0) {
3216
- console.log(chalk9.yellow(` \uC2E4\uD328: ${failed}\uAC1C`));
3556
+ console.log(chalk11.yellow(` \uC2E4\uD328: ${failed}\uAC1C`));
3217
3557
  }
3218
3558
  });
3219
3559
  libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9AC \uCEF4\uD3EC\uB10C\uD2B8 \uBAA9\uB85D").option("-c, --category <category>", "\uCE74\uD14C\uACE0\uB9AC \uD544\uD130").option("-s, --source <source>", "\uC18C\uC2A4 \uD544\uD130").action(async (options) => {
3220
3560
  const curator = new LibraryCurator();
3221
3561
  const index = await curator.loadIndex();
3222
3562
  if (!index) {
3223
- console.log(chalk9.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
3224
- console.log(chalk9.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
3563
+ console.log(chalk11.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
3564
+ console.log(chalk11.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
3225
3565
  return;
3226
3566
  }
3227
3567
  let components = index.components;
@@ -3231,7 +3571,7 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
3231
3571
  if (options.source) {
3232
3572
  components = components.filter((c) => c.source.type === options.source);
3233
3573
  }
3234
- console.log(chalk9.blue(`
3574
+ console.log(chalk11.blue(`
3235
3575
  \u{1F4E6} Library Components (${components.length}\uAC1C)
3236
3576
  `));
3237
3577
  const byCategory = /* @__PURE__ */ new Map();
@@ -3243,14 +3583,14 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
3243
3583
  byCategory.get(cat).push(comp);
3244
3584
  }
3245
3585
  for (const [category, items] of byCategory) {
3246
- console.log(chalk9.bold(`${category} (${items.length})`));
3586
+ console.log(chalk11.bold(`${category} (${items.length})`));
3247
3587
  for (const item of items.slice(0, 10)) {
3248
3588
  console.log(
3249
- ` ${chalk9.cyan(item.name.padEnd(25))} ${chalk9.gray(item.source.type.padEnd(8))} ${chalk9.gray(item.description.slice(0, 40))}`
3589
+ ` ${chalk11.cyan(item.name.padEnd(25))} ${chalk11.gray(item.source.type.padEnd(8))} ${chalk11.gray(item.description.slice(0, 40))}`
3250
3590
  );
3251
3591
  }
3252
3592
  if (items.length > 10) {
3253
- console.log(chalk9.gray(` ... \uC678 ${items.length - 10}\uAC1C`));
3593
+ console.log(chalk11.gray(` ... \uC678 ${items.length - 10}\uAC1C`));
3254
3594
  }
3255
3595
  console.log();
3256
3596
  }
@@ -3262,21 +3602,21 @@ libraryCmd.command("search <query>").alias("s").description("\uCEF4\uD3EC\uB10C\
3262
3602
  source: options.source
3263
3603
  });
3264
3604
  if (results.length === 0) {
3265
- console.log(chalk9.yellow(`
3605
+ console.log(chalk11.yellow(`
3266
3606
  '${query}'\uC5D0 \uB300\uD55C \uAC80\uC0C9 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
3267
3607
  `));
3268
3608
  return;
3269
3609
  }
3270
- console.log(chalk9.blue(`
3610
+ console.log(chalk11.blue(`
3271
3611
  \u{1F50D} '${query}' \uAC80\uC0C9 \uACB0\uACFC (${results.length}\uAC1C)
3272
3612
  `));
3273
3613
  for (const comp of results.slice(0, 20)) {
3274
3614
  console.log(
3275
- ` ${chalk9.cyan(comp.name.padEnd(25))} ${chalk9.gray(comp.source.type.padEnd(8))} ${chalk9.gray(comp.category.padEnd(12))} ${chalk9.gray(comp.description.slice(0, 30))}`
3615
+ ` ${chalk11.cyan(comp.name.padEnd(25))} ${chalk11.gray(comp.source.type.padEnd(8))} ${chalk11.gray(comp.category.padEnd(12))} ${chalk11.gray(comp.description.slice(0, 30))}`
3276
3616
  );
3277
3617
  }
3278
3618
  if (results.length > 20) {
3279
- console.log(chalk9.gray(`
3619
+ console.log(chalk11.gray(`
3280
3620
  ... \uC678 ${results.length - 20}\uAC1C`));
3281
3621
  }
3282
3622
  console.log();
@@ -3290,12 +3630,12 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
3290
3630
  const publisher2 = new Publisher();
3291
3631
  const index = await curator.loadIndex();
3292
3632
  if (!index) {
3293
- console.log(chalk9.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
3294
- console.log(chalk9.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
3633
+ console.log(chalk11.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
3634
+ console.log(chalk11.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
3295
3635
  return;
3296
3636
  }
3297
- console.log(chalk9.blue("\n\u{1F4E4} Library \uBC30\uCE58\n"));
3298
- console.log(chalk9.gray(`\uCD1D ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8
3637
+ console.log(chalk11.blue("\n\u{1F4E4} Library \uBC30\uCE58\n"));
3638
+ console.log(chalk11.gray(`\uCD1D ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8
3299
3639
  `));
3300
3640
  if (options.clean) {
3301
3641
  await publisher2.clean(options.output);
@@ -3306,17 +3646,17 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
3306
3646
  generateSearchIndex: true
3307
3647
  });
3308
3648
  if (result.success) {
3309
- console.log(chalk9.green(`
3649
+ console.log(chalk11.green(`
3310
3650
  \u2713 \uBC30\uCE58 \uC644\uB8CC`));
3311
- console.log(chalk9.gray(` - \uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC: ${result.outputDir}`));
3312
- console.log(chalk9.gray(` - \uC0DD\uC131\uB41C \uD30C\uC77C: ${result.files.length}\uAC1C`));
3313
- console.log(chalk9.gray(` - \uCE74\uD14C\uACE0\uB9AC: ${result.stats.categoriesPublished}\uAC1C`));
3314
- console.log(chalk9.gray(` - \uAC80\uC0C9 \uC778\uB371\uC2A4: ${result.stats.searchIndexSize}\uAC1C \uD56D\uBAA9`));
3651
+ console.log(chalk11.gray(` - \uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC: ${result.outputDir}`));
3652
+ console.log(chalk11.gray(` - \uC0DD\uC131\uB41C \uD30C\uC77C: ${result.files.length}\uAC1C`));
3653
+ console.log(chalk11.gray(` - \uCE74\uD14C\uACE0\uB9AC: ${result.stats.categoriesPublished}\uAC1C`));
3654
+ console.log(chalk11.gray(` - \uAC80\uC0C9 \uC778\uB371\uC2A4: ${result.stats.searchIndexSize}\uAC1C \uD56D\uBAA9`));
3315
3655
  } else {
3316
- console.log(chalk9.red(`
3656
+ console.log(chalk11.red(`
3317
3657
  \u2717 \uBC30\uCE58 \uC2E4\uD328`));
3318
3658
  for (const error of result.errors) {
3319
- console.log(chalk9.red(` - ${error}`));
3659
+ console.log(chalk11.red(` - ${error}`));
3320
3660
  }
3321
3661
  }
3322
3662
  console.log();
package/dist/monet.d.ts CHANGED
@@ -4,9 +4,9 @@
4
4
  * Monet (https://monet.design) 컴포넌트를 검색하고 AXIS 프로젝트에 가져옵니다.
5
5
  *
6
6
  * 사용법:
7
- * axis-cli monet list # 카테고리 목록
8
- * axis-cli monet search <query> # 컴포넌트 검색
9
- * axis-cli monet add <id> # 컴포넌트 추가
7
+ * npx @axis-ds/cli monet list # 카테고리 목록
8
+ * npx @axis-ds/cli monet search <query> # 컴포넌트 검색
9
+ * npx @axis-ds/cli monet add <id> # 컴포넌트 추가
10
10
  */
11
11
  declare const MONET_CATEGORIES: readonly [{
12
12
  readonly id: "hero";
package/dist/monet.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  MonetClient,
4
4
  getMonetMcpConfig,
5
5
  getMonetUrl
6
- } from "./chunk-WRDOGNSG.js";
6
+ } from "./chunk-ZVVACWEW.js";
7
7
  export {
8
8
  MONET_CATEGORIES,
9
9
  MonetClient,
@@ -9,7 +9,7 @@ import {
9
9
  parseContent,
10
10
  parseProjectTodo,
11
11
  registerSyncCommand
12
- } from "../chunk-D26GW2HO.js";
12
+ } from "../chunk-QORBOSUA.js";
13
13
  export {
14
14
  GitHubClient,
15
15
  STATUS_MAP,
package/dist/v0.d.ts CHANGED
@@ -4,9 +4,9 @@
4
4
  * V0 (https://v0.app) 생성 코드를 AXIS 프로젝트에 통합합니다.
5
5
  *
6
6
  * 사용법:
7
- * axis-cli v0 convert <file> # V0 코드를 AXIS 스타일로 변환
8
- * axis-cli v0 import <url> # V0 URL에서 가져오기
9
- * axis-cli v0 setup # GitHub 연동 안내
7
+ * npx @axis-ds/cli v0 convert <file> # V0 코드를 AXIS 스타일로 변환
8
+ * npx @axis-ds/cli v0 import <url> # V0 URL에서 가져오기
9
+ * npx @axis-ds/cli v0 setup # GitHub 연동 안내
10
10
  */
11
11
  declare class V0Client {
12
12
  convertCode(code: string, options?: {
package/dist/v0.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  V0Client,
3
3
  getV0Url,
4
4
  isV0Code
5
- } from "./chunk-GCOWKKXG.js";
5
+ } from "./chunk-AHQT77FJ.js";
6
6
  export {
7
7
  V0Client,
8
8
  getV0Url,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axis-ds/cli",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "description": "AXIS Design System - CLI for adding components (shadcn compatible)",
6
6
  "publishConfig": {