@axis-ds/cli 1.5.0 → 1.5.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
@@ -9,13 +9,15 @@ import {
9
9
  registerSyncCommand
10
10
  } from "./chunk-QORBOSUA.js";
11
11
  import {
12
+ AXIS_QUICK_START_URL,
13
+ AXIS_SITE_URL,
12
14
  fetchTemplateDetail,
13
15
  fetchTemplateIndex
14
- } from "./chunk-3WGMHDZL.js";
16
+ } from "./chunk-IQY3WUGG.js";
15
17
 
16
18
  // src/index.ts
17
19
  import { Command } from "commander";
18
- import chalk12 from "chalk";
20
+ import chalk13 from "chalk";
19
21
  import { createRequire as createRequire2 } from "module";
20
22
 
21
23
  // src/library/base-collector.ts
@@ -480,11 +482,11 @@ var ShadcnCollector = class extends BaseCollector {
480
482
  /**
481
483
  * 파일 타입 추론
482
484
  */
483
- getFileType(path16) {
484
- if (path16.includes("hook") || path16.startsWith("use")) return "hook";
485
- if (path16.includes("util") || path16.includes("lib")) return "util";
486
- if (path16.endsWith(".css")) return "style";
487
- if (path16.endsWith(".d.ts") || path16.includes("types")) return "type";
485
+ getFileType(path18) {
486
+ if (path18.includes("hook") || path18.startsWith("use")) return "hook";
487
+ if (path18.includes("util") || path18.includes("lib")) return "util";
488
+ if (path18.endsWith(".css")) return "style";
489
+ if (path18.endsWith(".d.ts") || path18.includes("types")) return "type";
488
490
  return "component";
489
491
  }
490
492
  };
@@ -863,9 +865,12 @@ import path2 from "path";
863
865
  var DEFAULT_PATHS = {
864
866
  uiReact: "packages/axis-ui-react/src",
865
867
  agenticUi: "packages/axis-agentic-ui/src",
866
- webComponents: "apps/web/src/app/components",
867
- webAgentic: "apps/web/src/app/agentic"
868
+ docsApp: "apps/web/src/app/(docs)"
869
+ };
870
+ var DOCS_SLUG_ALIASES = {
871
+ "agentic/approval-card": "agentic/approval-dialog"
868
872
  };
873
+ var NON_COMPONENT_FILE = /\.(test|spec|stories)\.tsx?$/;
869
874
  var AxisCollector = class extends BaseCollector {
870
875
  sourceType = "axis";
871
876
  rootDir;
@@ -875,28 +880,45 @@ var AxisCollector = class extends BaseCollector {
875
880
  this.rootDir = options.rootDir || process.cwd();
876
881
  this.paths = { ...DEFAULT_PATHS, ...options.paths };
877
882
  }
883
+ /** 스캔 순서: ui-react 먼저, agentic-ui 다음 (같은 이름이면 앞의 것) */
884
+ packageSources() {
885
+ return [
886
+ { base: this.paths.uiReact, category: "ui", route: "components" },
887
+ { base: this.paths.agenticUi, category: "agentic", route: "agentic" }
888
+ ];
889
+ }
878
890
  /**
879
891
  * AXIS 컴포넌트 목록 조회
880
892
  */
881
893
  async listComponents() {
882
894
  const items = [];
883
- items.push(...await this.scanPackage(this.paths.uiReact, "ui", "@axis-ds/ui-react"));
884
- items.push(...await this.scanPackage(this.paths.agenticUi, "agentic", "@axis-ds/agentic-ui"));
885
- items.push(...await this.scanWebDirectory(this.paths.webComponents, "ui"));
886
- items.push(...await this.scanWebDirectory(this.paths.webAgentic, "agentic"));
887
- const uniqueItems = /* @__PURE__ */ new Map();
888
- for (const item of items) {
889
- if (!uniqueItems.has(item.id)) {
890
- uniqueItems.set(item.id, item);
895
+ const seen = /* @__PURE__ */ new Set();
896
+ for (const pkg of this.packageSources()) {
897
+ for (const slug of await this.listComponentDirs(pkg.base)) {
898
+ const id = `axis-${slug}`;
899
+ if (seen.has(id)) continue;
900
+ seen.add(id);
901
+ const content = await fs2.readFile(
902
+ path2.join(this.rootDir, pkg.base, slug, "index.tsx"),
903
+ "utf-8"
904
+ );
905
+ const name = this.formatName(slug);
906
+ items.push({
907
+ id,
908
+ name,
909
+ description: this.extractDescription(content, slug) || `AXIS ${name} component`,
910
+ category: pkg.category,
911
+ source: "axis"
912
+ });
891
913
  }
892
914
  }
893
- return [...uniqueItems.values()];
915
+ return items;
894
916
  }
895
917
  /**
896
918
  * 단일 컴포넌트 수집
897
919
  */
898
920
  async collectComponent(id) {
899
- const slug = id.replace("axis-", "");
921
+ const slug = id.replace(/^axis-/, "");
900
922
  const componentInfo = await this.findComponent(slug);
901
923
  if (!componentInfo) {
902
924
  throw new Error(`AXIS component not found: ${slug}`);
@@ -913,138 +935,100 @@ var AxisCollector = class extends BaseCollector {
913
935
  const mainContent = codeFiles.map((f) => f.content).join("\n");
914
936
  const meta = this.createBaseMeta(
915
937
  componentInfo.name,
916
- this.extractDescription(mainContent) || `AXIS ${componentInfo.name} component`,
938
+ this.extractDescription(mainContent, slug) || `AXIS ${componentInfo.name} component`,
917
939
  codeFiles,
918
940
  {
919
941
  registry: "@axis",
920
- url: this.getDocsUrl(slug, componentInfo.category)
942
+ url: await this.resolveDocsUrl(slug, componentInfo.route)
921
943
  }
922
944
  );
923
945
  meta.category = componentInfo.category;
924
946
  return meta;
925
947
  }
926
948
  /**
927
- * 패키지 디렉토리 스캔
949
+ * 문서 URL 을 정합니다(WI-0057 D3).
950
+ * ① `<docsApp>/<route>/<slug>/page.tsx` 가 있으면 그 경로 ② 없으면 별칭 표의 대상이 실재할 때 그 경로
951
+ * ③ 둘 다 없으면 빈 문자열(library 상세 화면은 빈 URL 이면 문서 링크를 그리지 않습니다).
928
952
  */
929
- async scanPackage(packagePath, defaultCategory, registry) {
930
- const items = [];
931
- const fullPath = path2.join(this.rootDir, packagePath);
932
- if (!await fs2.pathExists(fullPath)) {
933
- return items;
934
- }
935
- const entries = await fs2.readdir(fullPath, { withFileTypes: true });
936
- for (const entry of entries) {
937
- if (entry.isDirectory()) {
938
- const componentDir = path2.join(fullPath, entry.name);
939
- const indexFile = path2.join(componentDir, "index.tsx");
940
- if (await fs2.pathExists(indexFile)) {
941
- const content = await fs2.readFile(indexFile, "utf-8");
942
- const name = this.formatName(entry.name);
943
- items.push({
944
- id: `axis-${entry.name}`,
945
- name,
946
- description: this.extractDescription(content) || `AXIS ${name} component`,
947
- category: this.classifyCategory(entry.name, content) || defaultCategory,
948
- source: "axis"
949
- });
950
- }
951
- } else if (entry.name.endsWith(".tsx") && entry.name !== "index.tsx") {
952
- const name = entry.name.replace(".tsx", "");
953
- const filePath = path2.join(fullPath, entry.name);
954
- const content = await fs2.readFile(filePath, "utf-8");
955
- items.push({
956
- id: `axis-${name}`,
957
- name: this.formatName(name),
958
- description: this.extractDescription(content) || `AXIS ${name} component`,
959
- category: this.classifyCategory(name, content) || defaultCategory,
960
- source: "axis"
961
- });
953
+ async resolveDocsUrl(slug, route) {
954
+ const direct = `${route}/${slug}`;
955
+ const candidates = [direct];
956
+ const alias = DOCS_SLUG_ALIASES[direct];
957
+ if (alias) candidates.push(alias);
958
+ for (const routePath of candidates) {
959
+ if (await this.docsRouteExists(routePath)) {
960
+ return `${AXIS_SITE_URL}/${routePath}`;
962
961
  }
963
962
  }
964
- return items;
963
+ return "";
964
+ }
965
+ async docsRouteExists(routePath) {
966
+ return fs2.pathExists(path2.join(this.rootDir, this.paths.docsApp, routePath, "page.tsx"));
965
967
  }
966
968
  /**
967
- * Web 디렉토리 스캔 (app router 구조)
969
+ * 패키지 src 바로 아래에서 index.tsx 가 있는 디렉터리 이름(정렬). 단일 파일(a11y.test.tsx 등)과
970
+ * index.tsx 가 없는 디렉터리(constants · test-utils)는 컴포넌트가 아닙니다.
968
971
  */
969
- async scanWebDirectory(webPath, defaultCategory) {
970
- const items = [];
971
- const fullPath = path2.join(this.rootDir, webPath);
972
+ async listComponentDirs(packagePath) {
973
+ const fullPath = path2.join(this.rootDir, packagePath);
972
974
  if (!await fs2.pathExists(fullPath)) {
973
- return items;
975
+ return [];
974
976
  }
975
977
  const entries = await fs2.readdir(fullPath, { withFileTypes: true });
978
+ const slugs = [];
976
979
  for (const entry of entries) {
977
- if (entry.isDirectory()) {
978
- const componentDir = path2.join(fullPath, entry.name);
979
- const pageFile = path2.join(componentDir, "page.tsx");
980
- if (await fs2.pathExists(pageFile)) {
981
- const content = await fs2.readFile(pageFile, "utf-8");
982
- const name = this.formatName(entry.name);
983
- items.push({
984
- id: `axis-${entry.name}`,
985
- name,
986
- description: this.extractDescription(content) || `AXIS ${name} component`,
987
- category: this.classifyCategory(entry.name, content) || defaultCategory,
988
- source: "axis"
989
- });
990
- }
980
+ if (!entry.isDirectory()) continue;
981
+ if (await fs2.pathExists(path2.join(fullPath, entry.name, "index.tsx"))) {
982
+ slugs.push(entry.name);
991
983
  }
992
984
  }
993
- return items;
985
+ return slugs.sort();
994
986
  }
995
987
  /**
996
988
  * 컴포넌트 찾기
997
989
  */
998
990
  async findComponent(slug) {
999
- const searchPaths = [
1000
- { base: this.paths.uiReact, category: "ui" },
1001
- { base: this.paths.agenticUi, category: "agentic" },
1002
- { base: this.paths.webComponents, category: "ui" },
1003
- { base: this.paths.webAgentic, category: "agentic" }
1004
- ];
1005
- for (const { base, category } of searchPaths) {
1006
- const fullBase = path2.join(this.rootDir, base);
1007
- const dirPath = path2.join(fullBase, slug);
1008
- if (await fs2.pathExists(dirPath)) {
1009
- const files = await this.getComponentFiles(dirPath);
1010
- if (files.length > 0) {
1011
- return {
1012
- name: this.formatName(slug),
1013
- files,
1014
- baseDir: dirPath,
1015
- category
1016
- };
1017
- }
1018
- }
1019
- const filePath = path2.join(fullBase, `${slug}.tsx`);
1020
- if (await fs2.pathExists(filePath)) {
991
+ for (const pkg of this.packageSources()) {
992
+ const dirPath = path2.join(this.rootDir, pkg.base, slug);
993
+ if (!await fs2.pathExists(path2.join(dirPath, "index.tsx"))) continue;
994
+ const files = await this.getComponentFiles(dirPath);
995
+ if (files.length > 0) {
1021
996
  return {
1022
997
  name: this.formatName(slug),
1023
- files: [filePath],
1024
- baseDir: fullBase,
1025
- category
998
+ files,
999
+ baseDir: dirPath,
1000
+ category: pkg.category,
1001
+ route: pkg.route
1026
1002
  };
1027
1003
  }
1028
1004
  }
1029
1005
  return null;
1030
1006
  }
1031
1007
  /**
1032
- * 컴포넌트 디렉토리에서 파일 목록 가져오기
1008
+ * 컴포넌트 디렉터리의 코드 파일(.ts · .tsx, 테스트 · 스토리 제외). 이름순으로 정렬해 결과가 매번 같습니다.
1033
1009
  */
1034
1010
  async getComponentFiles(dir) {
1035
- const files = [];
1036
1011
  const entries = await fs2.readdir(dir, { withFileTypes: true });
1037
- for (const entry of entries) {
1038
- if (entry.isFile() && (entry.name.endsWith(".tsx") || entry.name.endsWith(".ts"))) {
1039
- files.push(path2.join(dir, entry.name));
1040
- }
1041
- }
1042
- return files;
1012
+ return entries.filter(
1013
+ (entry) => entry.isFile() && (entry.name.endsWith(".tsx") || entry.name.endsWith(".ts")) && !NON_COMPONENT_FILE.test(entry.name)
1014
+ ).map((entry) => entry.name).sort().map((name) => path2.join(dir, name));
1043
1015
  }
1044
1016
  /**
1045
- * 설명 추출
1017
+ * 설명 추출. 컴포넌트 이름(slug 의 PascalCase)으로 선언된 곳 바로 앞의 JSDoc 첫 줄을 먼저 씁니다
1018
+ * (WI-0057: 파일 첫 JSDoc 은 Props 인터페이스 · 하위 컴포넌트 설명인 경우가 많았습니다).
1046
1019
  */
1047
- extractDescription(code) {
1020
+ extractDescription(code, slug) {
1021
+ if (slug) {
1022
+ const name = slug.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
1023
+ const decl = new RegExp(
1024
+ `/\\*\\*((?:(?!\\*/)[\\s\\S])*)\\*/\\s*(?:export\\s+)?(?:default\\s+)?(?:const|let|function|class)\\s+${name}\\b`
1025
+ );
1026
+ const m = code.match(decl);
1027
+ if (m) {
1028
+ const line = m[1].split("\n").map((l) => l.replace(/^\s*\*?\s?/, "").trim()).find((l) => l && !l.startsWith("@"));
1029
+ if (line) return line;
1030
+ }
1031
+ }
1048
1032
  const jsdocMatch = code.match(/\/\*\*\s*\n\s*\*\s*(.+)\n/);
1049
1033
  if (jsdocMatch) {
1050
1034
  return jsdocMatch[1].trim();
@@ -1072,14 +1056,6 @@ var AxisCollector = class extends BaseCollector {
1072
1056
  if (name.endsWith(".d.ts") || name.includes("types")) return "type";
1073
1057
  return "component";
1074
1058
  }
1075
- /**
1076
- * 문서 URL 생성
1077
- */
1078
- getDocsUrl(slug, category) {
1079
- const baseUrl = "https://axis.minu.best";
1080
- const route = category === "agentic" ? "agentic" : "components";
1081
- return `${baseUrl}/${route}/${slug}`;
1082
- }
1083
1059
  };
1084
1060
 
1085
1061
  // src/library/publisher.ts
@@ -1087,6 +1063,49 @@ import fs3 from "fs-extra";
1087
1063
  import path3 from "path";
1088
1064
  import chalk from "chalk";
1089
1065
  import ora from "ora";
1066
+ function toPublicComponent(component) {
1067
+ return {
1068
+ id: component.id,
1069
+ slug: component.slug,
1070
+ name: component.name,
1071
+ description: component.description,
1072
+ category: component.category,
1073
+ source: {
1074
+ type: component.source.type,
1075
+ registry: component.source.registry,
1076
+ url: component.source.url
1077
+ },
1078
+ tags: component.tags,
1079
+ code: component.code,
1080
+ preview: component.preview,
1081
+ status: component.status,
1082
+ updatedAt: component.updatedAt
1083
+ };
1084
+ }
1085
+ function toIndexEntry(c) {
1086
+ return {
1087
+ id: c.id,
1088
+ slug: c.slug,
1089
+ name: c.name,
1090
+ description: c.description,
1091
+ category: c.category,
1092
+ source: c.source.type,
1093
+ tags: c.tags,
1094
+ status: c.status
1095
+ };
1096
+ }
1097
+ function toSearchItem(c) {
1098
+ return {
1099
+ id: c.id,
1100
+ slug: c.slug,
1101
+ name: c.name,
1102
+ description: c.description,
1103
+ category: c.category,
1104
+ source: c.source.type,
1105
+ tags: c.tags,
1106
+ url: `/library/${c.category}/${c.slug}`
1107
+ };
1108
+ }
1090
1109
  var Publisher = class {
1091
1110
  defaultOutputDir = "apps/web/public/library";
1092
1111
  /**
@@ -1188,55 +1207,20 @@ var Publisher = class {
1188
1207
  updatedAt: index.updatedAt,
1189
1208
  stats: index.stats,
1190
1209
  categories: index.categories,
1191
- components: index.components.map((c) => ({
1192
- id: c.id,
1193
- slug: c.slug,
1194
- name: c.name,
1195
- description: c.description,
1196
- category: c.category,
1197
- source: c.source.type,
1198
- tags: c.tags,
1199
- status: c.status
1200
- }))
1210
+ components: index.components.map(toIndexEntry)
1201
1211
  };
1202
1212
  }
1203
1213
  /**
1204
1214
  * 공개용 컴포넌트 생성
1205
1215
  */
1206
1216
  createPublicComponent(component) {
1207
- return {
1208
- id: component.id,
1209
- slug: component.slug,
1210
- name: component.name,
1211
- description: component.description,
1212
- category: component.category,
1213
- source: {
1214
- type: component.source.type,
1215
- registry: component.source.registry,
1216
- url: component.source.url
1217
- },
1218
- tags: component.tags,
1219
- code: component.code,
1220
- preview: component.preview,
1221
- dependencies: component.dependencies,
1222
- status: component.status,
1223
- updatedAt: component.updatedAt
1224
- };
1217
+ return toPublicComponent(component);
1225
1218
  }
1226
1219
  /**
1227
1220
  * 검색 인덱스 생성
1228
1221
  */
1229
1222
  generateSearchIndex(index) {
1230
- return index.components.map((c) => ({
1231
- id: c.id,
1232
- slug: c.slug,
1233
- name: c.name,
1234
- description: c.description,
1235
- category: c.category,
1236
- source: c.source.type,
1237
- tags: c.tags,
1238
- url: `/library/${c.category}/${c.slug}`
1239
- }));
1223
+ return index.components.map(toSearchItem);
1240
1224
  }
1241
1225
  /**
1242
1226
  * JSON 파일 쓰기
@@ -1278,10 +1262,269 @@ var Publisher = class {
1278
1262
  };
1279
1263
  var publisher = new Publisher();
1280
1264
 
1281
- // src/library/index.ts
1265
+ // src/library/axis-refresh.ts
1282
1266
  import fs4 from "fs-extra";
1283
1267
  import path4 from "path";
1284
1268
  import chalk2 from "chalk";
1269
+ import { isDeepStrictEqual } from "util";
1270
+ var AXIS = "axis";
1271
+ var META_TAG_LIMIT = 50;
1272
+ function defaultUpdatedAt(now = /* @__PURE__ */ new Date()) {
1273
+ const kst = new Date(now.getTime() + 9 * 60 * 60 * 1e3);
1274
+ return `${kst.toISOString().slice(0, 10)}T00:00:00.000Z`;
1275
+ }
1276
+ function serialize(data) {
1277
+ return JSON.stringify(data, null, 2);
1278
+ }
1279
+ async function readJson(file) {
1280
+ if (!await fs4.pathExists(file)) {
1281
+ throw new Error(`library \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4: ${file}`);
1282
+ }
1283
+ return JSON.parse(await fs4.readFile(file, "utf-8"));
1284
+ }
1285
+ function withoutUpdatedAt(c) {
1286
+ const { updatedAt: _ignored, ...rest } = c;
1287
+ return JSON.parse(serialize(rest));
1288
+ }
1289
+ function computeStats(entries) {
1290
+ const bySource = {};
1291
+ const byCategory = {};
1292
+ for (const e of entries) {
1293
+ bySource[e.source] = (bySource[e.source] || 0) + 1;
1294
+ byCategory[e.category] = (byCategory[e.category] || 0) + 1;
1295
+ }
1296
+ return {
1297
+ total: entries.length,
1298
+ bySource,
1299
+ byCategory
1300
+ };
1301
+ }
1302
+ function aggregateTags(entries) {
1303
+ const counts = /* @__PURE__ */ new Map();
1304
+ for (const e of entries) {
1305
+ for (const tag of e.tags) counts.set(tag, (counts.get(tag) || 0) + 1);
1306
+ }
1307
+ return [...counts.entries()].map(([id, count]) => ({ id, name: id, count })).sort((a, b) => b.count - a.count);
1308
+ }
1309
+ async function refreshAxisLibrary(options) {
1310
+ const libraryDir = options.libraryDir || path4.join(options.rootDir, "apps/web/public/library");
1311
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/.test(options.updatedAt)) {
1312
+ throw new Error(`updatedAt \uC740 ISO 8601 UTC(\uC608: 2026-10-23T00:00:00.000Z)\uC5EC\uC57C \uD569\uB2C8\uB2E4: ${options.updatedAt}`);
1313
+ }
1314
+ const index = await readJson(path4.join(libraryDir, "index.json"));
1315
+ const searchIndex = await readJson(path4.join(libraryDir, "search-index.json"));
1316
+ const meta = await readJson(path4.join(libraryDir, "meta.json"));
1317
+ const categoryFiles = /* @__PURE__ */ new Map();
1318
+ for (const def of index.categories) {
1319
+ categoryFiles.set(def.id, await readJson(path4.join(libraryDir, "categories", `${def.id}.json`)));
1320
+ }
1321
+ const componentsDir = path4.join(libraryDir, "components");
1322
+ const existingFiles = /* @__PURE__ */ new Map();
1323
+ for (const name of (await fs4.readdir(componentsDir)).filter((n) => n.endsWith(".json")).sort()) {
1324
+ const raw = await fs4.readFile(path4.join(componentsDir, name), "utf-8");
1325
+ existingFiles.set(name.slice(0, -".json".length), { raw, data: JSON.parse(raw) });
1326
+ }
1327
+ const extIndex = /* @__PURE__ */ new Map();
1328
+ const extSearch = /* @__PURE__ */ new Map();
1329
+ const extCategory = /* @__PURE__ */ new Map();
1330
+ const extOrder = [];
1331
+ const remember = (id) => {
1332
+ if (!extOrder.includes(id)) extOrder.push(id);
1333
+ };
1334
+ for (const s of searchIndex) {
1335
+ if (s.source === AXIS) continue;
1336
+ extSearch.set(s.id, s);
1337
+ remember(s.id);
1338
+ }
1339
+ for (const e of index.components) {
1340
+ if (e.source === AXIS) continue;
1341
+ extIndex.set(e.id, e);
1342
+ remember(e.id);
1343
+ }
1344
+ const extCategoryOrder = /* @__PURE__ */ new Map();
1345
+ for (const [catId, file] of categoryFiles) {
1346
+ const ids = [];
1347
+ for (const c of file.components) {
1348
+ if (c.source.type === AXIS) continue;
1349
+ extCategory.set(c.id, c);
1350
+ ids.push(c.id);
1351
+ remember(c.id);
1352
+ }
1353
+ extCategoryOrder.set(catId, ids);
1354
+ }
1355
+ for (const id of extOrder) {
1356
+ const full = extCategory.get(id);
1357
+ const idx = extIndex.get(id);
1358
+ if (!full) {
1359
+ throw new Error(`\uC678\uBD80 \uD56D\uBAA9 ${id} \uAC00 categories/*.json \uC5D0 \uC5C6\uC5B4 \uC815\uD569\uC744 \uB9DE\uCD9C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4`);
1360
+ }
1361
+ if (!idx) extIndex.set(id, toIndexEntry(full));
1362
+ if (!extSearch.has(id)) extSearch.set(id, toSearchItem(full));
1363
+ if (!extCategoryOrder.get(full.category)?.includes(id)) {
1364
+ throw new Error(`\uC678\uBD80 \uD56D\uBAA9 ${id} \uC758 category(${full.category}) \uD30C\uC77C\uC5D0 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4`);
1365
+ }
1366
+ }
1367
+ const collector = options.collector || new AxisCollector({ rootDir: options.rootDir });
1368
+ const axisComponents = [];
1369
+ const added = [];
1370
+ const changed = [];
1371
+ const unchanged = [];
1372
+ const oldAxis = /* @__PURE__ */ new Map();
1373
+ for (const file of categoryFiles.values()) {
1374
+ for (const c of file.components) if (c.source.type === AXIS) oldAxis.set(c.id, c);
1375
+ }
1376
+ for (const f of existingFiles.values()) if (f.data.source?.type === AXIS) oldAxis.set(f.data.id, f.data);
1377
+ for (const item of await collector.listComponents()) {
1378
+ const fresh = toPublicComponent(await collector.collectComponent(item.id));
1379
+ const old = oldAxis.get(fresh.id);
1380
+ if (old && isDeepStrictEqual(withoutUpdatedAt(old), withoutUpdatedAt(fresh))) {
1381
+ fresh.updatedAt = old.updatedAt;
1382
+ unchanged.push(fresh.id);
1383
+ } else {
1384
+ fresh.updatedAt = options.updatedAt;
1385
+ const existedBefore = !!old || index.components.some((e) => e.id === fresh.id) || searchIndex.some((e) => e.id === fresh.id);
1386
+ (existedBefore ? changed : added).push(fresh.id);
1387
+ }
1388
+ axisComponents.push(JSON.parse(serialize(fresh)));
1389
+ }
1390
+ if (axisComponents.length === 0) {
1391
+ throw new Error(`AXIS \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD558\uB098\uB3C4 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(rootDir: ${options.rootDir})`);
1392
+ }
1393
+ const axisIds = new Set(axisComponents.map((c) => c.id));
1394
+ const oldAxisIds = /* @__PURE__ */ new Set();
1395
+ for (const e of index.components) if (e.source === AXIS) oldAxisIds.add(e.id);
1396
+ for (const e of searchIndex) if (e.source === AXIS) oldAxisIds.add(e.id);
1397
+ for (const file of categoryFiles.values()) {
1398
+ for (const c of file.components) if (c.source.type === AXIS) oldAxisIds.add(c.id);
1399
+ }
1400
+ for (const f of existingFiles.values()) if (f.data.source?.type === AXIS) oldAxisIds.add(f.data.id);
1401
+ const removed = [...oldAxisIds].filter((id) => !axisIds.has(id)).sort();
1402
+ const indexEntries = [
1403
+ ...extOrder.map((id) => extIndex.get(id)),
1404
+ ...axisComponents.map((c) => toIndexEntry(c))
1405
+ ];
1406
+ const searchItems = [
1407
+ ...extOrder.map((id) => extSearch.get(id)),
1408
+ ...axisComponents.map((c) => toSearchItem(c))
1409
+ ];
1410
+ const stats = computeStats(indexEntries);
1411
+ const allPublic = [...extOrder.map((id) => extCategory.get(id)), ...axisComponents];
1412
+ const updatedAt = allPublic.map((c) => c.updatedAt).filter(Boolean).sort().at(-1) || index.updatedAt;
1413
+ const outputs = /* @__PURE__ */ new Map();
1414
+ outputs.set(
1415
+ "index.json",
1416
+ serialize({
1417
+ version: index.version,
1418
+ updatedAt,
1419
+ stats,
1420
+ categories: index.categories,
1421
+ components: indexEntries
1422
+ })
1423
+ );
1424
+ outputs.set("search-index.json", serialize(searchItems));
1425
+ outputs.set(
1426
+ "meta.json",
1427
+ serialize({
1428
+ version: meta.version,
1429
+ updatedAt,
1430
+ stats,
1431
+ categories: meta.categories,
1432
+ tags: aggregateTags(indexEntries).slice(0, META_TAG_LIMIT)
1433
+ })
1434
+ );
1435
+ const knownCategories = new Set(index.categories.map((d) => d.id));
1436
+ for (const c of axisComponents) {
1437
+ if (!knownCategories.has(c.category)) {
1438
+ throw new Error(`AXIS \uD56D\uBAA9 ${c.id} \uC758 category(${c.category}) \uAC00 index.json categories \uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`);
1439
+ }
1440
+ }
1441
+ for (const def of index.categories) {
1442
+ const old = categoryFiles.get(def.id);
1443
+ const components = [
1444
+ ...(extCategoryOrder.get(def.id) || []).map((id) => extCategory.get(id)),
1445
+ ...axisComponents.filter((c) => c.category === def.id)
1446
+ ];
1447
+ outputs.set(
1448
+ `categories/${def.id}.json`,
1449
+ serialize({
1450
+ category: old.category,
1451
+ name: old.name,
1452
+ description: old.description,
1453
+ icon: old.icon,
1454
+ count: components.length,
1455
+ components
1456
+ })
1457
+ );
1458
+ }
1459
+ const finalSlugs = /* @__PURE__ */ new Set();
1460
+ const axisBySlug = new Map(axisComponents.map((c) => [c.slug, c]));
1461
+ for (const c of allPublic) finalSlugs.add(c.slug);
1462
+ const shadowedAxis = [];
1463
+ for (const slug of [...finalSlugs].sort()) {
1464
+ const axis = axisBySlug.get(slug);
1465
+ const existing = existingFiles.get(slug);
1466
+ const extForSlug = extOrder.map((id) => extCategory.get(id)).filter((c) => c.slug === slug);
1467
+ const existingIsExternal = !!existing && extForSlug.some((c) => c.id === existing.data.id);
1468
+ if (existingIsExternal) {
1469
+ if (axis) shadowedAxis.push(axis.id);
1470
+ continue;
1471
+ }
1472
+ if (axis) {
1473
+ outputs.set(`components/${slug}.json`, serialize(axis));
1474
+ continue;
1475
+ }
1476
+ outputs.set(`components/${slug}.json`, serialize(extForSlug[0]));
1477
+ }
1478
+ const writtenFiles = [];
1479
+ for (const [rel3, content] of outputs) {
1480
+ const file = path4.join(libraryDir, rel3);
1481
+ const before = await fs4.pathExists(file) ? await fs4.readFile(file, "utf-8") : void 0;
1482
+ if (before === content) continue;
1483
+ writtenFiles.push(rel3);
1484
+ if (!options.dryRun) await fs4.writeFile(file, content, "utf-8");
1485
+ }
1486
+ const removedFiles = [];
1487
+ for (const slug of existingFiles.keys()) {
1488
+ if (finalSlugs.has(slug)) continue;
1489
+ const rel3 = `components/${slug}.json`;
1490
+ removedFiles.push(rel3);
1491
+ if (!options.dryRun) await fs4.remove(path4.join(libraryDir, rel3));
1492
+ }
1493
+ return { added, changed, unchanged, removed, shadowedAxis, writtenFiles, removedFiles, stats };
1494
+ }
1495
+ function registerRefreshAxisCommand(libraryCmd2) {
1496
+ libraryCmd2.command("refresh-axis").description("AXIS \uD56D\uBAA9\uB9CC \uC800\uC7A5\uC18C \uC18C\uC2A4\uC5D0\uC11C \uB2E4\uC2DC \uB9CC\uB4E6 (\uC678\uBD80 \uC18C\uC2A4 \uD56D\uBAA9\uC740 \uADF8\uB300\uB85C, \uB124\uD2B8\uC6CC\uD06C \uC5C6\uC74C)").option("--root <dir>", "\uC800\uC7A5\uC18C \uB8E8\uD2B8", process.cwd()).option("-o, --output <dir>", "library \uB514\uB809\uD130\uB9AC (\uB8E8\uD2B8 \uAE30\uC900)", "apps/web/public/library").option("--updated-at <iso>", "\uBC14\uB010 \uD56D\uBAA9\uC5D0 \uAE30\uB85D\uD560 \uC2DC\uAC01 (\uAE30\uBCF8: \uC624\uB298 KST \uB0A0\uC9DC\uC758 00:00:00.000Z)").option("--dry-run", "\uD30C\uC77C\uC744 \uC4F0\uC9C0 \uC54A\uACE0 \uBC14\uB014 \uB0B4\uC6A9\uB9CC \uCD9C\uB825").action(async (opts) => {
1497
+ const rootDir = path4.resolve(opts.root);
1498
+ const result = await refreshAxisLibrary({
1499
+ rootDir,
1500
+ libraryDir: path4.resolve(rootDir, opts.output),
1501
+ updatedAt: opts.updatedAt || defaultUpdatedAt(),
1502
+ dryRun: opts.dryRun
1503
+ });
1504
+ const head = opts.dryRun ? "[dry-run] " : "";
1505
+ console.log(chalk2.blue(`
1506
+ ${head}AXIS library \uC7AC\uC0DD\uC131`));
1507
+ console.log(
1508
+ ` \uCD94\uAC00 ${result.added.length} \xB7 \uBCC0\uACBD ${result.changed.length} \xB7 \uC720\uC9C0 ${result.unchanged.length} \xB7 \uC0AD\uC81C ${result.removed.length}`
1509
+ );
1510
+ for (const id of result.added) console.log(chalk2.green(` + ${id}`));
1511
+ for (const id of result.changed) console.log(chalk2.yellow(` ~ ${id}`));
1512
+ for (const id of result.removed) console.log(chalk2.red(` - ${id}`));
1513
+ if (result.shadowedAxis.length > 0) {
1514
+ console.log(
1515
+ chalk2.yellow(` slug \uAC00 \uC678\uBD80 \uD56D\uBAA9 \uD30C\uC77C\uACFC \uACB9\uCCD0 \uD30C\uC77C\uC744 \uC4F0\uC9C0 \uC54A\uC74C(E4): ${result.shadowedAxis.join(", ")}`)
1516
+ );
1517
+ }
1518
+ console.log(` \uD30C\uC77C \uC4F0\uAE30 ${result.writtenFiles.length}\uAC1C \xB7 \uC0AD\uC81C ${result.removedFiles.length}\uAC1C`);
1519
+ console.log(` \uC804\uCCB4 ${result.stats.total}\uAC1C ${JSON.stringify(result.stats.bySource)}
1520
+ `);
1521
+ });
1522
+ }
1523
+
1524
+ // src/library/index.ts
1525
+ import fs5 from "fs-extra";
1526
+ import path5 from "path";
1527
+ import chalk3 from "chalk";
1285
1528
  import ora2 from "ora";
1286
1529
  var DEFAULT_CATEGORIES = [
1287
1530
  { id: "ui", name: "UI", description: "\uAE30\uBCF8 UI \uCEF4\uD3EC\uB10C\uD2B8", icon: "layers", order: 1 },
@@ -1311,11 +1554,11 @@ var LibraryCurator = class {
1311
1554
  async collectAll(sources, options) {
1312
1555
  const results = /* @__PURE__ */ new Map();
1313
1556
  const targetSources = sources || ["shadcn", "monet", "v0", "axis"];
1314
- console.log(chalk2.blue("\n\u{1F4E6} Library Curator - \uCEF4\uD3EC\uB10C\uD2B8 \uC218\uC9D1 \uC2DC\uC791\n"));
1557
+ console.log(chalk3.blue("\n\u{1F4E6} Library Curator - \uCEF4\uD3EC\uB10C\uD2B8 \uC218\uC9D1 \uC2DC\uC791\n"));
1315
1558
  for (const source of targetSources) {
1316
1559
  const collector = this.collectors.get(source);
1317
1560
  if (!collector) {
1318
- console.log(chalk2.yellow(`\u26A0\uFE0F ${source} collector not found, skipping`));
1561
+ console.log(chalk3.yellow(`\u26A0\uFE0F ${source} collector not found, skipping`));
1319
1562
  continue;
1320
1563
  }
1321
1564
  const spinner = ora2(`${source} \uC218\uC9D1 \uC911...`).start();
@@ -1326,7 +1569,7 @@ var LibraryCurator = class {
1326
1569
  results.set(source, result);
1327
1570
  if (result.success) {
1328
1571
  spinner.succeed(
1329
- `${source}: ${result.collected}\uAC1C \uC218\uC9D1 \uC644\uB8CC` + (result.failed > 0 ? chalk2.yellow(` (${result.failed}\uAC1C \uC2E4\uD328)`) : "")
1572
+ `${source}: ${result.collected}\uAC1C \uC218\uC9D1 \uC644\uB8CC` + (result.failed > 0 ? chalk3.yellow(` (${result.failed}\uAC1C \uC2E4\uD328)`) : "")
1330
1573
  );
1331
1574
  } else {
1332
1575
  spinner.fail(`${source}: \uC218\uC9D1 \uC2E4\uD328 - ${result.errors[0]?.error}`);
@@ -1386,15 +1629,15 @@ var LibraryCurator = class {
1386
1629
  * 인덱스 저장
1387
1630
  */
1388
1631
  async saveIndex(index) {
1389
- await fs4.ensureDir(this.dataDir);
1390
- const indexPath = path4.join(this.dataDir, "components.json");
1391
- await fs4.writeJSON(indexPath, index, { spaces: 2 });
1392
- const categoriesDir = path4.join(this.dataDir, "categories");
1393
- await fs4.ensureDir(categoriesDir);
1632
+ await fs5.ensureDir(this.dataDir);
1633
+ const indexPath = path5.join(this.dataDir, "components.json");
1634
+ await fs5.writeJSON(indexPath, index, { spaces: 2 });
1635
+ const categoriesDir = path5.join(this.dataDir, "categories");
1636
+ await fs5.ensureDir(categoriesDir);
1394
1637
  for (const category of DEFAULT_CATEGORIES) {
1395
1638
  const categoryComponents = index.components.filter((c) => c.category === category.id);
1396
- const categoryPath = path4.join(categoriesDir, `${category.id}.json`);
1397
- await fs4.writeJSON(
1639
+ const categoryPath = path5.join(categoriesDir, `${category.id}.json`);
1640
+ await fs5.writeJSON(
1398
1641
  categoryPath,
1399
1642
  {
1400
1643
  category: category.id,
@@ -1404,17 +1647,17 @@ var LibraryCurator = class {
1404
1647
  { spaces: 2 }
1405
1648
  );
1406
1649
  }
1407
- console.log(chalk2.green(`
1650
+ console.log(chalk3.green(`
1408
1651
  \u2713 \uC778\uB371\uC2A4 \uC800\uC7A5 \uC644\uB8CC: ${indexPath}`));
1409
- console.log(chalk2.gray(` - \uC804\uCCB4: ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8`));
1652
+ console.log(chalk3.gray(` - \uC804\uCCB4: ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8`));
1410
1653
  }
1411
1654
  /**
1412
1655
  * 인덱스 로드
1413
1656
  */
1414
1657
  async loadIndex() {
1415
- const indexPath = path4.join(this.dataDir, "components.json");
1416
- if (await fs4.pathExists(indexPath)) {
1417
- return await fs4.readJSON(indexPath);
1658
+ const indexPath = path5.join(this.dataDir, "components.json");
1659
+ if (await fs5.pathExists(indexPath)) {
1660
+ return await fs5.readJSON(indexPath);
1418
1661
  }
1419
1662
  return null;
1420
1663
  }
@@ -1469,26 +1712,26 @@ var LibraryCurator = class {
1469
1712
  async printStats() {
1470
1713
  const index = await this.loadIndex();
1471
1714
  if (!index) {
1472
- console.log(chalk2.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
1473
- 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"));
1715
+ console.log(chalk3.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
1716
+ console.log(chalk3.gray(" npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
1474
1717
  return;
1475
1718
  }
1476
- console.log(chalk2.blue("\n\u{1F4CA} Library Curator - \uD1B5\uACC4\n"));
1477
- console.log(chalk2.bold("\uC804\uCCB4 \uCEF4\uD3EC\uB10C\uD2B8: ") + chalk2.cyan(`${index.stats.total}\uAC1C`));
1478
- console.log(chalk2.gray(`\uB9C8\uC9C0\uB9C9 \uC5C5\uB370\uC774\uD2B8: ${index.updatedAt}
1719
+ console.log(chalk3.blue("\n\u{1F4CA} Library Curator - \uD1B5\uACC4\n"));
1720
+ console.log(chalk3.bold("\uC804\uCCB4 \uCEF4\uD3EC\uB10C\uD2B8: ") + chalk3.cyan(`${index.stats.total}\uAC1C`));
1721
+ console.log(chalk3.gray(`\uB9C8\uC9C0\uB9C9 \uC5C5\uB370\uC774\uD2B8: ${index.updatedAt}
1479
1722
  `));
1480
- console.log(chalk2.bold("\uC18C\uC2A4\uBCC4:"));
1723
+ console.log(chalk3.bold("\uC18C\uC2A4\uBCC4:"));
1481
1724
  for (const [source, count] of Object.entries(index.stats.bySource)) {
1482
- console.log(` ${chalk2.cyan(source.padEnd(10))} ${count}\uAC1C`);
1725
+ console.log(` ${chalk3.cyan(source.padEnd(10))} ${count}\uAC1C`);
1483
1726
  }
1484
- console.log(chalk2.bold("\n\uCE74\uD14C\uACE0\uB9AC\uBCC4:"));
1727
+ console.log(chalk3.bold("\n\uCE74\uD14C\uACE0\uB9AC\uBCC4:"));
1485
1728
  for (const [category, count] of Object.entries(index.stats.byCategory)) {
1486
- console.log(` ${chalk2.cyan(category.padEnd(15))} ${count}\uAC1C`);
1729
+ console.log(` ${chalk3.cyan(category.padEnd(15))} ${count}\uAC1C`);
1487
1730
  }
1488
- console.log(chalk2.bold("\n\uC778\uAE30 \uD0DC\uADF8:"));
1731
+ console.log(chalk3.bold("\n\uC778\uAE30 \uD0DC\uADF8:"));
1489
1732
  const topTags = index.tags.slice(0, 10);
1490
1733
  for (const tag of topTags) {
1491
- console.log(` ${chalk2.cyan(tag.name.padEnd(15))} ${tag.count}\uAC1C`);
1734
+ console.log(` ${chalk3.cyan(tag.name.padEnd(15))} ${tag.count}\uAC1C`);
1492
1735
  }
1493
1736
  console.log();
1494
1737
  }
@@ -1496,61 +1739,61 @@ var LibraryCurator = class {
1496
1739
  var libraryCurator = new LibraryCurator();
1497
1740
 
1498
1741
  // src/template/index.ts
1499
- import chalk7 from "chalk";
1742
+ import chalk8 from "chalk";
1500
1743
  import ora5 from "ora";
1501
1744
 
1502
1745
  // src/template/template-apply.ts
1503
- import fs7 from "fs-extra";
1504
- import path7 from "path";
1505
- import chalk4 from "chalk";
1746
+ import fs8 from "fs-extra";
1747
+ import path8 from "path";
1748
+ import chalk5 from "chalk";
1506
1749
  import ora3 from "ora";
1507
1750
  import prompts from "prompts";
1508
1751
 
1509
1752
  // src/template/post-install.ts
1510
- import fs5 from "fs-extra";
1511
- import path5 from "path";
1512
- import chalk3 from "chalk";
1753
+ import fs6 from "fs-extra";
1754
+ import path6 from "path";
1755
+ import chalk4 from "chalk";
1513
1756
  async function runPostInstall(patches, baseDir, dryRun = false) {
1514
1757
  for (const patch of patches) {
1515
- const filePath = path5.resolve(baseDir, patch.file);
1758
+ const filePath = path6.resolve(baseDir, patch.file);
1516
1759
  if (dryRun) {
1517
- console.log(chalk3.gray(` [dry-run] patch ${patch.type}: ${patch.file}`));
1760
+ console.log(chalk4.gray(` [dry-run] patch ${patch.type}: ${patch.file}`));
1518
1761
  continue;
1519
1762
  }
1520
- if (!await fs5.pathExists(filePath)) {
1521
- console.log(chalk3.yellow(` \uACBD\uACE0: \uD328\uCE58 \uB300\uC0C1 \uD30C\uC77C \uC5C6\uC74C - ${patch.file}`));
1763
+ if (!await fs6.pathExists(filePath)) {
1764
+ console.log(chalk4.yellow(` \uACBD\uACE0: \uD328\uCE58 \uB300\uC0C1 \uD30C\uC77C \uC5C6\uC74C - ${patch.file}`));
1522
1765
  continue;
1523
1766
  }
1524
1767
  switch (patch.type) {
1525
1768
  case "replace": {
1526
1769
  if (!patch.search || patch.value === void 0) break;
1527
- let content = await fs5.readFile(filePath, "utf-8");
1770
+ let content = await fs6.readFile(filePath, "utf-8");
1528
1771
  content = content.replace(patch.search, patch.value);
1529
- await fs5.writeFile(filePath, content);
1530
- console.log(chalk3.gray(` patch replace: ${patch.file}`));
1772
+ await fs6.writeFile(filePath, content);
1773
+ console.log(chalk4.gray(` patch replace: ${patch.file}`));
1531
1774
  break;
1532
1775
  }
1533
1776
  case "append": {
1534
1777
  if (patch.value === void 0) break;
1535
- const content = await fs5.readFile(filePath, "utf-8");
1536
- await fs5.writeFile(filePath, content + patch.value);
1537
- console.log(chalk3.gray(` patch append: ${patch.file}`));
1778
+ const content = await fs6.readFile(filePath, "utf-8");
1779
+ await fs6.writeFile(filePath, content + patch.value);
1780
+ console.log(chalk4.gray(` patch append: ${patch.file}`));
1538
1781
  break;
1539
1782
  }
1540
1783
  case "prepend": {
1541
1784
  if (patch.value === void 0) break;
1542
- const content = await fs5.readFile(filePath, "utf-8");
1543
- await fs5.writeFile(filePath, patch.value + content);
1544
- console.log(chalk3.gray(` patch prepend: ${patch.file}`));
1785
+ const content = await fs6.readFile(filePath, "utf-8");
1786
+ await fs6.writeFile(filePath, patch.value + content);
1787
+ console.log(chalk4.gray(` patch prepend: ${patch.file}`));
1545
1788
  break;
1546
1789
  }
1547
1790
  case "json-merge": {
1548
1791
  if (!patch.merge) break;
1549
- const raw = await fs5.readFile(filePath, "utf-8");
1792
+ const raw = await fs6.readFile(filePath, "utf-8");
1550
1793
  const json = JSON.parse(raw);
1551
1794
  deepMerge(json, patch.merge);
1552
- await fs5.writeJSON(filePath, json, { spaces: 2 });
1553
- console.log(chalk3.gray(` patch json-merge: ${patch.file}`));
1795
+ await fs6.writeJSON(filePath, json, { spaces: 2 });
1796
+ console.log(chalk4.gray(` patch json-merge: ${patch.file}`));
1554
1797
  break;
1555
1798
  }
1556
1799
  }
@@ -1568,10 +1811,10 @@ function deepMerge(target, source) {
1568
1811
  }
1569
1812
  }
1570
1813
 
1571
- // src/config/axis-config.ts
1572
- import fs6 from "fs-extra";
1573
- import path6 from "path";
1574
- var AXIS_CONFIG_SCHEMA_URL = "https://axis.minu.best/schema.json";
1814
+ // ../axis-registry-core/src/config/axis-config.ts
1815
+ import fs7 from "fs-extra";
1816
+ import path7 from "path";
1817
+ var AXIS_CONFIG_SCHEMA_URL = `${AXIS_SITE_URL}/schema.json`;
1575
1818
  var AXIS_CONFIG_FILE = "axis.config.json";
1576
1819
  function createInitConfig(answers, registry) {
1577
1820
  return {
@@ -1593,9 +1836,9 @@ function createTemplateConfig(template) {
1593
1836
  };
1594
1837
  }
1595
1838
  async function readAxisConfig(baseDir) {
1596
- const configPath = path6.join(baseDir, AXIS_CONFIG_FILE);
1597
- if (!await fs6.pathExists(configPath)) return null;
1598
- return await fs6.readJSON(configPath);
1839
+ const configPath = path7.join(baseDir, AXIS_CONFIG_FILE);
1840
+ if (!await fs7.pathExists(configPath)) return null;
1841
+ return await fs7.readJSON(configPath);
1599
1842
  }
1600
1843
 
1601
1844
  // src/template/template-apply.ts
@@ -1609,19 +1852,19 @@ async function applyTemplate(slug, options) {
1609
1852
  spinner.fail(err.message);
1610
1853
  process.exit(1);
1611
1854
  }
1612
- const baseDir = path7.resolve(options.dir || ".");
1855
+ const baseDir = path8.resolve(options.dir || ".");
1613
1856
  const conflicts = [];
1614
1857
  for (const file of detail.files) {
1615
- const dest = path7.join(baseDir, file.path);
1616
- if (await fs7.pathExists(dest)) {
1858
+ const dest = path8.join(baseDir, file.path);
1859
+ if (await fs8.pathExists(dest)) {
1617
1860
  conflicts.push(file.path);
1618
1861
  }
1619
1862
  }
1620
1863
  if (conflicts.length > 0 && !options.yes && !options.dryRun) {
1621
- console.log(chalk4.yellow(`
1864
+ console.log(chalk5.yellow(`
1622
1865
  \uAE30\uC874 \uD30C\uC77C\uACFC \uCDA9\uB3CC\uD558\uB294 ${conflicts.length}\uAC1C \uD30C\uC77C:`));
1623
1866
  for (const c of conflicts) {
1624
- console.log(chalk4.gray(` - ${c}`));
1867
+ console.log(chalk5.gray(` - ${c}`));
1625
1868
  }
1626
1869
  const { proceed } = await prompts({
1627
1870
  type: "confirm",
@@ -1630,59 +1873,59 @@ async function applyTemplate(slug, options) {
1630
1873
  initial: false
1631
1874
  });
1632
1875
  if (!proceed) {
1633
- console.log(chalk4.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1876
+ console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1634
1877
  return;
1635
1878
  }
1636
1879
  }
1637
1880
  if (options.dryRun) {
1638
- console.log(chalk4.blue("\n[\uBBF8\uB9AC\uBCF4\uAE30] \uC0DD\uC131\uB420 \uD30C\uC77C:"));
1881
+ console.log(chalk5.blue("\n[\uBBF8\uB9AC\uBCF4\uAE30] \uC0DD\uC131\uB420 \uD30C\uC77C:"));
1639
1882
  for (const file of detail.files) {
1640
- const dest = path7.join(baseDir, file.path);
1883
+ const dest = path8.join(baseDir, file.path);
1641
1884
  const exists = conflicts.includes(file.path);
1642
- const label = exists ? chalk4.yellow("\uB36E\uC5B4\uC4F0\uAE30") : chalk4.green("\uC0DD\uC131");
1885
+ const label = exists ? chalk5.yellow("\uB36E\uC5B4\uC4F0\uAE30") : chalk5.green("\uC0DD\uC131");
1643
1886
  console.log(` ${label} ${dest}`);
1644
1887
  }
1645
1888
  if (detail.postInstall?.length) {
1646
- console.log(chalk4.blue("\n[\uBBF8\uB9AC\uBCF4\uAE30] postInstall \uD328\uCE58:"));
1889
+ console.log(chalk5.blue("\n[\uBBF8\uB9AC\uBCF4\uAE30] postInstall \uD328\uCE58:"));
1647
1890
  for (const p of detail.postInstall) {
1648
- console.log(chalk4.gray(` ${p.type}: ${p.file}`));
1891
+ console.log(chalk5.gray(` ${p.type}: ${p.file}`));
1649
1892
  }
1650
1893
  }
1651
1894
  return;
1652
1895
  }
1653
1896
  const writeSpinner = ora3("\uD30C\uC77C \uC0DD\uC131 \uC911...").start();
1654
1897
  for (const file of detail.files) {
1655
- const dest = path7.join(baseDir, file.path);
1656
- await fs7.ensureDir(path7.dirname(dest));
1657
- await fs7.writeFile(dest, file.content);
1898
+ const dest = path8.join(baseDir, file.path);
1899
+ await fs8.ensureDir(path8.dirname(dest));
1900
+ await fs8.writeFile(dest, file.content);
1658
1901
  }
1659
1902
  writeSpinner.succeed(`${detail.files.length}\uAC1C \uD30C\uC77C \uC0DD\uC131 \uC644\uB8CC`);
1660
1903
  if (detail.postInstall?.length) {
1661
- console.log(chalk4.blue("\npostInstall \uD328\uCE58 \uC2E4\uD589 \uC911..."));
1904
+ console.log(chalk5.blue("\npostInstall \uD328\uCE58 \uC2E4\uD589 \uC911..."));
1662
1905
  await runPostInstall(detail.postInstall, baseDir);
1663
1906
  }
1664
1907
  if (!options.skipDeps) {
1665
1908
  const allDeps = { ...detail.dependencies, ...detail.devDependencies };
1666
1909
  const depList = Object.entries(allDeps);
1667
1910
  if (depList.length > 0) {
1668
- console.log(chalk4.yellow("\n\uD544\uC694\uD55C \uC758\uC874\uC131:"));
1911
+ console.log(chalk5.yellow("\n\uD544\uC694\uD55C \uC758\uC874\uC131:"));
1669
1912
  const deps = Object.entries(detail.dependencies || {}).map(([k, v]) => `${k}@${v}`).join(" ");
1670
1913
  const devDeps = Object.entries(detail.devDependencies || {}).map(([k, v]) => `${k}@${v}`).join(" ");
1671
1914
  if (deps) {
1672
- console.log(chalk4.cyan(` pnpm add ${deps}`));
1915
+ console.log(chalk5.cyan(` pnpm add ${deps}`));
1673
1916
  }
1674
1917
  if (devDeps) {
1675
- console.log(chalk4.cyan(` pnpm add -D ${devDeps}`));
1918
+ console.log(chalk5.cyan(` pnpm add -D ${devDeps}`));
1676
1919
  }
1677
1920
  }
1678
1921
  }
1679
- console.log(chalk4.green(`
1922
+ console.log(chalk5.green(`
1680
1923
  '${detail.name}' \uD15C\uD50C\uB9BF \uC801\uC6A9 \uC644\uB8CC!`));
1681
1924
  }
1682
1925
  async function initTemplate(slug, options) {
1683
1926
  let selectedSlug = slug;
1684
1927
  if (!selectedSlug) {
1685
- const { fetchTemplateIndex: fetchTemplateIndex2 } = await import("./registry-client-RMES4CL5.js");
1928
+ const { fetchTemplateIndex: fetchTemplateIndex2 } = await import("./registry-client-6WSGKPF2.js");
1686
1929
  const index = await fetchTemplateIndex2();
1687
1930
  const { choice } = await prompts({
1688
1931
  type: "select",
@@ -1695,7 +1938,7 @@ async function initTemplate(slug, options) {
1695
1938
  }))
1696
1939
  });
1697
1940
  if (!choice) {
1698
- console.log(chalk4.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1941
+ console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1699
1942
  return;
1700
1943
  }
1701
1944
  selectedSlug = choice;
@@ -1709,14 +1952,14 @@ async function initTemplate(slug, options) {
1709
1952
  initial: selectedSlug
1710
1953
  });
1711
1954
  if (!dir) {
1712
- console.log(chalk4.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1955
+ console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1713
1956
  return;
1714
1957
  }
1715
1958
  targetDir = dir;
1716
1959
  }
1717
- const resolved = path7.resolve(targetDir);
1718
- if (await fs7.pathExists(resolved)) {
1719
- const entries = await fs7.readdir(resolved);
1960
+ const resolved = path8.resolve(targetDir);
1961
+ if (await fs8.pathExists(resolved)) {
1962
+ const entries = await fs8.readdir(resolved);
1720
1963
  if (entries.length > 0) {
1721
1964
  const { proceed } = await prompts({
1722
1965
  type: "confirm",
@@ -1727,26 +1970,26 @@ async function initTemplate(slug, options) {
1727
1970
  if (!proceed) return;
1728
1971
  }
1729
1972
  } else {
1730
- await fs7.ensureDir(resolved);
1973
+ await fs8.ensureDir(resolved);
1731
1974
  }
1732
1975
  await applyTemplate(selectedSlug, { dir: targetDir, yes: true });
1733
- const configPath = path7.join(resolved, "axis.config.json");
1734
- if (!await fs7.pathExists(configPath)) {
1976
+ const configPath = path8.join(resolved, "axis.config.json");
1977
+ if (!await fs8.pathExists(configPath)) {
1735
1978
  const axisConfig = createTemplateConfig(selectedSlug);
1736
- await fs7.writeJSON(configPath, axisConfig, { spaces: 2 });
1737
- console.log(chalk4.green("axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
1979
+ await fs8.writeJSON(configPath, axisConfig, { spaces: 2 });
1980
+ console.log(chalk5.green("axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
1738
1981
  }
1739
- console.log(chalk4.blue(`
1982
+ console.log(chalk5.blue(`
1740
1983
  \uB2E4\uC74C \uB2E8\uACC4:`));
1741
- console.log(chalk4.cyan(` cd ${targetDir}`));
1742
- console.log(chalk4.cyan(` pnpm install`));
1743
- console.log(chalk4.cyan(` pnpm dev`));
1984
+ console.log(chalk5.cyan(` cd ${targetDir}`));
1985
+ console.log(chalk5.cyan(` pnpm install`));
1986
+ console.log(chalk5.cyan(` pnpm dev`));
1744
1987
  }
1745
1988
 
1746
1989
  // src/template/template-diff.ts
1747
- import fs8 from "fs-extra";
1748
- import path8 from "path";
1749
- import chalk5 from "chalk";
1990
+ import fs9 from "fs-extra";
1991
+ import path9 from "path";
1992
+ import chalk6 from "chalk";
1750
1993
  import ora4 from "ora";
1751
1994
  async function diffTemplate(slug, options) {
1752
1995
  const spinner = ora4(`'${slug}' \uD15C\uD50C\uB9BF \uAC00\uC838\uC624\uB294 \uC911...`).start();
@@ -1758,15 +2001,15 @@ async function diffTemplate(slug, options) {
1758
2001
  spinner.fail(err.message);
1759
2002
  process.exit(1);
1760
2003
  }
1761
- const baseDir = path8.resolve(options.dir || ".");
2004
+ const baseDir = path9.resolve(options.dir || ".");
1762
2005
  const entries = [];
1763
2006
  for (const file of detail.files) {
1764
- const localPath = path8.join(baseDir, file.path);
1765
- if (!await fs8.pathExists(localPath)) {
2007
+ const localPath = path9.join(baseDir, file.path);
2008
+ if (!await fs9.pathExists(localPath)) {
1766
2009
  entries.push({ path: file.path, status: "added" });
1767
2010
  continue;
1768
2011
  }
1769
- const localContent = await fs8.readFile(localPath, "utf-8");
2012
+ const localContent = await fs9.readFile(localPath, "utf-8");
1770
2013
  if (localContent === file.content) {
1771
2014
  entries.push({ path: file.path, status: "unchanged" });
1772
2015
  } else {
@@ -1787,14 +2030,14 @@ async function diffTemplate(slug, options) {
1787
2030
  }
1788
2031
  }
1789
2032
  }
1790
- console.log(chalk5.blue(`
2033
+ console.log(chalk6.blue(`
1791
2034
  '${detail.name}' \uD15C\uD50C\uB9BF diff \uACB0\uACFC:
1792
2035
  `));
1793
2036
  const statusIcon = {
1794
- added: chalk5.green("+ \uCD94\uAC00 \uD544\uC694"),
1795
- modified: chalk5.yellow("~ \uBCC0\uACBD\uB428"),
1796
- unchanged: chalk5.gray("= \uB3D9\uC77C"),
1797
- extra: chalk5.cyan("? \uB85C\uCEEC \uC804\uC6A9")
2037
+ added: chalk6.green("+ \uCD94\uAC00 \uD544\uC694"),
2038
+ modified: chalk6.yellow("~ \uBCC0\uACBD\uB428"),
2039
+ unchanged: chalk6.gray("= \uB3D9\uC77C"),
2040
+ extra: chalk6.cyan("? \uB85C\uCEEC \uC804\uC6A9")
1798
2041
  };
1799
2042
  let added = 0;
1800
2043
  let modified = 0;
@@ -1805,7 +2048,7 @@ async function diffTemplate(slug, options) {
1805
2048
  console.log(` ${icon.padEnd(28)} ${entry.path}`);
1806
2049
  if (entry.status === "modified" && options.verbose) {
1807
2050
  console.log(
1808
- chalk5.gray(
2051
+ chalk6.gray(
1809
2052
  ` \uB85C\uCEEC ${entry.localLines}\uC904 / \uC6D0\uBCF8 ${entry.remoteLines}\uC904`
1810
2053
  )
1811
2054
  );
@@ -1825,9 +2068,9 @@ async function diffTemplate(slug, options) {
1825
2068
  break;
1826
2069
  }
1827
2070
  }
1828
- console.log(chalk5.blue("\n\uC694\uC57D:"));
2071
+ console.log(chalk6.blue("\n\uC694\uC57D:"));
1829
2072
  console.log(
1830
- ` \uCD94\uAC00 \uD544\uC694: ${chalk5.green(String(added))} | \uBCC0\uACBD\uB428: ${chalk5.yellow(String(modified))} | \uB3D9\uC77C: ${chalk5.gray(String(unchanged))}${extra > 0 ? ` | \uB85C\uCEEC \uC804\uC6A9: ${chalk5.cyan(String(extra))}` : ""}`
2073
+ ` \uCD94\uAC00 \uD544\uC694: ${chalk6.green(String(added))} | \uBCC0\uACBD\uB428: ${chalk6.yellow(String(modified))} | \uB3D9\uC77C: ${chalk6.gray(String(unchanged))}${extra > 0 ? ` | \uB85C\uCEEC \uC804\uC6A9: ${chalk6.cyan(String(extra))}` : ""}`
1831
2074
  );
1832
2075
  }
1833
2076
  async function collectLocalFiles(dir, base) {
@@ -1836,27 +2079,27 @@ async function collectLocalFiles(dir, base) {
1836
2079
  const results = [];
1837
2080
  let entries;
1838
2081
  try {
1839
- entries = await fs8.readdir(dir, { withFileTypes: true });
2082
+ entries = await fs9.readdir(dir, { withFileTypes: true });
1840
2083
  } catch {
1841
2084
  return results;
1842
2085
  }
1843
2086
  for (const entry of entries) {
1844
2087
  if (ignore.has(entry.name)) continue;
1845
- const fullPath = path8.join(dir, entry.name);
2088
+ const fullPath = path9.join(dir, entry.name);
1846
2089
  if (entry.isDirectory()) {
1847
2090
  const nested = await collectLocalFiles(fullPath, root);
1848
2091
  results.push(...nested);
1849
2092
  } else {
1850
- results.push(path8.relative(root, fullPath).replace(/\\/g, "/"));
2093
+ results.push(path9.relative(root, fullPath).replace(/\\/g, "/"));
1851
2094
  }
1852
2095
  }
1853
2096
  return results;
1854
2097
  }
1855
2098
 
1856
2099
  // src/template/template-check.ts
1857
- import fs9 from "fs-extra";
1858
- import path9 from "path";
1859
- import chalk6 from "chalk";
2100
+ import fs10 from "fs-extra";
2101
+ import path10 from "path";
2102
+ import chalk7 from "chalk";
1860
2103
 
1861
2104
  // src/theme/brand-core.ts
1862
2105
  import { existsSync, readFileSync, statSync } from "fs";
@@ -2102,7 +2345,7 @@ function getBrand(baseDir, name) {
2102
2345
  };
2103
2346
  }
2104
2347
 
2105
- // src/template/tailwind-core.ts
2348
+ // ../axis-registry-core/src/template/tailwind-core.ts
2106
2349
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
2107
2350
  import { join as join2, resolve as resolve2 } from "path";
2108
2351
  function hasDependency(pkg, name) {
@@ -2523,9 +2766,9 @@ function checkTailwindSetup(baseDirInput) {
2523
2766
  return { name: "tailwind.config", severity: "warn", message: "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070 \uC124\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4" };
2524
2767
  }
2525
2768
  for (const file of otherFiles) {
2526
- const path16 = join2(baseDir, file);
2527
- if (existsSync2(path16)) {
2528
- if (hasTokensPresetReference(readFileSync2(path16, "utf8"))) {
2769
+ const path18 = join2(baseDir, file);
2770
+ if (existsSync2(path18)) {
2771
+ if (hasTokensPresetReference(readFileSync2(path18, "utf8"))) {
2529
2772
  return { name: "tailwind.config", severity: "pass", message: `${file}${PRESET_PASS_SUFFIX}` };
2530
2773
  }
2531
2774
  return { name: "tailwind.config", severity: "warn", message: `${file} \uC874\uC7AC (TypeScript \uAD8C\uC7A5)` };
@@ -2536,12 +2779,12 @@ function checkTailwindSetup(baseDirInput) {
2536
2779
 
2537
2780
  // src/template/template-check.ts
2538
2781
  var SEVERITY_ICON = {
2539
- pass: chalk6.green("PASS"),
2540
- warn: chalk6.yellow("WARN"),
2541
- fail: chalk6.red("FAIL")
2782
+ pass: chalk7.green("PASS"),
2783
+ warn: chalk7.yellow("WARN"),
2784
+ fail: chalk7.red("FAIL")
2542
2785
  };
2543
2786
  async function collectCheckResults(dir) {
2544
- const baseDir = path9.resolve(dir || ".");
2787
+ const baseDir = path10.resolve(dir || ".");
2545
2788
  const results = [];
2546
2789
  results.push(await checkFileExists(baseDir, "axis.config.json", "axis.config.json"));
2547
2790
  results.push(checkTailwindSetup(baseDir));
@@ -2554,7 +2797,7 @@ async function collectCheckResults(dir) {
2554
2797
  }
2555
2798
  async function runCheck(dir) {
2556
2799
  const results = await collectCheckResults(dir);
2557
- console.log(chalk6.blue("\nAXIS \uD504\uB85C\uC81D\uD2B8 \uAC80\uC99D \uACB0\uACFC:\n"));
2800
+ console.log(chalk7.blue("\nAXIS \uD504\uB85C\uC81D\uD2B8 \uAC80\uC99D \uACB0\uACFC:\n"));
2558
2801
  let passCount = 0;
2559
2802
  let warnCount = 0;
2560
2803
  let failCount = 0;
@@ -2574,19 +2817,19 @@ async function runCheck(dir) {
2574
2817
  }
2575
2818
  console.log();
2576
2819
  console.log(
2577
- ` \uACB0\uACFC: ${chalk6.green(`${passCount} pass`)} / ${chalk6.yellow(`${warnCount} warn`)} / ${chalk6.red(`${failCount} fail`)}`
2820
+ ` \uACB0\uACFC: ${chalk7.green(`${passCount} pass`)} / ${chalk7.yellow(`${warnCount} warn`)} / ${chalk7.red(`${failCount} fail`)}`
2578
2821
  );
2579
2822
  if (failCount > 0) {
2580
- console.log(chalk6.red("\n\uC77C\uBD80 \uD544\uC218 \uD56D\uBAA9\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC704 \uC548\uB0B4\uB97C \uD655\uC778\uD558\uC138\uC694."));
2823
+ console.log(chalk7.red("\n\uC77C\uBD80 \uD544\uC218 \uD56D\uBAA9\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC704 \uC548\uB0B4\uB97C \uD655\uC778\uD558\uC138\uC694."));
2581
2824
  } else if (warnCount > 0) {
2582
- console.log(chalk6.yellow("\n\uAD8C\uC7A5 \uD56D\uBAA9\uC744 \uD655\uC778\uD558\uC138\uC694."));
2825
+ console.log(chalk7.yellow("\n\uAD8C\uC7A5 \uD56D\uBAA9\uC744 \uD655\uC778\uD558\uC138\uC694."));
2583
2826
  } else {
2584
- console.log(chalk6.green("\n\uBAA8\uB4E0 \uAC80\uC99D\uC744 \uD1B5\uACFC\uD588\uC2B5\uB2C8\uB2E4!"));
2827
+ console.log(chalk7.green("\n\uBAA8\uB4E0 \uAC80\uC99D\uC744 \uD1B5\uACFC\uD588\uC2B5\uB2C8\uB2E4!"));
2585
2828
  }
2586
2829
  return { pass: passCount, warn: warnCount, fail: failCount };
2587
2830
  }
2588
2831
  async function checkFileExists(baseDir, fileName, label) {
2589
- const exists = await fs9.pathExists(path9.join(baseDir, fileName));
2832
+ const exists = await fs10.pathExists(path10.join(baseDir, fileName));
2590
2833
  return {
2591
2834
  name: label,
2592
2835
  severity: exists ? "pass" : "fail",
@@ -2602,9 +2845,9 @@ async function checkUtils(baseDir) {
2602
2845
  "utils.ts"
2603
2846
  ];
2604
2847
  for (const candidate of candidates) {
2605
- const fullPath = path9.join(baseDir, candidate);
2606
- if (await fs9.pathExists(fullPath)) {
2607
- const content = await fs9.readFile(fullPath, "utf-8");
2848
+ const fullPath = path10.join(baseDir, candidate);
2849
+ if (await fs10.pathExists(fullPath)) {
2850
+ const content = await fs10.readFile(fullPath, "utf-8");
2608
2851
  const hasCn = content.includes("function cn");
2609
2852
  return {
2610
2853
  name: "utils.ts",
@@ -2620,15 +2863,15 @@ async function checkUtils(baseDir) {
2620
2863
  };
2621
2864
  }
2622
2865
  async function checkDependencies(baseDir) {
2623
- const pkgPath = path9.join(baseDir, "package.json");
2624
- if (!await fs9.pathExists(pkgPath)) {
2866
+ const pkgPath = path10.join(baseDir, "package.json");
2867
+ if (!await fs10.pathExists(pkgPath)) {
2625
2868
  return {
2626
2869
  name: "package.json",
2627
2870
  severity: "fail",
2628
2871
  message: "package.json \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
2629
2872
  };
2630
2873
  }
2631
- const pkg = await fs9.readJSON(pkgPath);
2874
+ const pkg = await fs10.readJSON(pkgPath);
2632
2875
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
2633
2876
  const required = ["tailwindcss"];
2634
2877
  const recommended = ["clsx", "tailwind-merge"];
@@ -2702,10 +2945,10 @@ function registerTemplateCommand(program2) {
2702
2945
  templates = templates.filter((t) => t.category === options.category);
2703
2946
  }
2704
2947
  if (templates.length === 0) {
2705
- console.log(chalk7.yellow("\n\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uD15C\uD50C\uB9BF\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
2948
+ console.log(chalk8.yellow("\n\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uD15C\uD50C\uB9BF\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
2706
2949
  return;
2707
2950
  }
2708
- console.log(chalk7.blue(`
2951
+ console.log(chalk8.blue(`
2709
2952
  \u{1F4E6} AXIS \uD15C\uD50C\uB9BF (${templates.length}\uAC1C)
2710
2953
  `));
2711
2954
  const byCategory = /* @__PURE__ */ new Map();
@@ -2716,16 +2959,16 @@ function registerTemplateCommand(program2) {
2716
2959
  byCategory.get(t.category).push(t);
2717
2960
  }
2718
2961
  for (const [category, items] of byCategory) {
2719
- console.log(chalk7.bold(` ${category}`));
2962
+ console.log(chalk8.bold(` ${category}`));
2720
2963
  for (const t of items) {
2721
2964
  console.log(
2722
- ` ${chalk7.cyan(t.slug.padEnd(20))} ${chalk7.gray(t.description.slice(0, 50))}`
2965
+ ` ${chalk8.cyan(t.slug.padEnd(20))} ${chalk8.gray(t.description.slice(0, 50))}`
2723
2966
  );
2724
2967
  }
2725
2968
  console.log();
2726
2969
  }
2727
- console.log(chalk7.gray("\uC0AC\uC6A9\uBC95: axis template info <name>"));
2728
- console.log(chalk7.gray(" axis template apply <name>\n"));
2970
+ console.log(chalk8.gray("\uC0AC\uC6A9\uBC95: axis template info <name>"));
2971
+ console.log(chalk8.gray(" axis template apply <name>\n"));
2729
2972
  } catch (err) {
2730
2973
  spinner.fail(err.message);
2731
2974
  process.exit(1);
@@ -2736,30 +2979,30 @@ function registerTemplateCommand(program2) {
2736
2979
  try {
2737
2980
  const detail = await fetchTemplateDetail(name);
2738
2981
  spinner.stop();
2739
- console.log(chalk7.blue(`
2982
+ console.log(chalk8.blue(`
2740
2983
  \u{1F4CB} ${detail.name}
2741
2984
  `));
2742
- console.log(` ${chalk7.bold("\uC124\uBA85")}: ${detail.description}`);
2743
- console.log(` ${chalk7.bold("\uCE74\uD14C\uACE0\uB9AC")}: ${detail.category}`);
2744
- console.log(` ${chalk7.bold("\uBC84\uC804")}: ${detail.version}`);
2985
+ console.log(` ${chalk8.bold("\uC124\uBA85")}: ${detail.description}`);
2986
+ console.log(` ${chalk8.bold("\uCE74\uD14C\uACE0\uB9AC")}: ${detail.category}`);
2987
+ console.log(` ${chalk8.bold("\uBC84\uC804")}: ${detail.version}`);
2745
2988
  if (detail.tags.length > 0) {
2746
- console.log(` ${chalk7.bold("\uD0DC\uADF8")}: ${detail.tags.join(", ")}`);
2989
+ console.log(` ${chalk8.bold("\uD0DC\uADF8")}: ${detail.tags.join(", ")}`);
2747
2990
  }
2748
2991
  if (detail.features.length > 0) {
2749
- console.log(chalk7.bold("\n \uAE30\uB2A5:"));
2992
+ console.log(chalk8.bold("\n \uAE30\uB2A5:"));
2750
2993
  for (const f of detail.features) {
2751
2994
  console.log(` - ${f}`);
2752
2995
  }
2753
2996
  }
2754
- console.log(chalk7.bold(`
2997
+ console.log(chalk8.bold(`
2755
2998
  \uD30C\uC77C (${detail.files.length}\uAC1C):`));
2756
2999
  for (const f of detail.files) {
2757
- console.log(` ${chalk7.cyan(f.path)} ${chalk7.gray(`(${f.type})`)}`);
3000
+ console.log(` ${chalk8.cyan(f.path)} ${chalk8.gray(`(${f.type})`)}`);
2758
3001
  }
2759
3002
  const deps = Object.keys(detail.dependencies || {});
2760
3003
  const devDeps = Object.keys(detail.devDependencies || {});
2761
3004
  if (deps.length > 0 || devDeps.length > 0) {
2762
- console.log(chalk7.bold("\n \uC758\uC874\uC131:"));
3005
+ console.log(chalk8.bold("\n \uC758\uC874\uC131:"));
2763
3006
  if (deps.length > 0) {
2764
3007
  console.log(` dependencies: ${deps.join(", ")}`);
2765
3008
  }
@@ -2767,7 +3010,7 @@ function registerTemplateCommand(program2) {
2767
3010
  console.log(` devDependencies: ${devDeps.join(", ")}`);
2768
3011
  }
2769
3012
  }
2770
- console.log(chalk7.gray(`
3013
+ console.log(chalk8.gray(`
2771
3014
  \uC0AC\uC6A9\uBC95: axis template apply ${name}
2772
3015
  `));
2773
3016
  } catch (err) {
@@ -2793,16 +3036,40 @@ function registerCheckCommand(program2) {
2793
3036
  }
2794
3037
 
2795
3038
  // src/theme/index.ts
2796
- import chalk8 from "chalk";
3039
+ import chalk9 from "chalk";
3040
+ import path13 from "path";
3041
+
3042
+ // src/theme/theme-add.ts
3043
+ import { accessSync, constants, existsSync as existsSync4, readFileSync as readFileSync3, realpathSync, unlinkSync, writeFileSync } from "fs";
3044
+ import path12 from "path";
3045
+
3046
+ // ../axis-registry-core/src/project.ts
3047
+ import { existsSync as existsSync3 } from "fs";
2797
3048
  import path11 from "path";
3049
+ function detectInstallCommand(baseDir) {
3050
+ if (existsSync3(path11.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
3051
+ if (existsSync3(path11.join(baseDir, "yarn.lock"))) return "yarn install";
3052
+ if (existsSync3(path11.join(baseDir, "package-lock.json"))) return "npm install";
3053
+ return "pnpm install";
3054
+ }
3055
+ function hasDependency2(pkg, name) {
3056
+ for (const field of ["dependencies", "devDependencies"]) {
3057
+ const deps = pkg[field];
3058
+ if (typeof deps === "object" && deps !== null && name in deps) {
3059
+ return String(deps[name]);
3060
+ }
3061
+ }
3062
+ return void 0;
3063
+ }
3064
+ function isPlainObject2(value) {
3065
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3066
+ }
2798
3067
 
2799
3068
  // src/theme/theme-add.ts
2800
- import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync3, realpathSync, unlinkSync, writeFileSync } from "fs";
2801
- import path10 from "path";
2802
3069
  var TOKENS_DEPENDENCY_RANGE = `^${MIN_BRAND_TOKENS_VERSION}`;
2803
3070
  var THEME_PACKAGE = "@axis-ds/theme";
2804
3071
  function readText(file) {
2805
- return existsSync3(file) ? readFileSync3(file, "utf8") : null;
3072
+ return existsSync4(file) ? readFileSync3(file, "utf8") : null;
2806
3073
  }
2807
3074
  function eolOf(text) {
2808
3075
  return text.includes("\r\n") ? "\r\n" : "\n";
@@ -2870,33 +3137,15 @@ function compareVersions(a, b) {
2870
3137
  function realPathInside(baseDir, file) {
2871
3138
  const realBase = realpathSync(baseDir);
2872
3139
  const realPath = realpathSync(file);
2873
- const relPath = path10.relative(realBase, realPath);
2874
- const inside = relPath !== "" && !relPath.startsWith("..") && !path10.isAbsolute(relPath);
3140
+ const relPath = path12.relative(realBase, realPath);
3141
+ const inside = relPath !== "" && !relPath.startsWith("..") && !path12.isAbsolute(relPath);
2875
3142
  return { inside, realPath };
2876
3143
  }
2877
3144
  function isStylesheet(realPath) {
2878
- return path10.extname(realPath).toLowerCase() === ".css";
2879
- }
2880
- function detectInstallCommand(baseDir) {
2881
- if (existsSync3(path10.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
2882
- if (existsSync3(path10.join(baseDir, "yarn.lock"))) return "yarn install";
2883
- if (existsSync3(path10.join(baseDir, "package-lock.json"))) return "npm install";
2884
- return "pnpm install";
2885
- }
2886
- function hasDependency2(pkg, name) {
2887
- for (const field of ["dependencies", "devDependencies"]) {
2888
- const deps = pkg[field];
2889
- if (typeof deps === "object" && deps !== null && name in deps) {
2890
- return String(deps[name]);
2891
- }
2892
- }
2893
- return void 0;
2894
- }
2895
- function isPlainObject2(value) {
2896
- return typeof value === "object" && value !== null && !Array.isArray(value);
3145
+ return path12.extname(realPath).toLowerCase() === ".css";
2897
3146
  }
2898
3147
  function planThemeAdd(baseDirInput, brand) {
2899
- const baseDir = path10.resolve(baseDirInput);
3148
+ const baseDir = path12.resolve(baseDirInput);
2900
3149
  const plan = {
2901
3150
  baseDir,
2902
3151
  brand,
@@ -2908,7 +3157,7 @@ function planThemeAdd(baseDirInput, brand) {
2908
3157
  installCommand: detectInstallCommand(baseDir),
2909
3158
  writes: []
2910
3159
  };
2911
- const configFile = path10.join(baseDir, AXIS_CONFIG_FILE);
3160
+ const configFile = path12.join(baseDir, AXIS_CONFIG_FILE);
2912
3161
  const configText = readText(configFile);
2913
3162
  if (configText === null) {
2914
3163
  plan.errors.push({ kind: "no-config" });
@@ -2974,7 +3223,7 @@ function planThemeAdd(baseDirInput, brand) {
2974
3223
  } else {
2975
3224
  plan.css = { configuredMissing: location.configuredMissing, action: "manual", otherBrands: [] };
2976
3225
  }
2977
- const pkgFile = path10.join(baseDir, "package.json");
3226
+ const pkgFile = path12.join(baseDir, "package.json");
2978
3227
  const pkgText = readText(pkgFile);
2979
3228
  const installed = plan.tokens.version;
2980
3229
  const upgrade = installed !== void 0 && (compareVersions(installed, MIN_BRAND_TOKENS_VERSION) ?? 0) < 0;
@@ -3034,8 +3283,8 @@ function applyThemeAdd(plan) {
3034
3283
  if (current !== w.before) {
3035
3284
  throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
3036
3285
  }
3037
- const where = realPathInside(plan.baseDir, w.before === null ? path10.dirname(w.file) : w.file);
3038
- if (!where.inside && !(w.before === null && path10.dirname(w.file) === plan.baseDir)) {
3286
+ const where = realPathInside(plan.baseDir, w.before === null ? path12.dirname(w.file) : w.file);
3287
+ if (!where.inside && !(w.before === null && path12.dirname(w.file) === plan.baseDir)) {
3039
3288
  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.`);
3040
3289
  }
3041
3290
  if (!w.file.endsWith(".json") && !isStylesheet(where.realPath)) {
@@ -3047,7 +3296,7 @@ function applyThemeAdd(plan) {
3047
3296
  throw new Error(`${w.file}: \uBE0C\uB79C\uB4DC import \uAC00 \uC815\uD655\uD788 1\uC904\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
3048
3297
  }
3049
3298
  try {
3050
- accessSync(w.before === null ? path10.dirname(w.file) : w.file, constants.W_OK);
3299
+ accessSync(w.before === null ? path12.dirname(w.file) : w.file, constants.W_OK);
3051
3300
  } catch (err) {
3052
3301
  throw new Error(`${w.file} \uC5D0 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errorMessage(err)}).`);
3053
3302
  }
@@ -3086,22 +3335,22 @@ function tokensStatusGuide(status, version) {
3086
3335
  switch (status) {
3087
3336
  case "not-installed":
3088
3337
  return [
3089
- chalk8.yellow(`${TOKENS_PACKAGE} \uAC00 \uC124\uCE58\uB3FC \uC788\uC9C0 \uC54A\uC544 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`),
3090
- ` \uC124\uCE58: ${chalk8.cyan(TOKENS_INSTALL_COMMAND)}`
3338
+ chalk9.yellow(`${TOKENS_PACKAGE} \uAC00 \uC124\uCE58\uB3FC \uC788\uC9C0 \uC54A\uC544 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`),
3339
+ ` \uC124\uCE58: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
3091
3340
  ];
3092
3341
  case "unsupported":
3093
3342
  return [
3094
- chalk8.yellow(
3343
+ chalk9.yellow(
3095
3344
  `${TOKENS_PACKAGE} ${version ?? "(\uBC84\uC804 \uBAA8\uB984)"} \uC740 \uBE0C\uB79C\uB4DC\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${MIN_BRAND_TOKENS_VERSION} \uC774\uC0C1 \uD544\uC694).`
3096
3345
  ),
3097
- ` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk8.cyan(TOKENS_INSTALL_COMMAND)}`
3346
+ ` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
3098
3347
  ];
3099
3348
  case "not-built":
3100
3349
  return [
3101
- chalk8.yellow(
3350
+ chalk9.yellow(
3102
3351
  `${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.`
3103
3352
  ),
3104
- ` \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 ${chalk8.cyan(`pnpm --filter ${TOKENS_PACKAGE} build`)}, \uC544\uB2C8\uBA74 \uC7AC\uC124\uCE58: ${chalk8.cyan(TOKENS_INSTALL_COMMAND)}`
3353
+ ` \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 ${chalk9.cyan(`pnpm --filter ${TOKENS_PACKAGE} build`)}, \uC544\uB2C8\uBA74 \uC7AC\uC124\uCE58: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
3105
3354
  ];
3106
3355
  }
3107
3356
  }
@@ -3111,22 +3360,22 @@ function renderThemeList(result) {
3111
3360
  }
3112
3361
  if (result.brands.length === 0) {
3113
3362
  return {
3114
- lines: ["", chalk8.yellow(`\uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${result.version ?? ""} \uC5D0 \uBE0C\uB79C\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.`), ""],
3363
+ lines: ["", chalk9.yellow(`\uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${result.version ?? ""} \uC5D0 \uBE0C\uB79C\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.`), ""],
3115
3364
  exitCode: 0
3116
3365
  };
3117
3366
  }
3118
3367
  const width = Math.max(...result.brands.map((b) => b.name.length));
3119
3368
  const lines = [
3120
3369
  "",
3121
- chalk8.blue(`AXIS \uBE0C\uB79C\uB4DC (${result.brands.length}\uAC1C, ${TOKENS_PACKAGE} ${result.version ?? ""})`),
3370
+ chalk9.blue(`AXIS \uBE0C\uB79C\uB4DC (${result.brands.length}\uAC1C, ${TOKENS_PACKAGE} ${result.version ?? ""})`),
3122
3371
  ""
3123
3372
  ];
3124
3373
  for (const b of result.brands) {
3125
3374
  lines.push(
3126
- ` ${chalk8.cyan(b.name.padEnd(width))} ${b.description} ${chalk8.gray(`(${b.themes.join(" \xB7 ")})`)}`
3375
+ ` ${chalk9.cyan(b.name.padEnd(width))} ${b.description} ${chalk9.gray(`(${b.themes.join(" \xB7 ")})`)}`
3127
3376
  );
3128
3377
  }
3129
- lines.push("", chalk8.gray("\uC0AC\uC6A9\uBC95: axis theme info <brand>"), "");
3378
+ lines.push("", chalk9.gray("\uC0AC\uC6A9\uBC95: axis theme info <brand>"), "");
3130
3379
  return { lines, exitCode: 0 };
3131
3380
  }
3132
3381
  function a11yValue(value) {
@@ -3142,13 +3391,13 @@ function tokenTable(brand) {
3142
3391
  const header = ["\uD1A0\uD070", "\uB77C\uC774\uD2B8", "\uB2E4\uD06C"];
3143
3392
  const w0 = Math.max(header[0].length, ...rows.map((r) => r[0].length));
3144
3393
  const w1 = Math.max(header[1].length, ...rows.map((r) => r[1].length));
3145
- lines.push(chalk8.gray(` ${header[0].padEnd(w0)} ${header[1].padEnd(w1)} ${header[2]}`));
3394
+ lines.push(chalk9.gray(` ${header[0].padEnd(w0)} ${header[1].padEnd(w1)} ${header[2]}`));
3146
3395
  for (const [k, l, d] of rows) {
3147
3396
  lines.push(` ${k.padEnd(w0)} ${l.padEnd(w1)} ${d}`);
3148
3397
  }
3149
3398
  }
3150
3399
  if (missing.length > 0) {
3151
- lines.push(chalk8.gray(` \uBE0C\uB79C\uB4DC\uAC00 \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC74C: ${missing.join(", ")}`));
3400
+ lines.push(chalk9.gray(` \uBE0C\uB79C\uB4DC\uAC00 \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC74C: ${missing.join(", ")}`));
3152
3401
  }
3153
3402
  return lines;
3154
3403
  }
@@ -3161,9 +3410,9 @@ function renderThemeInfo(result, name) {
3161
3410
  return {
3162
3411
  lines: [
3163
3412
  "",
3164
- chalk8.red(`\uBE0C\uB79C\uB4DC '${name}' \uAC00 \uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${result.version ?? ""} \uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4.`),
3413
+ chalk9.red(`\uBE0C\uB79C\uB4DC '${name}' \uAC00 \uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${result.version ?? ""} \uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4.`),
3165
3414
  ` \uC124\uCE58\uB41C \uBE0C\uB79C\uB4DC: ${result.available.length > 0 ? result.available.join(", ") : "(\uC5C6\uC74C)"}`,
3166
- chalk8.gray(" \uBAA9\uB85D: axis theme list"),
3415
+ chalk9.gray(" \uBAA9\uB85D: axis theme list"),
3167
3416
  ""
3168
3417
  ],
3169
3418
  exitCode: 1
@@ -3171,34 +3420,34 @@ function renderThemeInfo(result, name) {
3171
3420
  }
3172
3421
  const lines = [
3173
3422
  "",
3174
- chalk8.blue(`\uBE0C\uB79C\uB4DC ${brand.name}`),
3423
+ chalk9.blue(`\uBE0C\uB79C\uB4DC ${brand.name}`),
3175
3424
  ` \uC124\uBA85: ${brand.description}`,
3176
3425
  ` \uD14C\uB9C8: ${brand.themes.join(" \xB7 ")}`,
3177
3426
  "",
3178
- chalk8.bold("Import (globals.css, @charset \xB7 \uB2E4\uB978 @import \uB2E4\uC74C)"),
3427
+ chalk9.bold("Import (globals.css, @charset \xB7 \uB2E4\uB978 @import \uB2E4\uC74C)"),
3179
3428
  ` @import "${brand.importPath}";`,
3180
3429
  "",
3181
- chalk8.bold("Provider (@axis-ds/theme 1.3.0 \uC774\uC0C1)"),
3430
+ chalk9.bold("Provider (@axis-ds/theme 1.3.0 \uC774\uC0C1)"),
3182
3431
  ...brand.providerExample.split("\n").map((l) => l ? ` ${l}` : ""),
3183
- chalk8.gray(
3432
+ chalk9.gray(
3184
3433
  ` ThemeProvider \uB098 <html data-brand="${brand.name}"> \uAC00 \uC5C6\uC73C\uBA74 import \uB9CC\uC73C\uB85C\uB294 \uD654\uBA74\uC774 \uBC14\uB00C\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`
3185
3434
  ),
3186
3435
  "",
3187
- chalk8.bold("\uC8FC\uC694 \uD1A0\uD070"),
3436
+ chalk9.bold("\uC8FC\uC694 \uD1A0\uD070"),
3188
3437
  ...tokenTable(brand),
3189
3438
  "",
3190
- chalk8.bold("\uBCF4\uC815 \uB0B4\uC5ED"),
3439
+ chalk9.bold("\uBCF4\uC815 \uB0B4\uC5ED"),
3191
3440
  ` a11y \uC0C1\uD0DC: ${a11yValue(brand.adjustments.a11y.status)}`,
3192
3441
  ` \uC810\uAC80\uC77C: ${a11yValue(brand.adjustments.a11y.checkedAt)}`,
3193
3442
  ` \uAC8C\uC774\uD2B8: ${a11yValue(brand.adjustments.a11y.gate)}`,
3194
3443
  ` \uADFC\uAC70 \uBB38\uC11C: ${brand.adjustments.reference}`,
3195
- chalk8.gray(" \uBCF4\uC815 \uC804 \xB7 \uD6C4 \uAC12\uC740 \uC774 \uBC84\uC804\uC5D0\uC11C \uCD9C\uB825\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."),
3444
+ chalk9.gray(" \uBCF4\uC815 \uC804 \xB7 \uD6C4 \uAC12\uC740 \uC774 \uBC84\uC804\uC5D0\uC11C \uCD9C\uB825\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."),
3196
3445
  ""
3197
3446
  ];
3198
3447
  return { lines, exitCode: 0 };
3199
3448
  }
3200
3449
  function rel(plan, file) {
3201
- return path11.relative(plan.baseDir, file) || file;
3450
+ return path13.relative(plan.baseDir, file) || file;
3202
3451
  }
3203
3452
  function renderThemeAdd(plan, written) {
3204
3453
  const error = plan.errors[0];
@@ -3207,24 +3456,24 @@ function renderThemeAdd(plan, written) {
3207
3456
  switch (error.kind) {
3208
3457
  case "no-config":
3209
3458
  lines2.push(
3210
- chalk8.red("axis.config.json \uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."),
3211
- ` \uBA3C\uC800 ${chalk8.cyan("axis init")} \uC744 \uC2E4\uD589\uD558\uC138\uC694.`
3459
+ chalk9.red("axis.config.json \uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."),
3460
+ ` \uBA3C\uC800 ${chalk9.cyan("axis init")} \uC744 \uC2E4\uD589\uD558\uC138\uC694.`
3212
3461
  );
3213
3462
  break;
3214
3463
  case "invalid-config":
3215
- lines2.push(chalk8.red(`axis.config.json \uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${error.message}). \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
3464
+ lines2.push(chalk9.red(`axis.config.json \uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${error.message}). \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
3216
3465
  break;
3217
3466
  case "invalid-package-json":
3218
- lines2.push(chalk8.red(`package.json \uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${error.message}). \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
3467
+ lines2.push(chalk9.red(`package.json \uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${error.message}). \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
3219
3468
  break;
3220
3469
  case "invalid-name":
3221
3470
  lines2.push(
3222
- chalk8.red(`\uBE0C\uB79C\uB4DC \uC774\uB984 '${error.brand}' \uAC00 \uADDC\uCE59(\uC18C\uBB38\uC790 \xB7 \uC22B\uC790 \xB7 \uD558\uC774\uD508, \uC608: ontology)\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`)
3471
+ chalk9.red(`\uBE0C\uB79C\uB4DC \uC774\uB984 '${error.brand}' \uAC00 \uADDC\uCE59(\uC18C\uBB38\uC790 \xB7 \uC22B\uC790 \xB7 \uD558\uC774\uD508, \uC608: ontology)\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`)
3223
3472
  );
3224
3473
  break;
3225
3474
  case "css-outside-project":
3226
3475
  lines2.push(
3227
- chalk8.red(
3476
+ chalk9.red(
3228
3477
  `CSS \uD30C\uC77C ${error.file} \uC758 \uC2E4\uC81C \uC704\uCE58(${error.realPath})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`
3229
3478
  ),
3230
3479
  ` axis.config.json \uC758 globalCss \uB97C \uD504\uB85C\uC81D\uD2B8 \uC548 \uD30C\uC77C\uB85C \uACE0\uCE58\uAC70\uB098, \uADF8 \uD30C\uC77C\uC5D0 \uC9C1\uC811 \uB123\uC73C\uC138\uC694: @import "${plan.importPath}";`
@@ -3232,25 +3481,25 @@ function renderThemeAdd(plan, written) {
3232
3481
  break;
3233
3482
  case "css-not-stylesheet":
3234
3483
  lines2.push(
3235
- chalk8.red(`${error.file} \uC758 \uC2E4\uC81C \uB300\uC0C1(${error.realPath})\uC774 CSS \uD30C\uC77C(.css)\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`),
3484
+ chalk9.red(`${error.file} \uC758 \uC2E4\uC81C \uB300\uC0C1(${error.realPath})\uC774 CSS \uD30C\uC77C(.css)\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`),
3236
3485
  ` axis.config.json \uC758 globalCss \uB97C \uC804\uC5ED CSS \uD30C\uC77C\uB85C \uACE0\uCE58\uAC70\uB098, \uADF8 \uD30C\uC77C\uC5D0 \uC9C1\uC811 \uB123\uC73C\uC138\uC694: @import "${plan.importPath}";`
3237
3486
  );
3238
3487
  break;
3239
3488
  case "unknown-brand":
3240
3489
  lines2.push(
3241
- chalk8.red(`\uBE0C\uB79C\uB4DC '${error.brand}' \uAC00 \uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${error.version ?? ""} \uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4.`),
3490
+ chalk9.red(`\uBE0C\uB79C\uB4DC '${error.brand}' \uAC00 \uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${error.version ?? ""} \uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4.`),
3242
3491
  ` \uC124\uCE58\uB41C \uBE0C\uB79C\uB4DC: ${error.available.length > 0 ? error.available.join(", ") : "(\uC5C6\uC74C)"}`,
3243
- chalk8.gray(" \uBAA9\uB85D: axis theme list")
3492
+ chalk9.gray(" \uBAA9\uB85D: axis theme list")
3244
3493
  );
3245
3494
  break;
3246
3495
  }
3247
3496
  lines2.push("");
3248
3497
  return { lines: lines2, exitCode: 1 };
3249
3498
  }
3250
- const lines = ["", chalk8.blue(`\uBE0C\uB79C\uB4DC ${plan.brand} \uC801\uC6A9`), ""];
3499
+ const lines = ["", chalk9.blue(`\uBE0C\uB79C\uB4DC ${plan.brand} \uC801\uC6A9`), ""];
3251
3500
  if (plan.unverifiedBrand) {
3252
3501
  lines.push(
3253
- chalk8.yellow(
3502
+ chalk9.yellow(
3254
3503
  ` ! ${TOKENS_PACKAGE} \uB97C \uC77D\uC744 \uC218 \uC5C6\uC5B4(${plan.tokens.status}) \uC774\uB984 \uADDC\uCE59\uB9CC \uD655\uC778\uD588\uC2B5\uB2C8\uB2E4. \uC124\uCE58 \uD6C4 axis theme list \uB85C '${plan.brand}' \uAC00 \uC788\uB294\uC9C0 \uD655\uC778\uD558\uC138\uC694.`
3255
3504
  )
3256
3505
  );
@@ -3258,24 +3507,24 @@ function renderThemeAdd(plan, written) {
3258
3507
  const css = plan.css;
3259
3508
  if (css?.configuredMissing) {
3260
3509
  lines.push(
3261
- chalk8.yellow(
3510
+ chalk9.yellow(
3262
3511
  css.file ? ` ! axis.config.json \uC758 globalCss(${css.configuredMissing})\uAC00 \uC5C6\uC5B4 ${rel(plan, css.file)} \uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.` : ` ! axis.config.json \uC758 globalCss(${css.configuredMissing})\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.`
3263
3512
  )
3264
3513
  );
3265
3514
  }
3266
3515
  if (css?.action === "add" && css.file) {
3267
- lines.push(` ${chalk8.green("\u2713")} ${rel(plan, css.file)}: @import "${plan.importPath}"; \uCD94\uAC00`);
3516
+ lines.push(` ${chalk9.green("\u2713")} ${rel(plan, css.file)}: @import "${plan.importPath}"; \uCD94\uAC00`);
3268
3517
  } else if (css?.action === "exists" && css.file) {
3269
- lines.push(` ${chalk8.gray("-")} ${rel(plan, css.file)}: import \uAC00 \uC774\uBBF8 \uC788\uC5B4 \uAC74\uB108\uB700`);
3518
+ lines.push(` ${chalk9.gray("-")} ${rel(plan, css.file)}: import \uAC00 \uC774\uBBF8 \uC788\uC5B4 \uAC74\uB108\uB700`);
3270
3519
  } else {
3271
3520
  lines.push(
3272
- chalk8.yellow(" ! CSS \uC9C4\uC785\uC810(globalCss \xB7 app/globals.css \xB7 src/app/globals.css \xB7 globals.css)\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4."),
3521
+ chalk9.yellow(" ! CSS \uC9C4\uC785\uC810(globalCss \xB7 app/globals.css \xB7 src/app/globals.css \xB7 globals.css)\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4."),
3273
3522
  ` \uC804\uC5ED CSS \uB9E8 \uC55E(@charset \xB7 \uB2E4\uB978 @import \uB2E4\uC74C)\uC5D0 \uC9C1\uC811 \uB123\uC73C\uC138\uC694: @import "${plan.importPath}";`
3274
3523
  );
3275
3524
  }
3276
3525
  if (css && css.otherBrands.length > 0) {
3277
3526
  lines.push(
3278
- chalk8.yellow(
3527
+ chalk9.yellow(
3279
3528
  ` ! \uB2E4\uB978 \uBE0C\uB79C\uB4DC import(${css.otherBrands.join(", ")})\uB294 \uADF8\uB300\uB85C \uB450\uC5C8\uC2B5\uB2C8\uB2E4. \uC4F0\uC9C0 \uC54A\uC73C\uBA74 \uC774\uC804 \uBE0C\uB79C\uB4DC import \uB97C \uC9C0\uC6CC\uB3C4 \uB429\uB2C8\uB2E4.`
3280
3529
  )
3281
3530
  );
@@ -3283,60 +3532,60 @@ function renderThemeAdd(plan, written) {
3283
3532
  const dep = plan.dependency;
3284
3533
  if (dep?.action === "add") {
3285
3534
  lines.push(
3286
- ` ${chalk8.green("\u2713")} package.json: dependencies \uC5D0 "${TOKENS_PACKAGE}": "${TOKENS_DEPENDENCY_RANGE}" \uCD94\uAC00`,
3287
- ` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk8.cyan(plan.installCommand)}`
3535
+ ` ${chalk9.green("\u2713")} package.json: dependencies \uC5D0 "${TOKENS_PACKAGE}": "${TOKENS_DEPENDENCY_RANGE}" \uCD94\uAC00`,
3536
+ ` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk9.cyan(plan.installCommand)}`
3288
3537
  );
3289
3538
  } else if (dep?.action === "present") {
3290
- lines.push(` ${chalk8.gray("-")} package.json: ${TOKENS_PACKAGE} ${dep.declaredRange} \uAC00 \uC774\uBBF8 \uC788\uC5B4 \uBC94\uC704\uB97C \uBC14\uAFB8\uC9C0 \uC54A\uC74C`);
3539
+ lines.push(` ${chalk9.gray("-")} package.json: ${TOKENS_PACKAGE} ${dep.declaredRange} \uAC00 \uC774\uBBF8 \uC788\uC5B4 \uBC94\uC704\uB97C \uBC14\uAFB8\uC9C0 \uC54A\uC74C`);
3291
3540
  } else if (dep?.action === "no-package-json") {
3292
3541
  lines.push(
3293
- chalk8.yellow(` ! package.json \uC774 \uC5C6\uC5B4 \uC758\uC874\uC131\uC744 \uCD94\uAC00\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${TOKENS_INSTALL_COMMAND}`)
3542
+ chalk9.yellow(` ! package.json \uC774 \uC5C6\uC5B4 \uC758\uC874\uC131\uC744 \uCD94\uAC00\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${TOKENS_INSTALL_COMMAND}`)
3294
3543
  );
3295
3544
  }
3296
3545
  if (dep?.upgrade) {
3297
3546
  lines.push(
3298
- chalk8.yellow(
3547
+ chalk9.yellow(
3299
3548
  ` ! \uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${plan.tokens.version} \uC740 \uBE0C\uB79C\uB4DC\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${MIN_BRAND_TOKENS_VERSION} \uC774\uC0C1 \uD544\uC694).`
3300
3549
  ),
3301
- ` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk8.cyan(TOKENS_INSTALL_COMMAND)}`
3550
+ ` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
3302
3551
  );
3303
3552
  }
3304
3553
  if (plan.configChanged) {
3305
- lines.push(` ${chalk8.green("\u2713")} axis.config.json: "brand": "${plan.brand}" \uAE30\uB85D`);
3554
+ lines.push(` ${chalk9.green("\u2713")} axis.config.json: "brand": "${plan.brand}" \uAE30\uB85D`);
3306
3555
  } else {
3307
- lines.push(` ${chalk8.gray("-")} axis.config.json: brand \uAC00 \uC774\uBBF8 "${plan.brand}"`);
3556
+ lines.push(` ${chalk9.gray("-")} axis.config.json: brand \uAC00 \uC774\uBBF8 "${plan.brand}"`);
3308
3557
  }
3309
3558
  lines.push(
3310
3559
  "",
3311
- chalk8.bold(`Provider (${THEME_PACKAGE} 1.3.0 \uC774\uC0C1)`),
3560
+ chalk9.bold(`Provider (${THEME_PACKAGE} 1.3.0 \uC774\uC0C1)`),
3312
3561
  ...providerExample(plan.brand).split("\n").map((l) => l ? ` ${l}` : ""),
3313
- chalk8.gray(
3562
+ chalk9.gray(
3314
3563
  ` ThemeProvider \uB098 <html data-brand="${plan.brand}"> \uAC00 \uC5C6\uC73C\uBA74 import \uB9CC\uC73C\uB85C\uB294 \uD654\uBA74\uC774 \uBC14\uB00C\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`
3315
3564
  )
3316
3565
  );
3317
3566
  if (dep?.themeMissing) {
3318
- lines.push(` ${THEME_PACKAGE} \uC124\uCE58: ${chalk8.cyan(`pnpm add ${THEME_PACKAGE}@^1.3.0`)}`);
3567
+ lines.push(` ${THEME_PACKAGE} \uC124\uCE58: ${chalk9.cyan(`pnpm add ${THEME_PACKAGE}@^1.3.0`)}`);
3319
3568
  }
3320
- lines.push("", chalk8.gray(written.length > 0 ? `\uD30C\uC77C ${written.length}\uAC1C\uB97C \uBC14\uAFE8\uC2B5\uB2C8\uB2E4.` : "\uBC14\uAFBC \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."), "");
3569
+ lines.push("", chalk9.gray(written.length > 0 ? `\uD30C\uC77C ${written.length}\uAC1C\uB97C \uBC14\uAFE8\uC2B5\uB2C8\uB2E4.` : "\uBC14\uAFBC \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."), "");
3321
3570
  return { lines, exitCode: 0 };
3322
3571
  }
3323
3572
  function renderThemeAddFailure(plan, err) {
3324
3573
  const lines = [""];
3325
3574
  if (err instanceof ThemeApplyError) {
3326
- lines.push(chalk8.red(err.message));
3575
+ lines.push(chalk9.red(err.message));
3327
3576
  if (err.restored.length > 0) {
3328
3577
  lines.push(` \uBA3C\uC800 \uC4F4 \uD30C\uC77C\uC740 \uC6D0\uB798 \uB0B4\uC6A9\uC73C\uB85C \uB418\uB3CC\uB838\uC2B5\uB2C8\uB2E4: ${err.restored.map((f) => rel(plan, f)).join(", ")}`);
3329
3578
  }
3330
3579
  if (err.restoreFailed.length > 0) {
3331
3580
  lines.push(
3332
- chalk8.red(` \uB418\uB3CC\uB9AC\uC9C0 \uBABB\uD574 \uBC14\uB010 \uCC44 \uB0A8\uC740 \uD30C\uC77C: ${err.restoreFailed.map((f) => rel(plan, f)).join(", ")}`)
3581
+ chalk9.red(` \uB418\uB3CC\uB9AC\uC9C0 \uBABB\uD574 \uBC14\uB010 \uCC44 \uB0A8\uC740 \uD30C\uC77C: ${err.restoreFailed.map((f) => rel(plan, f)).join(", ")}`)
3333
3582
  );
3334
3583
  }
3335
3584
  if (err.restored.length === 0 && err.restoreFailed.length === 0) {
3336
3585
  lines.push(" \uBC14\uB010 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
3337
3586
  }
3338
3587
  } else {
3339
- lines.push(chalk8.red(err instanceof Error ? err.message : String(err)), " \uBC14\uB010 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
3588
+ lines.push(chalk9.red(err instanceof Error ? err.message : String(err)), " \uBC14\uB010 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
3340
3589
  }
3341
3590
  lines.push("");
3342
3591
  return { lines, exitCode: 1 };
@@ -3348,15 +3597,15 @@ function print(output) {
3348
3597
  function registerThemeCommand(program2) {
3349
3598
  const themeCmd = program2.command("theme").description("\uBE0C\uB79C\uB4DC \uD14C\uB9C8 (@axis-ds/tokens \uBE0C\uB79C\uB4DC)");
3350
3599
  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) => {
3351
- const baseDir = path11.resolve(options.dir || ".");
3600
+ const baseDir = path13.resolve(options.dir || ".");
3352
3601
  print(renderThemeList(listBrands(baseDir)));
3353
3602
  });
3354
3603
  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) => {
3355
- const baseDir = path11.resolve(options.dir || ".");
3604
+ const baseDir = path13.resolve(options.dir || ".");
3356
3605
  print(renderThemeInfo(getBrand(baseDir, name), name));
3357
3606
  });
3358
3607
  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) => {
3359
- const baseDir = path11.resolve(options.dir || ".");
3608
+ const baseDir = path13.resolve(options.dir || ".");
3360
3609
  const plan = planThemeAdd(baseDir, name);
3361
3610
  let written = [];
3362
3611
  if (plan.errors.length === 0) {
@@ -3372,17 +3621,17 @@ function registerThemeCommand(program2) {
3372
3621
  }
3373
3622
 
3374
3623
  // src/init/index.ts
3375
- import chalk10 from "chalk";
3624
+ import chalk11 from "chalk";
3376
3625
  import prompts2 from "prompts";
3377
3626
 
3378
- // src/registry/schema.ts
3627
+ // ../axis-registry-core/src/registry/schema.ts
3379
3628
  import { createHash } from "crypto";
3380
3629
  var REGISTRY_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
3381
3630
  var REGISTRY_NAME_MAX_LENGTH = 64;
3382
3631
  function isValidRegistryName(name) {
3383
3632
  return typeof name === "string" && name.length > 0 && name.length <= REGISTRY_NAME_MAX_LENGTH && REGISTRY_NAME_PATTERN.test(name);
3384
3633
  }
3385
- var REGISTRY_PUBLIC_BASE_URL = "https://axis-design-system.pages.dev/r";
3634
+ var REGISTRY_PUBLIC_BASE_URL = `${AXIS_SITE_URL}/r`;
3386
3635
  function redactRegistryUrl(raw) {
3387
3636
  return maskQueryAndHash(redactUserinfo(raw));
3388
3637
  }
@@ -3579,7 +3828,7 @@ function checkItemSha256(item, entry, where = `${item.name}.json`) {
3579
3828
  }
3580
3829
  }
3581
3830
 
3582
- // src/registry/remote.ts
3831
+ // ../axis-registry-core/src/registry/remote.ts
3583
3832
  var DEFAULT_REGISTRY_URL = REGISTRY_PUBLIC_BASE_URL;
3584
3833
  var DEFAULT_REGISTRY_TIMEOUT_MS = 5e3;
3585
3834
  var LEGACY_DEFAULT_REGISTRY_URL = "https://axis.minu.best/r";
@@ -3648,10 +3897,18 @@ async function fetchRegistryJson(url, options = {}) {
3648
3897
  try {
3649
3898
  let res;
3650
3899
  try {
3651
- res = await fetchImpl(url, { signal: controller.signal, headers: { accept: "application/json" } });
3900
+ res = await fetchImpl(url, {
3901
+ signal: controller.signal,
3902
+ headers: { accept: "application/json" },
3903
+ ...options.rejectRedirects ? { redirect: "manual" } : {}
3904
+ });
3652
3905
  } catch (error) {
3653
3906
  throw describe(error);
3654
3907
  }
3908
+ if (options.rejectRedirects && (res.type === "opaqueredirect" || res.status >= 300 && res.status < 400 || res.status === 0)) {
3909
+ await res.text().catch(() => void 0);
3910
+ throw new RegistryAccessError(`${shown}: \uB9AC\uB2E4\uC774\uB809\uD2B8(HTTP ${res.status})\uB97C \uB530\uB77C\uAC00\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`);
3911
+ }
3655
3912
  if (!res.ok) {
3656
3913
  await res.text().catch(() => void 0);
3657
3914
  throw new RegistryAccessError(`${shown}: HTTP ${res.status}`);
@@ -3668,15 +3925,15 @@ async function fetchRegistryJson(url, options = {}) {
3668
3925
  }
3669
3926
 
3670
3927
  // src/init/init.ts
3671
- import { accessSync as accessSync2, constants as constants2, existsSync as existsSync5, lstatSync as lstatSync2, readFileSync as readFileSync4, realpathSync as realpathSync3, statSync as statSync3, writeFileSync as writeFileSync2 } from "fs";
3672
- import path13 from "path";
3673
- import chalk9 from "chalk";
3674
- import fs11 from "fs-extra";
3928
+ import { accessSync as accessSync2, constants as constants2, existsSync as existsSync6, lstatSync as lstatSync2, readFileSync as readFileSync4, realpathSync as realpathSync3, statSync as statSync3, writeFileSync as writeFileSync2 } from "fs";
3929
+ import path15 from "path";
3930
+ import chalk10 from "chalk";
3931
+ import fs12 from "fs-extra";
3675
3932
 
3676
- // src/add/safe-write.ts
3677
- import { constants as fsConstants, existsSync as existsSync4, lstatSync, realpathSync as realpathSync2, statSync as statSync2 } from "fs";
3678
- import path12 from "path";
3679
- import fs10 from "fs-extra";
3933
+ // ../axis-registry-core/src/add/safe-write.ts
3934
+ import { constants as fsConstants, existsSync as existsSync5, lstatSync, realpathSync as realpathSync2, statSync as statSync2 } from "fs";
3935
+ import path14 from "path";
3936
+ import fs11 from "fs-extra";
3680
3937
  var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
3681
3938
  var OVERWRITE_FLAGS = fsConstants.O_WRONLY | (fsConstants.O_NOFOLLOW ?? 0);
3682
3939
  var HARDLINK_ERROR_CODE = "EAXISHARDLINK";
@@ -3686,15 +3943,15 @@ function codedError(code, message) {
3686
3943
  e.code = code;
3687
3944
  return e;
3688
3945
  }
3689
- function isSameOrInside(parent, child, impl = path12) {
3946
+ function isSameOrInside(parent, child, impl = path14) {
3690
3947
  const rel3 = impl.relative(parent, child);
3691
3948
  if (rel3 === "") return true;
3692
3949
  return !(rel3 === ".." || rel3.startsWith(`..${impl.sep}`) || impl.isAbsolute(rel3));
3693
3950
  }
3694
3951
  function nearestExisting(p) {
3695
3952
  let cur = p;
3696
- while (!existsSync4(cur)) {
3697
- const up = path12.dirname(cur);
3953
+ while (!existsSync5(cur)) {
3954
+ const up = path14.dirname(cur);
3698
3955
  if (up === cur) return cur;
3699
3956
  cur = up;
3700
3957
  }
@@ -3702,10 +3959,10 @@ function nearestExisting(p) {
3702
3959
  }
3703
3960
  function escapeReason(root, target, options = {}) {
3704
3961
  const realRoot = realpathSync2(root);
3705
- if (!isSameOrInside(path12.resolve(root), path12.resolve(target)) || path12.resolve(target) === path12.resolve(root)) {
3962
+ if (!isSameOrInside(path14.resolve(root), path14.resolve(target)) || path14.resolve(target) === path14.resolve(root)) {
3706
3963
  return `\uACBD\uB85C\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4(${target})`;
3707
3964
  }
3708
- const anchor = nearestExisting(path12.dirname(target));
3965
+ const anchor = nearestExisting(path14.dirname(target));
3709
3966
  const realAnchor = realpathSync2(anchor);
3710
3967
  if (!isSameOrInside(realRoot, realAnchor)) {
3711
3968
  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`;
@@ -3718,7 +3975,7 @@ function escapeReason(root, target, options = {}) {
3718
3975
  }
3719
3976
  if (st) {
3720
3977
  if (st.isDirectory()) return `\uAC19\uC740 \uC774\uB984\uC758 \uB514\uB809\uD130\uB9AC\uAC00 \uC788\uC2B5\uB2C8\uB2E4(${target})`;
3721
- const shown = path12.relative(path12.resolve(root), path12.resolve(target)).split(path12.sep).join("/");
3978
+ const shown = path14.relative(path14.resolve(root), path14.resolve(target)).split(path14.sep).join("/");
3722
3979
  let realTarget;
3723
3980
  try {
3724
3981
  realTarget = realpathSync2(target);
@@ -3786,50 +4043,50 @@ async function writeNoFollow(target, content, mode) {
3786
4043
  let fd;
3787
4044
  if (mode === "overwrite") {
3788
4045
  try {
3789
- fd = await fs10.open(target, OVERWRITE_FLAGS);
4046
+ fd = await fs11.open(target, OVERWRITE_FLAGS);
3790
4047
  } catch (e) {
3791
4048
  if (e.code !== "ENOENT") throw e;
3792
4049
  actual = "new";
3793
- fd = await fs10.open(target, NEW_FILE_FLAGS, 438);
4050
+ fd = await fs11.open(target, NEW_FILE_FLAGS, 438);
3794
4051
  }
3795
4052
  } else {
3796
- fd = await fs10.open(target, NEW_FILE_FLAGS, 438);
4053
+ fd = await fs11.open(target, NEW_FILE_FLAGS, 438);
3797
4054
  }
3798
4055
  try {
3799
4056
  if (actual === "overwrite") {
3800
- const st = await fs10.fstat(fd);
4057
+ const st = await fs11.fstat(fd);
3801
4058
  if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
3802
4059
  if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
3803
- await fs10.ftruncate(fd, 0);
4060
+ await fs11.ftruncate(fd, 0);
3804
4061
  }
3805
- await fs10.writeFile(fd, content);
4062
+ await fs11.writeFile(fd, content);
3806
4063
  } finally {
3807
- await fs10.close(fd);
4064
+ await fs11.close(fd);
3808
4065
  }
3809
4066
  return actual;
3810
4067
  }
3811
4068
  async function overwriteFollowingLinks(target, content) {
3812
- const fd = await fs10.open(target, fsConstants.O_WRONLY | fsConstants.O_CREAT, 438);
4069
+ const fd = await fs11.open(target, fsConstants.O_WRONLY | fsConstants.O_CREAT, 438);
3813
4070
  try {
3814
- const st = await fs10.fstat(fd);
4071
+ const st = await fs11.fstat(fd);
3815
4072
  if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
3816
4073
  if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
3817
- await fs10.ftruncate(fd, 0);
3818
- await fs10.writeFile(fd, content);
4074
+ await fs11.ftruncate(fd, 0);
4075
+ await fs11.writeFile(fd, content);
3819
4076
  } finally {
3820
- await fs10.close(fd);
4077
+ await fs11.close(fd);
3821
4078
  }
3822
4079
  }
3823
4080
  function checkParentInside(root, target) {
3824
4081
  const realRoot = realpathSync2(root);
3825
- const realParent = realpathSync2(path12.dirname(target));
4082
+ const realParent = realpathSync2(path14.dirname(target));
3826
4083
  if (!isSameOrInside(realRoot, realParent)) {
3827
4084
  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`;
3828
4085
  }
3829
4086
  return escapeReason(root, target);
3830
4087
  }
3831
4088
 
3832
- // src/init/init.ts
4089
+ // ../axis-registry-core/src/utils-deps.ts
3833
4090
  var CLSX_RANGE = "^2.1.1";
3834
4091
  var TAILWIND_MERGE_RANGES = {
3835
4092
  tailwind4: "^3.4.0",
@@ -3841,6 +4098,8 @@ function selectUtilsDependencies(tailwind) {
3841
4098
  "tailwind-merge": tailwind.major !== void 0 && tailwind.major >= 4 ? TAILWIND_MERGE_RANGES.tailwind4 : TAILWIND_MERGE_RANGES.tailwind3
3842
4099
  };
3843
4100
  }
4101
+
4102
+ // src/init/init.ts
3844
4103
  function tailwindWarnings(tailwind, installCommand) {
3845
4104
  const out = [];
3846
4105
  if (tailwind.source === "none" && tailwind.value !== void 0) {
@@ -3904,7 +4163,7 @@ var TAILWIND4_TOKENS_VERSION = TAILWIND4_MIN_AXIS_VERSION;
3904
4163
  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.";
3905
4164
  function readPackageJsonSafe(baseDir) {
3906
4165
  try {
3907
- const text = readFileSync4(path13.join(baseDir, "package.json"), "utf8");
4166
+ const text = readFileSync4(path15.join(baseDir, "package.json"), "utf8");
3908
4167
  const parsed = JSON.parse(text.startsWith(BOM) ? text.slice(1) : text);
3909
4168
  return isPlainObject2(parsed) ? parsed : void 0;
3910
4169
  } catch {
@@ -3969,7 +4228,7 @@ function addCommandFor(installCommand, deps) {
3969
4228
  return `pnpm add ${specs}`;
3970
4229
  }
3971
4230
  function planUtilsDependencies(baseDirInput) {
3972
- const baseDir = path13.resolve(baseDirInput);
4231
+ const baseDir = path15.resolve(baseDirInput);
3973
4232
  const installCommand = detectInstallCommand(baseDir);
3974
4233
  const tailwind0 = detectTailwind(baseDir);
3975
4234
  const ranges0 = selectUtilsDependencies(tailwind0);
@@ -3982,8 +4241,8 @@ function planUtilsDependencies(baseDirInput) {
3982
4241
  installCommand,
3983
4242
  addCommand: addCommandFor(installCommand, ranges0)
3984
4243
  };
3985
- const pkgFile = path13.join(baseDir, "package.json");
3986
- if (!existsSync5(pkgFile)) return plan;
4244
+ const pkgFile = path15.join(baseDir, "package.json");
4245
+ if (!existsSync6(pkgFile)) return plan;
3987
4246
  const unwritable = (reason) => ({ ...plan, action: "unwritable", reason });
3988
4247
  let where;
3989
4248
  try {
@@ -4036,8 +4295,8 @@ var defaultWriteFile = (file, data) => writeFileSync2(file, data);
4036
4295
  function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile) {
4037
4296
  const w = plan.write;
4038
4297
  if (plan.action !== "add" || !w) return false;
4039
- const baseDir = path13.resolve(baseDirInput);
4040
- const current = existsSync5(w.file) ? readFileSync4(w.file, "utf8") : null;
4298
+ const baseDir = path15.resolve(baseDirInput);
4299
+ const current = existsSync6(w.file) ? readFileSync4(w.file, "utf8") : null;
4041
4300
  if (current !== w.before) {
4042
4301
  throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
4043
4302
  }
@@ -4066,25 +4325,25 @@ function reportDependencies(plan, log) {
4066
4325
  const presentText = plan.present.map((p) => `${p.name} (${p.range})`).join(", ");
4067
4326
  const basis = ` tailwind-merge \uBC94\uC704 \uAE30\uC900: ${describeTailwindBasis(plan.tailwind)}`;
4068
4327
  const logBasis = () => {
4069
- log(chalk9.gray(basis));
4070
- for (const w of tailwindWarnings(plan.tailwind, plan.installCommand)) log(chalk9.yellow(` ${w}`));
4328
+ log(chalk10.gray(basis));
4329
+ for (const w of tailwindWarnings(plan.tailwind, plan.installCommand)) log(chalk10.yellow(` ${w}`));
4071
4330
  };
4072
4331
  if (plan.action === "add") {
4073
4332
  const addedText = plan.added.map((n) => `${n}@${plan.ranges[n]}`).join(", ");
4074
- log(chalk9.green(`\u2713 package.json dependencies \uC5D0 \uCD94\uAC00: ${addedText}`));
4075
- if (plan.present.length > 0) log(chalk9.gray(` \uC774\uBBF8 \uC788\uC74C(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
4333
+ log(chalk10.green(`\u2713 package.json dependencies \uC5D0 \uCD94\uAC00: ${addedText}`));
4334
+ if (plan.present.length > 0) log(chalk10.gray(` \uC774\uBBF8 \uC788\uC74C(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
4076
4335
  if (plan.added.includes("tailwind-merge")) logBasis();
4077
- log(chalk9.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk9.cyan(plan.installCommand)}`));
4336
+ log(chalk10.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk10.cyan(plan.installCommand)}`));
4078
4337
  } else if (plan.action === "present") {
4079
- log(chalk9.green(`\u2713 utils.ts \uC758\uC874\uC131\uC774 package.json \uC5D0 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
4080
- log(chalk9.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk9.cyan(plan.installCommand)}`));
4338
+ log(chalk10.green(`\u2713 utils.ts \uC758\uC874\uC131\uC774 package.json \uC5D0 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
4339
+ log(chalk10.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk10.cyan(plan.installCommand)}`));
4081
4340
  } else if (plan.action === "no-package-json") {
4082
- 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."));
4083
- log(chalk9.yellow(` \uC124\uCE58: ${chalk9.cyan(plan.addCommand)}`));
4341
+ 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."));
4342
+ log(chalk10.yellow(` \uC124\uCE58: ${chalk10.cyan(plan.addCommand)}`));
4084
4343
  logBasis();
4085
4344
  } else {
4086
- log(chalk9.yellow(`! package.json \uC744 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(${plan.reason}).`));
4087
- log(chalk9.yellow(` utils.ts \uC758\uC874\uC131 \uC124\uCE58: ${chalk9.cyan(plan.addCommand)}`));
4345
+ log(chalk10.yellow(`! package.json \uC744 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(${plan.reason}).`));
4346
+ log(chalk10.yellow(` utils.ts \uC758\uC874\uC131 \uC124\uCE58: ${chalk10.cyan(plan.addCommand)}`));
4088
4347
  if (plan.addCommand.includes('"tailwind-merge@')) logBasis();
4089
4348
  }
4090
4349
  }
@@ -4107,8 +4366,8 @@ function errCode(e) {
4107
4366
  return e.code ?? e.message;
4108
4367
  }
4109
4368
  function planUtilsWrite(baseDirInput, utilsPath) {
4110
- const baseDir = path13.resolve(baseDirInput);
4111
- const shown = path13.relative(baseDir, utilsPath).split(path13.sep).join("/") || utilsPath;
4369
+ const baseDir = path15.resolve(baseDirInput);
4370
+ const shown = path15.relative(baseDir, utilsPath).split(path15.sep).join("/") || utilsPath;
4112
4371
  let st;
4113
4372
  try {
4114
4373
  st = lstatSync2(utilsPath);
@@ -4169,7 +4428,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
4169
4428
  return { action: "overwrite" };
4170
4429
  }
4171
4430
  async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
4172
- const baseDir = path13.resolve(baseDirInput);
4431
+ const baseDir = path15.resolve(baseDirInput);
4173
4432
  const current = await existingConfig(baseDir);
4174
4433
  const existingRegistry = nonEmptyString(current?.registry);
4175
4434
  const migratedRegistry = existingRegistry !== void 0 && isLegacyDefaultRegistryUrl(existingRegistry);
@@ -4186,13 +4445,13 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
4186
4445
  },
4187
4446
  registry
4188
4447
  );
4189
- const configPath = path13.join(baseDir, "axis.config.json");
4448
+ const configPath = path15.join(baseDir, "axis.config.json");
4190
4449
  const nextText = `${JSON.stringify(axisConfig, null, 2)}
4191
4450
  `;
4192
4451
  const rejects = [];
4193
4452
  let previousText = null;
4194
4453
  try {
4195
- previousText = await fs11.readFile(configPath, "utf8");
4454
+ previousText = await fs12.readFile(configPath, "utf8");
4196
4455
  } catch (e) {
4197
4456
  if (e.code !== "ENOENT") {
4198
4457
  rejects.push(`\uAE30\uC874 axis.config.json \uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})`);
@@ -4205,79 +4464,79 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
4205
4464
  } catch {
4206
4465
  }
4207
4466
  }
4208
- const utilsPath = path13.resolve(baseDir, answers.componentsDir, "utils.ts");
4467
+ const utilsPath = path15.resolve(baseDir, answers.componentsDir, "utils.ts");
4209
4468
  const utilsPlan = planUtilsWrite(baseDir, utilsPath);
4210
4469
  if (utilsPlan.action === "reject") rejects.push(utilsPlan.reason);
4211
4470
  if (rejects.length > 0) {
4212
- log(chalk9.red("\u2717 \uC4F8 \uC218 \uC5C6\uB294 \uD30C\uC77C\uC774 \uC788\uC5B4 \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(axis.config.json \xB7 utils.ts \xB7 package.json \uADF8\uB300\uB85C)."));
4213
- for (const r of rejects) log(chalk9.red(` - ${r}`));
4471
+ log(chalk10.red("\u2717 \uC4F8 \uC218 \uC5C6\uB294 \uD30C\uC77C\uC774 \uC788\uC5B4 \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(axis.config.json \xB7 utils.ts \xB7 package.json \uADF8\uB300\uB85C)."));
4472
+ for (const r of rejects) log(chalk10.red(` - ${r}`));
4214
4473
  process.exitCode = 1;
4215
4474
  return;
4216
4475
  }
4217
4476
  let configState;
4218
4477
  if (previousText === null) {
4219
4478
  try {
4220
- await fs11.writeFile(configPath, nextText, { flag: "wx" });
4479
+ await fs12.writeFile(configPath, nextText, { flag: "wx" });
4221
4480
  } catch (err) {
4222
4481
  const reason = err.code === "EEXIST" ? "\uAC80\uC0AC \uB4A4 \uC4F0\uAE30 \uC9C1\uC804\uC5D0 \uAC19\uC740 \uC774\uB984\uC758 \uD30C\uC77C\uC774 \uC0DD\uACBC\uC2B5\uB2C8\uB2E4(\uB3D9\uC2DC \uACBD\uD569)" : err.message;
4223
- log(chalk9.red(`\u2717 axis.config.json \uC744 \uB9CC\uB4E4\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${reason}. \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
4482
+ log(chalk10.red(`\u2717 axis.config.json \uC744 \uB9CC\uB4E4\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${reason}. \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
4224
4483
  process.exitCode = 1;
4225
4484
  return;
4226
4485
  }
4227
4486
  configState = "created";
4228
- log(chalk9.green("\u2713 axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
4487
+ log(chalk10.green("\u2713 axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
4229
4488
  } else if (previousText === nextText) {
4230
4489
  configState = "kept";
4231
- log(chalk9.green("\u2713 axis.config.json \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9)"));
4490
+ log(chalk10.green("\u2713 axis.config.json \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9)"));
4232
4491
  } else {
4233
4492
  try {
4234
4493
  await overwriteFollowingLinks(configPath, nextText);
4235
4494
  } catch (err) {
4236
4495
  const reason = err.code === HARDLINK_ERROR_CODE ? `\uAC80\uC0AC \uB4A4 \uC4F0\uAE30 \uC9C1\uC804\uC5D0 \uB2E4\uB978 \uACBD\uB85C\uC640 \uD558\uB4DC\uB9C1\uD06C\uB85C \uC774\uC5B4\uC84C\uC2B5\uB2C8\uB2E4(\uB3D9\uC2DC \uACBD\uD569, D19)` : err.message;
4237
- log(chalk9.red(`\u2717 axis.config.json \uC744 \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${reason}. \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
4496
+ log(chalk10.red(`\u2717 axis.config.json \uC744 \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${reason}. \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
4238
4497
  process.exitCode = 1;
4239
4498
  return;
4240
4499
  }
4241
4500
  configState = "updated";
4242
4501
  const registryNote = migratedRegistry ? "registry \uB97C \uC0C8 \uAE30\uBCF8 \uC8FC\uC18C\uB85C \uAC31\uC2E0" : existingRegistry !== void 0 ? "registry \uB294 \uAE30\uC874 \uAC12 \uC720\uC9C0" : "registry \uB294 \uAE30\uBCF8\uAC12";
4243
4502
  const agenticNote = existingAgenticDir !== void 0 ? ", agenticDir \uB294 \uAE30\uC874 \uAC12 \uC720\uC9C0" : "";
4244
- log(chalk9.green(`\u2713 axis.config.json \uAC31\uC2E0(\uAE30\uC874 \uD30C\uC77C\uC744 init \uAC12\uC73C\uB85C \uB2E4\uC2DC \uC500, ${registryNote}${agenticNote})`));
4503
+ log(chalk10.green(`\u2713 axis.config.json \uAC31\uC2E0(\uAE30\uC874 \uD30C\uC77C\uC744 init \uAC12\uC73C\uB85C \uB2E4\uC2DC \uC500, ${registryNote}${agenticNote})`));
4245
4504
  if (migratedRegistry && existingRegistry !== void 0) {
4246
4505
  log(
4247
- chalk9.yellow(
4506
+ chalk10.yellow(
4248
4507
  ` registry \uB97C \uC0C8 \uAE30\uBCF8 \uC8FC\uC18C(${redactRegistryUrl(registry)})\uB85C \uAC31\uC2E0\uD588\uC2B5\uB2C8\uB2E4(\uC885\uC804 axis.minu.best: ${redactRegistryUrl(existingRegistry)}).`
4249
4508
  )
4250
4509
  );
4251
4510
  }
4252
4511
  const dropped = current ? Object.keys(current).filter((k) => !(k in axisConfig) && current[k] !== void 0) : [];
4253
4512
  if (dropped.length > 0) {
4254
- log(chalk9.yellow(` \uAE30\uC874 \uC124\uC815\uC5D0\uC11C \uBE60\uC9C4 \uD0A4: ${dropped.join(", ")} (\uD544\uC694\uD558\uBA74 axis.config.json \uC5D0 \uB2E4\uC2DC \uC801\uC5B4 \uC8FC\uC138\uC694)`));
4513
+ log(chalk10.yellow(` \uAE30\uC874 \uC124\uC815\uC5D0\uC11C \uBE60\uC9C4 \uD0A4: ${dropped.join(", ")} (\uD544\uC694\uD558\uBA74 axis.config.json \uC5D0 \uB2E4\uC2DC \uC801\uC5B4 \uC8FC\uC138\uC694)`));
4255
4514
  }
4256
4515
  }
4257
4516
  let utilsStateNote = "utils.ts \uB294 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9).";
4258
4517
  if (utilsPlan.action === "keep") {
4259
- if (utilsPlan.link === void 0) log(chalk9.green("\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9)"));
4260
- else if (utilsPlan.link.outside === null) log(chalk9.green("\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9, \uB9C1\uD06C)"));
4261
- else log(chalk9.green(`\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9, \uB9C1\uD06C \uB300\uC0C1\uC774 \uD504\uB85C\uC81D\uD2B8 \uBC16: ${utilsPlan.link.outside})`));
4518
+ if (utilsPlan.link === void 0) log(chalk10.green("\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9)"));
4519
+ else if (utilsPlan.link.outside === null) log(chalk10.green("\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9, \uB9C1\uD06C)"));
4520
+ else log(chalk10.green(`\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9, \uB9C1\uD06C \uB300\uC0C1\uC774 \uD504\uB85C\uC81D\uD2B8 \uBC16: ${utilsPlan.link.outside})`));
4262
4521
  } else {
4263
4522
  let actual;
4264
4523
  try {
4265
- await fs11.ensureDir(path13.dirname(utilsPath));
4524
+ await fs12.ensureDir(path15.dirname(utilsPath));
4266
4525
  actual = await writeNoFollow(utilsPath, UTILS_TS_CONTENT, utilsPlan.action === "create" ? "new" : "overwrite");
4267
4526
  } catch (err) {
4268
4527
  const code = err.code;
4269
4528
  const reason = code === HARDLINK_ERROR_CODE ? "\uAC80\uC0AC \uB4A4 \uC4F0\uAE30 \uC9C1\uC804\uC5D0 \uB2E4\uB978 \uACBD\uB85C\uC640 \uD558\uB4DC\uB9C1\uD06C\uB85C \uC774\uC5B4\uC84C\uC2B5\uB2C8\uB2E4(\uB3D9\uC2DC \uACBD\uD569, D19)" : code === "ELOOP" || code === "EEXIST" ? "\uAC80\uC0AC \uB4A4 \uC4F0\uAE30 \uC9C1\uC804\uC5D0 \uAC19\uC740 \uC774\uB984\uC758 \uD30C\uC77C \xB7 \uB9C1\uD06C\uAC00 \uC0DD\uACBC\uC2B5\uB2C8\uB2E4(\uB3D9\uC2DC \uACBD\uD569)" : err.message;
4270
4529
  log(
4271
- chalk9.red(
4530
+ chalk10.red(
4272
4531
  utilsPlan.action === "create" ? `\u2717 utils.ts \uB97C \uB9CC\uB4E4\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${reason}.` : `\u2717 utils.ts \uB97C \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${reason}. \uADF8 \uD30C\uC77C\uC740 \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`
4273
4532
  )
4274
4533
  );
4275
- log(chalk9.yellow(` ${configStateNote(configState)}`));
4534
+ log(chalk10.yellow(` ${configStateNote(configState)}`));
4276
4535
  process.exitCode = 1;
4277
4536
  return;
4278
4537
  }
4279
4538
  log(
4280
- chalk9.green(
4539
+ chalk10.green(
4281
4540
  actual === "new" ? "\u2713 utils.ts \uC0DD\uC131 \uC644\uB8CC" : "\u2713 utils.ts \uB36E\uC5B4\uC500(\uAE30\uC874 \uB0B4\uC6A9\uACFC \uB2EC\uB77C init \uC758 utils \uB85C \uB2E4\uC2DC \uC500)"
4282
4541
  )
4283
4542
  );
@@ -4286,9 +4545,9 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
4286
4545
  try {
4287
4546
  applyUtilsDependencies(baseDir, plan);
4288
4547
  } catch (err) {
4289
- log(chalk9.red(`\u2717 package.json \uC744 \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${err.message}`));
4290
- log(chalk9.yellow(` ${configStateNote(configState)} ${utilsStateNote}`));
4291
- log(chalk9.yellow(` utils.ts \uC758\uC874\uC131 \uC124\uCE58: ${chalk9.cyan(plan.addCommand)}`));
4548
+ log(chalk10.red(`\u2717 package.json \uC744 \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${err.message}`));
4549
+ log(chalk10.yellow(` ${configStateNote(configState)} ${utilsStateNote}`));
4550
+ log(chalk10.yellow(` utils.ts \uC758\uC874\uC131 \uC124\uCE58: ${chalk10.cyan(plan.addCommand)}`));
4292
4551
  process.exitCode = 1;
4293
4552
  return;
4294
4553
  }
@@ -4300,19 +4559,19 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
4300
4559
  answers.globalCss,
4301
4560
  baseDir
4302
4561
  );
4303
- log(chalk9.blue(`
4562
+ log(chalk10.blue(`
4304
4563
  ${head}`));
4305
- for (const line of rest) log(line.startsWith(" !") ? chalk9.yellow(line) : chalk9.cyan(line));
4564
+ for (const line of rest) log(line.startsWith(" !") ? chalk10.yellow(line) : chalk10.cyan(line));
4306
4565
  }
4307
- 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:"));
4308
- log(chalk9.cyan(` ${INIT_NEXT_STEP_COMMAND}
4566
+ log(chalk10.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:"));
4567
+ log(chalk10.cyan(` ${INIT_NEXT_STEP_COMMAND}
4309
4568
  `));
4310
4569
  }
4311
4570
 
4312
4571
  // src/init/index.ts
4313
4572
  function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL) {
4314
4573
  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) => {
4315
- console.log(chalk10.blue("\n\u{1F3A8} AXIS Design System \uCD08\uAE30\uD654\n"));
4574
+ console.log(chalk11.blue("\n\u{1F3A8} AXIS Design System \uCD08\uAE30\uD654\n"));
4316
4575
  const tailwind4 = isTailwind4(planUtilsDependencies(process.cwd()).tailwind);
4317
4576
  const config = options.yes ? { ...INIT_DEFAULTS } : await prompts2([
4318
4577
  {
@@ -4339,27 +4598,27 @@ function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL) {
4339
4598
  }
4340
4599
 
4341
4600
  // src/add/index.ts
4342
- import chalk11 from "chalk";
4601
+ import chalk12 from "chalk";
4343
4602
  import prompts3 from "prompts";
4344
4603
 
4345
- // src/add/add.ts
4346
- import { existsSync as existsSync7, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
4347
- import path15 from "path";
4348
- import fs12 from "fs-extra";
4604
+ // ../axis-registry-core/src/add/add.ts
4605
+ import { existsSync as existsSync8, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
4606
+ import path17 from "path";
4607
+ import fs13 from "fs-extra";
4349
4608
 
4350
- // src/registry/bundled.ts
4351
- import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
4352
- import path14 from "path";
4609
+ // ../axis-registry-core/src/registry/bundled.ts
4610
+ import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
4611
+ import path16 from "path";
4353
4612
  import { fileURLToPath } from "url";
4354
4613
  function findBundledRegistryDir(moduleUrl = import.meta.url) {
4355
- const here = path14.dirname(fileURLToPath(moduleUrl));
4356
- for (const dir of [path14.join(here, "registry"), path14.join(here, "..", "registry")]) {
4357
- if (existsSync6(path14.join(dir, "index.json"))) return dir;
4614
+ const here = path16.dirname(fileURLToPath(moduleUrl));
4615
+ for (const dir of [path16.join(here, "registry"), path16.join(here, "..", "registry")]) {
4616
+ if (existsSync7(path16.join(dir, "index.json"))) return dir;
4358
4617
  }
4359
4618
  return null;
4360
4619
  }
4361
4620
  function readBundledJson(dir, fileName) {
4362
- const file = path14.join(dir, fileName);
4621
+ const file = path16.join(dir, fileName);
4363
4622
  let text;
4364
4623
  try {
4365
4624
  text = readFileSync5(file, "utf8");
@@ -4369,7 +4628,238 @@ function readBundledJson(dir, fileName) {
4369
4628
  return parseJsonText(text, `\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC ${fileName}`);
4370
4629
  }
4371
4630
 
4372
- // src/registry/index.ts
4631
+ // ../axis-registry-core/src/registry/host-guard.ts
4632
+ import { lookup as dnsLookup } from "dns/promises";
4633
+ import { isIP } from "net";
4634
+ var defaultLookupAll = (hostname) => dnsLookup(hostname, { all: true, verbatim: true });
4635
+ function ipv4Octets(ip) {
4636
+ const parts = ip.split(".");
4637
+ if (parts.length !== 4) return null;
4638
+ const nums = parts.map((p) => /^\d{1,3}$/.test(p) ? Number(p) : NaN);
4639
+ return nums.every((n) => n >= 0 && n <= 255) ? nums : null;
4640
+ }
4641
+ var BLOCKED_V4 = [
4642
+ ["0.0.0.0", 8, "\uBBF8\uC9C0\uC815 \uC8FC\uC18C(0.0.0.0/8)"],
4643
+ ["10.0.0.0", 8, "\uC0AC\uC124 \uC8FC\uC18C(10.0.0.0/8)"],
4644
+ ["100.64.0.0", 10, "\uACF5\uC720 \uC8FC\uC18C(100.64.0.0/10)"],
4645
+ ["127.0.0.0", 8, "\uB8E8\uD504\uBC31 \uC8FC\uC18C(127.0.0.0/8)"],
4646
+ ["169.254.0.0", 16, "\uB9C1\uD06C\uB85C\uCEEC \uC8FC\uC18C(169.254.0.0/16)"],
4647
+ ["172.16.0.0", 12, "\uC0AC\uC124 \uC8FC\uC18C(172.16.0.0/12)"],
4648
+ ["192.0.0.0", 24, "IETF \uD504\uB85C\uD1A0\uCF5C \uD560\uB2F9 \uC8FC\uC18C(192.0.0.0/24)"],
4649
+ ["192.0.2.0", 24, "\uBB38\uC11C\uC6A9 \uC8FC\uC18C(192.0.2.0/24)"],
4650
+ ["192.88.99.0", 24, "6to4 \uB9B4\uB808\uC774 \uC8FC\uC18C(192.88.99.0/24)"],
4651
+ ["192.168.0.0", 16, "\uC0AC\uC124 \uC8FC\uC18C(192.168.0.0/16)"],
4652
+ ["198.18.0.0", 15, "\uBCA4\uCE58\uB9C8\uD06C \uC8FC\uC18C(198.18.0.0/15)"],
4653
+ ["198.51.100.0", 24, "\uBB38\uC11C\uC6A9 \uC8FC\uC18C(198.51.100.0/24)"],
4654
+ ["203.0.113.0", 24, "\uBB38\uC11C\uC6A9 \uC8FC\uC18C(203.0.113.0/24)"],
4655
+ ["224.0.0.0", 4, "\uBA40\uD2F0\uCE90\uC2A4\uD2B8 \uC8FC\uC18C(224.0.0.0/4)"],
4656
+ ["240.0.0.0", 4, "\uC608\uC57D \uC8FC\uC18C(240.0.0.0/4)"]
4657
+ ];
4658
+ function ipv4ToInt(o) {
4659
+ return (o[0] << 24 | o[1] << 16 | o[2] << 8 | o[3]) >>> 0;
4660
+ }
4661
+ function blockedIpv4Reason(ip) {
4662
+ const o = ipv4Octets(ip);
4663
+ if (!o) return "IPv4 \uC8FC\uC18C \uD615\uC2DD\uC774 \uC544\uB2D8";
4664
+ const n = ipv4ToInt(o);
4665
+ for (const [base, len, name] of BLOCKED_V4) {
4666
+ const mask = len === 0 ? 0 : 4294967295 << 32 - len >>> 0;
4667
+ if ((n & mask) >>> 0 === (ipv4ToInt(ipv4Octets(base)) & mask) >>> 0) return name;
4668
+ }
4669
+ return null;
4670
+ }
4671
+ function parseIpv6(ip) {
4672
+ let s = ip.toLowerCase();
4673
+ const zone = s.indexOf("%");
4674
+ if (zone >= 0) s = s.slice(0, zone);
4675
+ const lastColon = s.lastIndexOf(":");
4676
+ if (lastColon >= 0 && s.slice(lastColon + 1).includes(".")) {
4677
+ const o = ipv4Octets(s.slice(lastColon + 1));
4678
+ if (!o) return null;
4679
+ s = `${s.slice(0, lastColon + 1)}${(o[0] << 8 | o[1]).toString(16)}:${(o[2] << 8 | o[3]).toString(16)}`;
4680
+ }
4681
+ const halves = s.split("::");
4682
+ if (halves.length > 2) return null;
4683
+ const toGroups = (part) => part === "" ? [] : part.split(":");
4684
+ const parseGroup = (g) => /^[0-9a-f]{1,4}$/.test(g) ? parseInt(g, 16) : NaN;
4685
+ let groups = toGroups(halves[0]).map(parseGroup);
4686
+ const restNums = halves.length === 2 ? toGroups(halves[1]).map(parseGroup) : [];
4687
+ const total = groups.length + restNums.length;
4688
+ if (halves.length === 2) {
4689
+ if (total > 7) return null;
4690
+ groups = [...groups, ...new Array(8 - total).fill(0), ...restNums];
4691
+ } else if (total !== 8) {
4692
+ return null;
4693
+ }
4694
+ return groups.every((g) => Number.isInteger(g) && g >= 0 && g <= 65535) ? groups : null;
4695
+ }
4696
+ function groupsToIpv4(hi, lo) {
4697
+ return `${hi >> 8}.${hi & 255}.${lo >> 8}.${lo & 255}`;
4698
+ }
4699
+ function blockedIpv6Reason(ip) {
4700
+ const g = parseIpv6(ip);
4701
+ if (!g) return "IPv6 \uC8FC\uC18C \uD615\uC2DD\uC774 \uC544\uB2D8";
4702
+ const zeros = (from, to) => g.slice(from, to).every((x) => x === 0);
4703
+ const embeddedTail = () => groupsToIpv4(g[6], g[7]);
4704
+ const viaEmbedded = (v4, what) => {
4705
+ const r = blockedIpv4Reason(v4);
4706
+ return r ? `${what}\uC774 \uD488\uC740 ${v4}: ${r}` : null;
4707
+ };
4708
+ if (zeros(0, 8)) return "\uBBF8\uC9C0\uC815 \uC8FC\uC18C(::)";
4709
+ if (zeros(0, 7) && g[7] === 1) return "\uB8E8\uD504\uBC31 \uC8FC\uC18C(::1)";
4710
+ if (zeros(0, 5) && g[5] === 65535) return viaEmbedded(embeddedTail(), "IPv4 \uB9E4\uD551 \uC8FC\uC18C(::ffff:0:0/96)");
4711
+ if (zeros(0, 6)) return viaEmbedded(embeddedTail(), "IPv4 \uD638\uD658 \uC8FC\uC18C(::/96)");
4712
+ if (g[0] === 100 && g[1] === 65435 && zeros(2, 6)) return viaEmbedded(embeddedTail(), "NAT64 \uC8FC\uC18C(64:ff9b::/96)");
4713
+ if (g[0] === 100 && g[1] === 65435 && g[2] === 1) return "\uB85C\uCEEC NAT64 \uC8FC\uC18C(64:ff9b:1::/48)";
4714
+ if (g[0] === 256 && zeros(1, 4)) return "\uD3D0\uAE30 \uC804\uC6A9 \uC8FC\uC18C(100::/64)";
4715
+ if (g[0] === 256 && zeros(1, 3) && g[3] === 1) return "\uB354\uBBF8 \uC811\uB450 \uC8FC\uC18C(100:0:0:1::/64)";
4716
+ if (g[0] === 8193 && g[1] === 0) {
4717
+ const server = groupsToIpv4(g[2], g[3]);
4718
+ const client = groupsToIpv4(~g[6] & 65535, ~g[7] & 65535);
4719
+ return viaEmbedded(server, "Teredo \uC8FC\uC18C(2001::/32) \uC11C\uBC84") ?? viaEmbedded(client, "Teredo \uC8FC\uC18C(2001::/32) \uD074\uB77C\uC774\uC5B8\uD2B8");
4720
+ }
4721
+ if (g[0] === 8193 && g[1] < 512) return "IETF \uD504\uB85C\uD1A0\uCF5C \uD560\uB2F9 \uC8FC\uC18C(2001::/23)";
4722
+ if (g[0] === 8193 && g[1] === 3512) return "\uBB38\uC11C\uC6A9 \uC8FC\uC18C(2001:db8::/32)";
4723
+ if ((g[0] & 65520) === 16368) return "\uBB38\uC11C\uC6A9 \uC8FC\uC18C(3fff::/20)";
4724
+ if (g[0] === 8194) return viaEmbedded(groupsToIpv4(g[1], g[2]), "6to4 \uC8FC\uC18C(2002::/16)");
4725
+ if (g[0] === 24320) return "SRv6 SID \uC8FC\uC18C(5f00::/16)";
4726
+ if ((g[0] & 65024) === 64512) return "\uC0AC\uC124 \uC8FC\uC18C(fc00::/7)";
4727
+ if ((g[0] & 65472) === 65152) return "\uB9C1\uD06C\uB85C\uCEEC \uC8FC\uC18C(fe80::/10)";
4728
+ if ((g[0] & 65472) === 65216) return "\uC0AC\uC774\uD2B8\uB85C\uCEEC \uC8FC\uC18C(fec0::/10)";
4729
+ if ((g[0] & 65280) === 65280) return "\uBA40\uD2F0\uCE90\uC2A4\uD2B8 \uC8FC\uC18C(ff00::/8)";
4730
+ return null;
4731
+ }
4732
+ function blockedAddressReason(address) {
4733
+ const v = isIP(address.split("%")[0]);
4734
+ if (v === 4) return blockedIpv4Reason(address);
4735
+ if (v === 6) return blockedIpv6Reason(address);
4736
+ return "IP \uC8FC\uC18C \uD615\uC2DD\uC774 \uC544\uB2D8";
4737
+ }
4738
+ async function publicRegistryUrlProblem(raw, lookupAll = defaultLookupAll) {
4739
+ let parsed;
4740
+ try {
4741
+ parsed = new URL(raw.trim());
4742
+ } catch {
4743
+ return "URL \uD615\uC2DD\uC774 \uC544\uB2D8";
4744
+ }
4745
+ if (parsed.protocol !== "https:") return `https \uAC00 \uC544\uB2D8(${parsed.protocol.replace(/:$/, "")})`;
4746
+ let host = parsed.hostname.toLowerCase();
4747
+ if (host.startsWith("[") && host.endsWith("]")) host = host.slice(1, -1);
4748
+ host = host.replace(/\.+$/, "");
4749
+ if (host === "") return "\uD638\uC2A4\uD2B8\uAC00 \uC5C6\uC74C";
4750
+ if (isIP(host)) {
4751
+ const r = blockedAddressReason(host);
4752
+ return r ? `${r}\uB97C \uAC00\uB9AC\uD0B4` : null;
4753
+ }
4754
+ if (host === "localhost" || host.endsWith(".localhost")) return "localhost \uC774\uB984";
4755
+ if (host.endsWith(".local")) return "\uB85C\uCEEC \uB124\uD2B8\uC6CC\uD06C \uC774\uB984(.local)";
4756
+ let addresses;
4757
+ try {
4758
+ addresses = await lookupAll(host);
4759
+ } catch (error) {
4760
+ const code = error.code;
4761
+ return `\uD638\uC2A4\uD2B8 \uC8FC\uC18C\uB97C \uD655\uC778\uD558\uC9C0 \uBABB\uD568(${code ?? error.message})`;
4762
+ }
4763
+ if (addresses.length === 0) return "\uD638\uC2A4\uD2B8 \uC8FC\uC18C\uB97C \uD655\uC778\uD558\uC9C0 \uBABB\uD568(\uACB0\uACFC \uC5C6\uC74C)";
4764
+ for (const { address } of addresses) {
4765
+ const r = blockedAddressReason(address);
4766
+ if (r) return `${host} \uAC00 ${address}(${r})\uB85C \uD480\uB9BC`;
4767
+ }
4768
+ return null;
4769
+ }
4770
+
4771
+ // ../axis-registry-core/src/registry/pinned-fetch.ts
4772
+ import { request as httpsRequest } from "https";
4773
+ var PINNED_FETCH_MAX_BYTES = 4 * 1024 * 1024;
4774
+ var BLOCKED_CONNECT_CODE = "EAXISBLOCKEDADDR";
4775
+ function guardedLookup(lookupAll, judge) {
4776
+ return (hostname, options, callback) => {
4777
+ lookupAll(hostname).then(
4778
+ (addresses) => {
4779
+ if (addresses.length === 0) {
4780
+ callback(Object.assign(new Error(`${hostname} \uC758 \uC8FC\uC18C\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4`), { code: "ENOTFOUND" }), "", 0);
4781
+ return;
4782
+ }
4783
+ for (const { address } of addresses) {
4784
+ const reason = judge(address);
4785
+ if (reason) {
4786
+ const err = Object.assign(
4787
+ new Error(`\uC5F0\uACB0 \uB2E8\uACC4\uC5D0\uC11C ${hostname} \uAC00 ${address}(${reason})\uB85C \uD480\uB824 \uC5F0\uACB0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`),
4788
+ { code: BLOCKED_CONNECT_CODE }
4789
+ );
4790
+ callback(err, "", 0);
4791
+ return;
4792
+ }
4793
+ }
4794
+ const family = options?.family === 4 || options?.family === 6 ? options.family : 0;
4795
+ const usable = family ? addresses.filter((a) => a.family === family) : addresses;
4796
+ if (usable.length === 0) {
4797
+ callback(Object.assign(new Error(`${hostname} \uC5D0 IPv${family} \uC8FC\uC18C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4`), { code: "ENOTFOUND" }), "", 0);
4798
+ return;
4799
+ }
4800
+ if (options?.all) callback(null, usable.map((a) => ({ address: a.address, family: a.family })));
4801
+ else callback(null, usable[0].address, usable[0].family);
4802
+ },
4803
+ (error) => callback(error, "", 0)
4804
+ );
4805
+ };
4806
+ }
4807
+ function createPinnedFetch(options = {}) {
4808
+ const lookupAll = options.lookupAll ?? defaultLookupAll;
4809
+ const judge = options.judge ?? blockedAddressReason;
4810
+ const send = options.request ?? httpsRequest;
4811
+ const maxBytes = options.maxBytes ?? PINNED_FETCH_MAX_BYTES;
4812
+ return (input, init) => new Promise((resolve3, reject) => {
4813
+ let url;
4814
+ try {
4815
+ url = new URL(input);
4816
+ } catch (error) {
4817
+ reject(error);
4818
+ return;
4819
+ }
4820
+ const host = url.hostname.startsWith("[") ? url.hostname.slice(1, -1) : url.hostname;
4821
+ const req = send(
4822
+ {
4823
+ hostname: host,
4824
+ port: options.port ?? (url.port ? Number(url.port) : void 0),
4825
+ path: `${url.pathname}${url.search}`,
4826
+ method: "GET",
4827
+ headers: init?.headers ?? {},
4828
+ servername: host,
4829
+ lookup: guardedLookup(lookupAll, judge),
4830
+ ...init?.signal ? { signal: init.signal } : {}
4831
+ },
4832
+ (res) => {
4833
+ const chunks = [];
4834
+ let size = 0;
4835
+ let failed = false;
4836
+ res.on("data", (chunk) => {
4837
+ size += chunk.length;
4838
+ if (size > maxBytes && !failed) {
4839
+ failed = true;
4840
+ res.destroy();
4841
+ reject(new Error(`\uC751\uB2F5\uC774 ${maxBytes} \uBC14\uC774\uD2B8\uB97C \uB118\uC5B4 \uC77D\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`));
4842
+ return;
4843
+ }
4844
+ chunks.push(chunk);
4845
+ });
4846
+ res.on("error", (error) => {
4847
+ if (!failed) reject(error);
4848
+ });
4849
+ res.on("end", () => {
4850
+ if (failed) return;
4851
+ const body = Buffer.concat(chunks).toString("utf8");
4852
+ const status = res.statusCode ?? 0;
4853
+ resolve3({ ok: status >= 200 && status < 300, status, text: async () => body });
4854
+ });
4855
+ }
4856
+ );
4857
+ req.on("error", reject);
4858
+ req.end();
4859
+ });
4860
+ }
4861
+
4862
+ // ../axis-registry-core/src/registry/index.ts
4373
4863
  var RegistryError = class extends Error {
4374
4864
  constructor(code, message) {
4375
4865
  super(message);
@@ -4377,15 +4867,16 @@ var RegistryError = class extends Error {
4377
4867
  this.name = "RegistryError";
4378
4868
  }
4379
4869
  };
4380
- function bundledFallbackMessage(version, reason, kind = "access") {
4870
+ var DEFAULT_BUNDLED_LABEL = "CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC";
4871
+ function bundledFallbackMessage(version, reason, kind = "access", label = DEFAULT_BUNDLED_LABEL) {
4381
4872
  const lead = kind === "invalid" ? "\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC \uC751\uB2F5\uC774 \uD615\uC2DD \uAC80\uC99D\uC744 \uD1B5\uACFC\uD558\uC9C0 \uBABB\uD574" : "\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC811\uADFC\uD558\uC9C0 \uBABB\uD574";
4382
- return `${lead} CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${version})\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4. (\uC6D0\uC778: ${reason})`;
4873
+ return `${lead} ${label}(version ${version})\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4. (\uC6D0\uC778: ${reason})`;
4383
4874
  }
4384
4875
  function fallbackKindOf(error) {
4385
4876
  return error instanceof RegistryAccessError ? "access" : "invalid";
4386
4877
  }
4387
- function versionMismatchMessage(remoteVersion, bundledVersion) {
4388
- return `\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${remoteVersion})\uC640 CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${bundledVersion})\uC758 version \uC774 \uB2E4\uB985\uB2C8\uB2E4. \uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC6B0\uC120 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.`;
4878
+ function versionMismatchMessage(remoteVersion, bundledVersion, label = DEFAULT_BUNDLED_LABEL) {
4879
+ return `\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${remoteVersion})\uC640 ${label}(version ${bundledVersion})\uC758 version \uC774 \uB2E4\uB985\uB2C8\uB2E4. \uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC6B0\uC120 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.`;
4389
4880
  }
4390
4881
  function messageOf(error) {
4391
4882
  return error instanceof Error ? error.message : String(error);
@@ -4397,6 +4888,10 @@ var RegistryClient = class {
4397
4888
  timeoutMs;
4398
4889
  fetchImpl;
4399
4890
  notify;
4891
+ bundledLabel;
4892
+ rawUrl;
4893
+ urlSource;
4894
+ rejectRedirects;
4400
4895
  mode = null;
4401
4896
  indexPromise = null;
4402
4897
  bundledIndex = null;
@@ -4419,6 +4914,15 @@ var RegistryClient = class {
4419
4914
  this.timeoutMs = options.timeoutMs ?? DEFAULT_REGISTRY_TIMEOUT_MS;
4420
4915
  this.fetchImpl = options.fetchImpl;
4421
4916
  this.notify = options.notify ?? ((message) => console.warn(message));
4917
+ this.bundledLabel = options.bundledLabel ?? DEFAULT_BUNDLED_LABEL;
4918
+ this.rawUrl = options.url;
4919
+ this.urlSource = options.urlSource;
4920
+ this.rejectRedirects = options.rejectRedirects === true;
4921
+ }
4922
+ /** 원격 주소(가림 적용)와 그 출처. 표시용입니다(WI-0055 D13) */
4923
+ get remote() {
4924
+ const url = this.baseUrl ?? this.rawUrl;
4925
+ return { url: url === null ? null : redactRegistryUrl(url), source: this.urlSource };
4422
4926
  }
4423
4927
  /** 지금 쓰는 출처. index 를 읽기 전에는 null 입니다 */
4424
4928
  get origin() {
@@ -4462,7 +4966,11 @@ var RegistryClient = class {
4462
4966
  return bases;
4463
4967
  }
4464
4968
  fetchOptions() {
4465
- return { timeoutMs: this.timeoutMs, ...this.fetchImpl ? { fetchImpl: this.fetchImpl } : {} };
4969
+ return {
4970
+ timeoutMs: this.timeoutMs,
4971
+ ...this.fetchImpl ? { fetchImpl: this.fetchImpl } : {},
4972
+ ...this.rejectRedirects ? { rejectRedirects: true } : {}
4973
+ };
4466
4974
  }
4467
4975
  async loadIndex() {
4468
4976
  let remoteError;
@@ -4486,7 +4994,7 @@ var RegistryClient = class {
4486
4994
  /** 동봉본 index 를 읽습니다(성공하면 한 번만). 실패하면 이유를 돌려줍니다 */
4487
4995
  loadBundledIndex() {
4488
4996
  if (this.bundledIndex) return { index: this.bundledIndex };
4489
- if (!this.bundledDir) return { error: "CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4" };
4997
+ if (!this.bundledDir) return { error: `${this.bundledLabel}\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4` };
4490
4998
  try {
4491
4999
  this.bundledIndex = validateRegistryIndex(readBundledJson(this.bundledDir, "index.json"), "\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC index.json");
4492
5000
  return { index: this.bundledIndex };
@@ -4497,7 +5005,7 @@ var RegistryClient = class {
4497
5005
  warnVersionMismatch(remoteVersion) {
4498
5006
  const bundled = this.loadBundledIndex();
4499
5007
  if ("index" in bundled && bundled.index.version !== remoteVersion) {
4500
- this.notify(versionMismatchMessage(remoteVersion, bundled.index.version));
5008
+ this.notify(versionMismatchMessage(remoteVersion, bundled.index.version, this.bundledLabel));
4501
5009
  }
4502
5010
  }
4503
5011
  async switchToBundled(reason, kind = "access") {
@@ -4512,7 +5020,7 @@ var RegistryClient = class {
4512
5020
  this.indexPromise = Promise.resolve(bundled.index);
4513
5021
  if (!this.fallbackAnnounced) {
4514
5022
  this.fallbackAnnounced = true;
4515
- this.notify(bundledFallbackMessage(bundled.index.version, reason, kind));
5023
+ this.notify(bundledFallbackMessage(bundled.index.version, reason, kind, this.bundledLabel));
4516
5024
  }
4517
5025
  return bundled.index;
4518
5026
  }
@@ -4522,7 +5030,7 @@ var RegistryClient = class {
4522
5030
  if (!index || !entry || !this.bundledDir) {
4523
5031
  throw new RegistryError(
4524
5032
  "not-found",
4525
- `'${name}' \uD56D\uBAA9\uC774 CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${index?.version ?? "\uC54C \uC218 \uC5C6\uC74C"})\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`
5033
+ `'${name}' \uD56D\uBAA9\uC774 ${this.bundledLabel}(version ${index?.version ?? "\uC54C \uC218 \uC5C6\uC74C"})\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`
4526
5034
  );
4527
5035
  }
4528
5036
  try {
@@ -4530,18 +5038,23 @@ var RegistryClient = class {
4530
5038
  checkItemSha256(item, entry);
4531
5039
  return item;
4532
5040
  } catch (error) {
4533
- throw new RegistryError("unavailable", `CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 '${name}' \uD56D\uBAA9\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${messageOf(error)}`);
5041
+ throw new RegistryError("unavailable", `${this.bundledLabel}\uC758 '${name}' \uD56D\uBAA9\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${messageOf(error)}`);
4534
5042
  }
4535
5043
  }
4536
5044
  };
4537
5045
 
4538
- // src/add/add.ts
5046
+ // ../axis-registry-core/src/add/add.ts
4539
5047
  var AGENTIC_PREFIX = "agentic-";
5048
+ var CLI_ADD_HINTS = {
5049
+ listCommand: "npx @axis-ds/cli list",
5050
+ overwrite: "--overwrite",
5051
+ agenticFlag: true
5052
+ };
4540
5053
  function applyAgenticAlias(name, agentic) {
4541
5054
  if (!agentic || name.startsWith(AGENTIC_PREFIX)) return name;
4542
5055
  return `${AGENTIC_PREFIX}${name}`;
4543
5056
  }
4544
- function describeMissingName(requested, resolved, index, agentic) {
5057
+ function describeMissingName(requested, resolved, index, agentic, agenticFlag = true) {
4545
5058
  const names = new Set(index.items.map((it) => it.name));
4546
5059
  if (!isValidRegistryName(resolved)) {
4547
5060
  return `'${requested}': \uC774\uB984 \uADDC\uCE59(\uC18C\uBB38\uC790 \xB7 \uC22B\uC790 \xB7 \uD558\uC774\uD508)\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`;
@@ -4550,6 +5063,9 @@ function describeMissingName(requested, resolved, index, agentic) {
4550
5063
  return `'${requested}': Agentic UI \uC5D0 '${resolved}' \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. '${requested}' \uB294 Core UI \uD56D\uBAA9\uC774\uB2C8 --agentic \uC5C6\uC774 \uC2E4\uD589\uD558\uC138\uC694`;
4551
5064
  }
4552
5065
  if (!agentic && names.has(`${AGENTIC_PREFIX}${requested}`)) {
5066
+ if (!agenticFlag) {
5067
+ return `'${requested}': \uC5C6\uC2B5\uB2C8\uB2E4. Agentic UI \uD56D\uBAA9\uC744 \uB73B\uD588\uB2E4\uBA74 \uC804\uCCB4 \uC774\uB984 '${AGENTIC_PREFIX}${requested}' \uB97C \uC4F0\uC138\uC694`;
5068
+ }
4553
5069
  return `'${requested}': \uC5C6\uC2B5\uB2C8\uB2E4. Agentic UI \uD56D\uBAA9 '${AGENTIC_PREFIX}${requested}' \uB97C \uB73B\uD588\uB2E4\uBA74 \uC804\uCCB4 \uC774\uB984\uC744 \uC4F0\uAC70\uB098 --agentic \uC744 \uBD99\uC774\uC138\uC694`;
4554
5070
  }
4555
5071
  return `'${requested}': \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`;
@@ -4564,10 +5080,10 @@ function layoutFromConfig(root, config) {
4564
5080
  throw new Error("axis.config.json \uC758 agenticDir \uAC00 \uBB38\uC790\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4");
4565
5081
  }
4566
5082
  const componentsDir = componentsRaw.replace(/\\/g, "/");
4567
- const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") : path15.posix.join(path15.posix.dirname(componentsDir), "agentic");
4568
- return { root: path15.resolve(root), componentsDir, agenticDir };
5083
+ const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") : path17.posix.join(path17.posix.dirname(componentsDir), "agentic");
5084
+ return { root: path17.resolve(root), componentsDir, agenticDir };
4569
5085
  }
4570
- function toPosix(p, impl = path15) {
5086
+ function toPosix(p, impl = path17) {
4571
5087
  return p.split(impl.sep).join("/");
4572
5088
  }
4573
5089
  function itemKind(item) {
@@ -4589,12 +5105,12 @@ function placeFile(layout, item, filePath, target) {
4589
5105
  const problem = registryPathProblem(p);
4590
5106
  if (problem) throw new Error(`${item.name}: \uD30C\uC77C \uACBD\uB85C\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${JSON.stringify(p)}, ${problem})`);
4591
5107
  }
4592
- const base = path15.posix.basename(filePath);
5108
+ const base = path17.posix.basename(filePath);
4593
5109
  if (!INSTALL_FILE_NAME_PATTERN.test(base)) {
4594
5110
  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)`);
4595
5111
  }
4596
5112
  const dir = itemKind(item) === "agentic" ? layout.agenticDir : layout.componentsDir;
4597
- return path15.resolve(layout.root, dir, base);
5113
+ return path17.resolve(layout.root, dir, base);
4598
5114
  }
4599
5115
  function stripExt(p) {
4600
5116
  return p.replace(/\.(?:tsx?|jsx?|mjs|cjs)$/, "");
@@ -4605,7 +5121,7 @@ function buildImportTargets(entries) {
4605
5121
  for (const { item, file, target } of entries) {
4606
5122
  const rel3 = stripExt(file.path.replace(/\\/g, "/").replace(/^\.?\//, ""));
4607
5123
  exact.set(`@/${rel3}`, target);
4608
- if (itemKind(item) === "lib") lib.set(path15.posix.basename(rel3), target);
5124
+ if (itemKind(item) === "lib") lib.set(path17.posix.basename(rel3), target);
4609
5125
  }
4610
5126
  return { exact, lib };
4611
5127
  }
@@ -4681,7 +5197,7 @@ function insideRanges(ranges, at) {
4681
5197
  }
4682
5198
  var SPECIFIER_PATTERN = /(\bfrom\s*|\bimport\s*\(\s*|\bimport\s+|\brequire\s*\(\s*)(["'])(@\/[^"'\n]+)\2/g;
4683
5199
  var STANDARD_LIB_PATTERN = /^@\/registry\/[^/]+\/lib\/(.+)$/;
4684
- function relativeSpecifier(fromFile, toFile, impl = path15) {
5200
+ function relativeSpecifier(fromFile, toFile, impl = path17) {
4685
5201
  let rel3 = toPosix(impl.relative(impl.dirname(fromFile), stripExt(toFile)), impl);
4686
5202
  if (!rel3.startsWith(".")) rel3 = `./${rel3}`;
4687
5203
  return rel3;
@@ -4709,7 +5225,7 @@ function rewriteImports(content, fileTarget, targets) {
4709
5225
  }
4710
5226
  var RESOLVE_EXTS = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", "/index.ts", "/index.tsx", "/index.js"];
4711
5227
  function relativeSpecifierResolves(fromFile, spec) {
4712
- const base = path15.resolve(path15.dirname(fromFile), spec);
5228
+ const base = path17.resolve(path17.dirname(fromFile), spec);
4713
5229
  return RESOLVE_EXTS.some((ext) => {
4714
5230
  try {
4715
5231
  return statSync4(base + ext).isFile();
@@ -4761,7 +5277,7 @@ function planFiles(layout, items) {
4761
5277
  }
4762
5278
  const prev = byTarget.get(target);
4763
5279
  if (prev !== void 0) {
4764
- errors.push(`${item.name}: ${toPosix(path15.relative(layout.root, target))} \uB97C ${prev} \uC640 \uD568\uAED8 \uC501\uB2C8\uB2E4(\uAC19\uC740 \uC704\uCE58)`);
5280
+ errors.push(`${item.name}: ${toPosix(path17.relative(layout.root, target))} \uB97C ${prev} \uC640 \uD568\uAED8 \uC501\uB2C8\uB2E4(\uAC19\uC740 \uC704\uCE58)`);
4765
5281
  continue;
4766
5282
  }
4767
5283
  byTarget.set(target, item.name);
@@ -4787,7 +5303,7 @@ function missingDependencies(root, items) {
4787
5303
  const installCommand = detectInstallCommand(root);
4788
5304
  let pkg;
4789
5305
  try {
4790
- const text = readFileSync6(path15.join(root, "package.json"), "utf8").replace(/^/, "");
5306
+ const text = readFileSync6(path17.join(root, "package.json"), "utf8").replace(/^/, "");
4791
5307
  const parsed = JSON.parse(text);
4792
5308
  pkg = isPlainObject2(parsed) ? parsed : void 0;
4793
5309
  } catch {
@@ -4819,15 +5335,16 @@ function addCommandForSpecs(installCommand, specs) {
4819
5335
  return `pnpm add ${args}`;
4820
5336
  }
4821
5337
  function rel2(root, p) {
4822
- return toPosix(path15.relative(root, p));
5338
+ return toPosix(path17.relative(root, p));
4823
5339
  }
4824
5340
  async function runAdd(cwd, requested, options, ctx) {
4825
5341
  const log = ctx.log ?? console.log;
4826
5342
  const error = ctx.error ?? console.error;
4827
- const root = path15.resolve(cwd);
5343
+ const hints = { ...CLI_ADD_HINTS, ...ctx.hints };
5344
+ const root = path17.resolve(cwd);
4828
5345
  const result = { exitCode: 1, written: [], overwritten: [], unchanged: [], skipped: [] };
4829
5346
  if (requested.length === 0) {
4830
- error("\uCD94\uAC00\uD560 \uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984\uC744 \uD558\uB098 \uC774\uC0C1 \uC801\uC73C\uC138\uC694. \uBAA9\uB85D: npx @axis-ds/cli list");
5347
+ error(`\uCD94\uAC00\uD560 \uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984\uC744 \uD558\uB098 \uC774\uC0C1 \uC801\uC73C\uC138\uC694. \uBAA9\uB85D: ${hints.listCommand}`);
4831
5348
  return result;
4832
5349
  }
4833
5350
  let config;
@@ -4837,9 +5354,16 @@ async function runAdd(cwd, requested, options, ctx) {
4837
5354
  error(`axis.config.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`);
4838
5355
  return result;
4839
5356
  }
5357
+ if (!config && ctx.fallbackConfig) {
5358
+ config = ctx.fallbackConfig;
5359
+ result.usedFallbackConfig = true;
5360
+ log(`axis.config.json \uC774 \uC5C6\uC5B4 \uAE30\uBCF8 \uBC30\uCE58(componentsDir ${config.componentsDir ?? "(\uC5C6\uC74C)"})\uB85C \uC124\uCE58\uD569\uB2C8\uB2E4`);
5361
+ }
4840
5362
  if (!config) {
4841
5363
  error(
4842
- "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"
5364
+ `axis.config.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
5365
+ \uD574\uACB0: \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0\uC11C 'npx @axis-ds/cli init'\uC744 \uC2E4\uD589\uD558\uC138\uC694.
5366
+ \uCC38\uACE0: ${AXIS_QUICK_START_URL}`
4843
5367
  );
4844
5368
  return result;
4845
5369
  }
@@ -4862,13 +5386,13 @@ async function runAdd(cwd, requested, options, ctx) {
4862
5386
  const missing = [];
4863
5387
  for (const req of requested) {
4864
5388
  const name = applyAgenticAlias(req, options.agentic);
4865
- if (!isValidRegistryName(name) || !names.has(name)) missing.push(describeMissingName(req, name, index, options.agentic));
5389
+ if (!isValidRegistryName(name) || !names.has(name)) missing.push(describeMissingName(req, name, index, options.agentic, hints.agenticFlag));
4866
5390
  else if (!resolved.includes(name)) resolved.push(name);
4867
5391
  }
4868
5392
  if (missing.length > 0) {
4869
5393
  error(`\uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4 \uC544\uBB34\uAC83\uB3C4 \uC124\uCE58\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(\uB808\uC9C0\uC2A4\uD2B8\uB9AC version ${index.version}).`);
4870
5394
  for (const m of missing) error(` - ${m}`);
4871
- error(" \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBAA9\uB85D: npx @axis-ds/cli list");
5395
+ error(` \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBAA9\uB85D: ${hints.listCommand}`);
4872
5396
  return result;
4873
5397
  }
4874
5398
  let items;
@@ -4880,6 +5404,7 @@ async function runAdd(cwd, requested, options, ctx) {
4880
5404
  return result;
4881
5405
  }
4882
5406
  items = collected.items;
5407
+ result.items = items.map((it) => it.name);
4883
5408
  } catch (e) {
4884
5409
  const msg = e instanceof RegistryError ? e.message : `\uB808\uC9C0\uC2A4\uD2B8\uB9AC \uD56D\uBAA9\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`;
4885
5410
  error(msg);
@@ -4894,7 +5419,7 @@ async function runAdd(cwd, requested, options, ctx) {
4894
5419
  const existing = /* @__PURE__ */ new Map();
4895
5420
  const readErrors = [];
4896
5421
  for (const file of plan.files) {
4897
- if (!existsSync7(file.target)) {
5422
+ if (!existsSync8(file.target)) {
4898
5423
  existing.set(file, null);
4899
5424
  continue;
4900
5425
  }
@@ -4973,7 +5498,7 @@ async function runAdd(cwd, requested, options, ctx) {
4973
5498
  try {
4974
5499
  const before = escapeReason(root, d.file.target);
4975
5500
  if (before) return stopWriting(p, before);
4976
- await fs12.ensureDir(path15.dirname(d.file.target));
5501
+ await fs13.ensureDir(path17.dirname(d.file.target));
4977
5502
  const after = checkParentInside(root, d.file.target);
4978
5503
  if (after) return stopWriting(p, after);
4979
5504
  actual = await writeNoFollow(d.file.target, d.file.content, actual);
@@ -5029,7 +5554,7 @@ async function runAdd(cwd, requested, options, ctx) {
5029
5554
  log(outsideRel.has(p) ? ` = ${p} (\uAC19\uC740 \uB0B4\uC6A9\uC774\uB77C \uAC74\uB108\uB700, \uB9C1\uD06C \uB300\uC0C1\uC774 \uD504\uB85C\uC81D\uD2B8 \uBC16)` : ` = ${p} (\uAC19\uC740 \uB0B4\uC6A9\uC774\uB77C \uAC74\uB108\uB700)`);
5030
5555
  }
5031
5556
  if (result.skipped.length > 0) {
5032
- log(`\uB0B4\uC6A9\uC774 \uB2E4\uB978 \uAE30\uC874 \uD30C\uC77C ${result.skipped.length}\uAC1C\uB97C \uAC74\uB108\uB6F0\uC5C8\uC2B5\uB2C8\uB2E4(\uB36E\uC5B4\uC4F0\uB824\uBA74 --overwrite):`);
5557
+ log(`\uB0B4\uC6A9\uC774 \uB2E4\uB978 \uAE30\uC874 \uD30C\uC77C ${result.skipped.length}\uAC1C\uB97C \uAC74\uB108\uB6F0\uC5C8\uC2B5\uB2C8\uB2E4(\uB36E\uC5B4\uC4F0\uB824\uBA74 ${hints.overwrite}):`);
5033
5558
  for (const p of result.skipped) log(outsideRel.has(p) ? ` - ${p} (\uB9C1\uD06C \uB300\uC0C1\uC774 \uD504\uB85C\uC81D\uD2B8 \uBC16)` : ` - ${p}`);
5034
5559
  }
5035
5560
  if (broken.length > 0) {
@@ -5039,8 +5564,9 @@ async function runAdd(cwd, requested, options, ctx) {
5039
5564
  }
5040
5565
  const deps = missingDependencies(root, items);
5041
5566
  if (Object.keys(deps.specs).length > 0) {
5567
+ result.dependencyCommand = addCommandForSpecs(deps.installCommand, deps.specs);
5042
5568
  log("\npackage.json \uC5D0 \uC5C6\uB294 \uC758\uC874\uC131(\uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4):");
5043
- log(` ${addCommandForSpecs(deps.installCommand, deps.specs)}`);
5569
+ log(` ${result.dependencyCommand}`);
5044
5570
  }
5045
5571
  return { ...result, exitCode: 0 };
5046
5572
  }
@@ -5055,17 +5581,50 @@ function groupIndex(index) {
5055
5581
  }
5056
5582
  return { ui, agentic };
5057
5583
  }
5058
- async function createClientFor(cwd, notify, env = process.env) {
5584
+ async function createClientFor(cwd, notify, env = process.env, clientOptions = {}) {
5585
+ const { guardConfigRegistry, ...options } = clientOptions;
5059
5586
  let config = null;
5060
5587
  try {
5061
- config = await readAxisConfig(path15.resolve(cwd));
5588
+ config = await readAxisConfig(path17.resolve(cwd));
5062
5589
  } catch {
5063
5590
  config = null;
5064
5591
  }
5065
- const resolved = resolveRegistryUrl({ config, env });
5592
+ let resolved = resolveRegistryUrl({ config, env });
5066
5593
  const say = notify ?? ((message) => console.warn(message));
5067
5594
  if (resolved.migratedFrom !== void 0) say(LEGACY_REGISTRY_NOTICE);
5068
- return new RegistryClient({ url: resolved.url, ...notify ? { notify } : {} });
5595
+ let rejectRedirects = false;
5596
+ if (guardConfigRegistry && resolved.source === "config" && resolved.migratedFrom === void 0 && !isDefaultRegistry(resolved.url)) {
5597
+ const problem = await publicRegistryUrlProblem(resolved.url, guardConfigRegistry.lookup);
5598
+ if (problem !== null) {
5599
+ say(configRegistryRejectedMessage(resolved.url, problem));
5600
+ resolved = { url: DEFAULT_REGISTRY_URL, source: "default" };
5601
+ } else {
5602
+ rejectRedirects = true;
5603
+ if (!options.fetchImpl) {
5604
+ options.fetchImpl = createPinnedFetch({
5605
+ ...guardConfigRegistry.lookup ? { lookupAll: guardConfigRegistry.lookup } : {},
5606
+ ...guardConfigRegistry.connect
5607
+ });
5608
+ }
5609
+ }
5610
+ }
5611
+ return new RegistryClient({
5612
+ ...options,
5613
+ url: resolved.url,
5614
+ urlSource: resolved.source,
5615
+ ...rejectRedirects ? { rejectRedirects: true } : {},
5616
+ ...notify ? { notify } : {}
5617
+ });
5618
+ }
5619
+ function isDefaultRegistry(url) {
5620
+ try {
5621
+ return normalizeRegistryBaseUrl(url.trim()) === DEFAULT_REGISTRY_URL;
5622
+ } catch {
5623
+ return false;
5624
+ }
5625
+ }
5626
+ function configRegistryRejectedMessage(url, problem) {
5627
+ return `axis.config.json \uC758 registry(${redactRegistryUrl(url)})\uB97C \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${problem}. config \uC758 registry \uB294 \uACF5\uAC1C https \uC8FC\uC18C\uC77C \uB54C\uB9CC \uC501\uB2C8\uB2E4(\uB8E8\uD504\uBC31 \xB7 \uC0AC\uC124 \xB7 \uB9C1\uD06C\uB85C\uCEEC \uC8FC\uC18C \uC81C\uC678). \uAE30\uBCF8 \uC8FC\uC18C(${DEFAULT_REGISTRY_URL})\uB85C \uC870\uD68C\uD569\uB2C8\uB2E4`;
5069
5628
  }
5070
5629
 
5071
5630
  // src/add/index.ts
@@ -5076,7 +5635,7 @@ function createConfirm(interactive) {
5076
5635
  return overwrite === true;
5077
5636
  };
5078
5637
  }
5079
- var defaultCreateClient = (cwd) => createClientFor(cwd, (m) => console.warn(chalk11.yellow(m)));
5638
+ var defaultCreateClient = (cwd) => createClientFor(cwd, (m) => console.warn(chalk12.yellow(m)));
5080
5639
  function registerAddCommand(program2, deps = {}) {
5081
5640
  program2.command("add <components...>").description("\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD504\uB85C\uC81D\uD2B8\uC5D0 \uBCF5\uC0AC(registryDependencies \uD3EC\uD568)").option("--agentic", "\uC774\uB984 \uC55E\uC5D0 agentic- \uB97C \uBD99\uC5EC \uCC3E\uC74C(\uC804\uCCB4 \uC774\uB984\uB3C4 \uD5C8\uC6A9)").option("-y, --yes", "\uBB3B\uC9C0 \uC54A\uACE0 \uC9C4\uD589. \uB0B4\uC6A9\uC774 \uB2E4\uB978 \uAE30\uC874 \uD30C\uC77C\uC740 \uAC74\uB108\uB700").option("--overwrite", "\uB0B4\uC6A9\uC774 \uB2E4\uB978 \uAE30\uC874 \uD30C\uC77C\uC744 \uB36E\uC5B4\uC500").action(async (components, options) => {
5082
5641
  const client = await (deps.createClient ?? defaultCreateClient)(process.cwd());
@@ -5084,7 +5643,7 @@ function registerAddCommand(program2, deps = {}) {
5084
5643
  const result = await runAdd(process.cwd(), components, options, {
5085
5644
  client,
5086
5645
  log: (...a) => console.log(...a),
5087
- error: (...a) => console.error(chalk11.red(a.map(String).join(" "))),
5646
+ error: (...a) => console.error(chalk12.red(a.map(String).join(" "))),
5088
5647
  ...confirm ? { confirm } : {}
5089
5648
  });
5090
5649
  process.exitCode = result.exitCode;
@@ -5093,7 +5652,7 @@ function registerAddCommand(program2, deps = {}) {
5093
5652
  function registerListCommand(program2, deps = {}) {
5094
5653
  program2.command("list").description("\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uCEF4\uD3EC\uB10C\uD2B8 \uBAA9\uB85D").option("--category <type>", "\uCE74\uD14C\uACE0\uB9AC \uD544\uD130 (ui, agentic)").action(async (options) => {
5095
5654
  if (options.category !== void 0 && options.category !== "ui" && options.category !== "agentic") {
5096
- console.error(chalk11.red(`--category \uB294 ui \uB610\uB294 agentic \uC785\uB2C8\uB2E4(\uBC1B\uC740 \uAC12: ${options.category})`));
5655
+ console.error(chalk12.red(`--category \uB294 ui \uB610\uB294 agentic \uC785\uB2C8\uB2E4(\uBC1B\uC740 \uAC12: ${options.category})`));
5097
5656
  process.exitCode = 1;
5098
5657
  return;
5099
5658
  }
@@ -5105,26 +5664,26 @@ function registerListCommand(program2, deps = {}) {
5105
5664
  groups = groupIndex(index);
5106
5665
  version = index.version;
5107
5666
  } catch (e) {
5108
- console.error(chalk11.red(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`));
5667
+ console.error(chalk12.red(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`));
5109
5668
  process.exitCode = 1;
5110
5669
  return;
5111
5670
  }
5112
5671
  const total = groups.ui.length + groups.agentic.length;
5113
5672
  const origin = client.origin === "bundled" ? "CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC" : "\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC";
5114
- console.log(chalk11.blue(`
5673
+ console.log(chalk12.blue(`
5115
5674
  \u{1F4E6} AXIS Design System \uCEF4\uD3EC\uB10C\uD2B8 ${total}\uAC1C (${origin}, version ${version})
5116
5675
  `));
5117
5676
  const show = (label, items) => {
5118
- console.log(chalk11.bold(`${label} (${items.length})`));
5677
+ console.log(chalk12.bold(`${label} (${items.length})`));
5119
5678
  for (const c of items) {
5120
- console.log(` ${chalk11.cyan(c.name.padEnd(32))} ${chalk11.gray(c.description ?? c.title ?? "")}`);
5679
+ console.log(` ${chalk12.cyan(c.name.padEnd(32))} ${chalk12.gray(c.description ?? c.title ?? "")}`);
5121
5680
  }
5122
5681
  console.log();
5123
5682
  };
5124
5683
  if (!options.category || options.category === "ui") show("Core UI", groups.ui);
5125
5684
  if (!options.category || options.category === "agentic") show("Agentic UI", groups.agentic);
5126
- console.log(chalk11.gray("\uC0AC\uC6A9\uBC95: npx @axis-ds/cli add <\uC774\uB984...> (\uC608: add button input card)"));
5127
- console.log(chalk11.gray("Agentic: npx @axis-ds/cli add run-progress --agentic (= add agentic-run-progress)\n"));
5685
+ console.log(chalk12.gray("\uC0AC\uC6A9\uBC95: npx @axis-ds/cli add <\uC774\uB984...> (\uC608: add button input card)"));
5686
+ console.log(chalk12.gray("Agentic: npx @axis-ds/cli add run-progress --agentic (= add agentic-run-progress)\n"));
5128
5687
  });
5129
5688
  }
5130
5689
 
@@ -5153,24 +5712,24 @@ monetCmd.command("import").alias("i").description("\uD074\uB9BD\uBCF4\uB4DC\uC5D
5153
5712
  await client.importFromClipboard();
5154
5713
  });
5155
5714
  monetCmd.command("setup").description("Monet MCP \uC11C\uBC84 \uC124\uC815 \uC548\uB0B4").action(() => {
5156
- console.log(chalk12.blue("\n\u{1F527} Monet MCP \uC11C\uBC84 \uC124\uC815\n"));
5157
- console.log(chalk12.bold("1. API \uD0A4 \uBC1C\uAE09:"));
5158
- console.log(chalk12.cyan(" https://monet.design/mcp\n"));
5159
- console.log(chalk12.bold("2. \uD658\uACBD \uBCC0\uC218 \uC124\uC815:"));
5160
- console.log(chalk12.gray(" .env \uD30C\uC77C\uC5D0 \uCD94\uAC00:"));
5161
- console.log(chalk12.cyan(" MONET_API_KEY=your-api-key-here\n"));
5162
- console.log(chalk12.bold("3. Claude Code MCP \uC124\uC815:"));
5163
- console.log(chalk12.gray(" .claude/mcp.json\uC5D0\uC11C monet \uC11C\uBC84 \uD65C\uC131\uD654:\n"));
5715
+ console.log(chalk13.blue("\n\u{1F527} Monet MCP \uC11C\uBC84 \uC124\uC815\n"));
5716
+ console.log(chalk13.bold("1. API \uD0A4 \uBC1C\uAE09:"));
5717
+ console.log(chalk13.cyan(" https://monet.design/mcp\n"));
5718
+ console.log(chalk13.bold("2. \uD658\uACBD \uBCC0\uC218 \uC124\uC815:"));
5719
+ console.log(chalk13.gray(" .env \uD30C\uC77C\uC5D0 \uCD94\uAC00:"));
5720
+ console.log(chalk13.cyan(" MONET_API_KEY=your-api-key-here\n"));
5721
+ console.log(chalk13.bold("3. Claude Code MCP \uC124\uC815:"));
5722
+ console.log(chalk13.gray(" .claude/mcp.json\uC5D0\uC11C monet \uC11C\uBC84 \uD65C\uC131\uD654:\n"));
5164
5723
  console.log(
5165
- chalk12.cyan(` "monet": {
5724
+ chalk13.cyan(` "monet": {
5166
5725
  "url": "https://www.monet.design/api/remote/mcp",
5167
5726
  "headers": { "Authorization": "Bearer \${MONET_API_KEY}" },
5168
5727
  "disabled": false
5169
5728
  }
5170
5729
  `)
5171
5730
  );
5172
- console.log(chalk12.bold("4. Claude Code \uC7AC\uC2DC\uC791 \uD6C4 \uC0AC\uC6A9:"));
5173
- console.log(chalk12.gray(' "monet\uC5D0\uC11C hero \uCEF4\uD3EC\uB10C\uD2B8 \uCC3E\uC544\uC918"\n'));
5731
+ console.log(chalk13.bold("4. Claude Code \uC7AC\uC2DC\uC791 \uD6C4 \uC0AC\uC6A9:"));
5732
+ console.log(chalk13.gray(' "monet\uC5D0\uC11C hero \uCEF4\uD3EC\uB10C\uD2B8 \uCC3E\uC544\uC918"\n'));
5174
5733
  });
5175
5734
  var v0Cmd = program.command("v0").description("V0 (v0.app) \uCF54\uB4DC \uBCC0\uD658 \uBC0F \uD1B5\uD569");
5176
5735
  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) => {
@@ -5207,18 +5766,18 @@ libraryCmd.command("collect").alias("c").description("\uC678\uBD80 \uC18C\uC2A4\
5207
5766
  total += result.collected;
5208
5767
  failed += result.failed;
5209
5768
  }
5210
- console.log(chalk12.blue(`
5769
+ console.log(chalk13.blue(`
5211
5770
  \u{1F4CA} \uC218\uC9D1 \uC644\uB8CC: ${total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8`));
5212
5771
  if (failed > 0) {
5213
- console.log(chalk12.yellow(` \uC2E4\uD328: ${failed}\uAC1C`));
5772
+ console.log(chalk13.yellow(` \uC2E4\uD328: ${failed}\uAC1C`));
5214
5773
  }
5215
5774
  });
5216
5775
  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) => {
5217
5776
  const curator = new LibraryCurator();
5218
5777
  const index = await curator.loadIndex();
5219
5778
  if (!index) {
5220
- console.log(chalk12.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
5221
- console.log(chalk12.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
5779
+ console.log(chalk13.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
5780
+ console.log(chalk13.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
5222
5781
  return;
5223
5782
  }
5224
5783
  let components = index.components;
@@ -5228,7 +5787,7 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
5228
5787
  if (options.source) {
5229
5788
  components = components.filter((c) => c.source.type === options.source);
5230
5789
  }
5231
- console.log(chalk12.blue(`
5790
+ console.log(chalk13.blue(`
5232
5791
  \u{1F4E6} Library Components (${components.length}\uAC1C)
5233
5792
  `));
5234
5793
  const byCategory = /* @__PURE__ */ new Map();
@@ -5240,14 +5799,14 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
5240
5799
  byCategory.get(cat).push(comp);
5241
5800
  }
5242
5801
  for (const [category, items] of byCategory) {
5243
- console.log(chalk12.bold(`${category} (${items.length})`));
5802
+ console.log(chalk13.bold(`${category} (${items.length})`));
5244
5803
  for (const item of items.slice(0, 10)) {
5245
5804
  console.log(
5246
- ` ${chalk12.cyan(item.name.padEnd(25))} ${chalk12.gray(item.source.type.padEnd(8))} ${chalk12.gray(item.description.slice(0, 40))}`
5805
+ ` ${chalk13.cyan(item.name.padEnd(25))} ${chalk13.gray(item.source.type.padEnd(8))} ${chalk13.gray(item.description.slice(0, 40))}`
5247
5806
  );
5248
5807
  }
5249
5808
  if (items.length > 10) {
5250
- console.log(chalk12.gray(` ... \uC678 ${items.length - 10}\uAC1C`));
5809
+ console.log(chalk13.gray(` ... \uC678 ${items.length - 10}\uAC1C`));
5251
5810
  }
5252
5811
  console.log();
5253
5812
  }
@@ -5259,21 +5818,21 @@ libraryCmd.command("search <query>").alias("s").description("\uCEF4\uD3EC\uB10C\
5259
5818
  source: options.source
5260
5819
  });
5261
5820
  if (results.length === 0) {
5262
- console.log(chalk12.yellow(`
5821
+ console.log(chalk13.yellow(`
5263
5822
  '${query}'\uC5D0 \uB300\uD55C \uAC80\uC0C9 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
5264
5823
  `));
5265
5824
  return;
5266
5825
  }
5267
- console.log(chalk12.blue(`
5826
+ console.log(chalk13.blue(`
5268
5827
  \u{1F50D} '${query}' \uAC80\uC0C9 \uACB0\uACFC (${results.length}\uAC1C)
5269
5828
  `));
5270
5829
  for (const comp of results.slice(0, 20)) {
5271
5830
  console.log(
5272
- ` ${chalk12.cyan(comp.name.padEnd(25))} ${chalk12.gray(comp.source.type.padEnd(8))} ${chalk12.gray(comp.category.padEnd(12))} ${chalk12.gray(comp.description.slice(0, 30))}`
5831
+ ` ${chalk13.cyan(comp.name.padEnd(25))} ${chalk13.gray(comp.source.type.padEnd(8))} ${chalk13.gray(comp.category.padEnd(12))} ${chalk13.gray(comp.description.slice(0, 30))}`
5273
5832
  );
5274
5833
  }
5275
5834
  if (results.length > 20) {
5276
- console.log(chalk12.gray(`
5835
+ console.log(chalk13.gray(`
5277
5836
  ... \uC678 ${results.length - 20}\uAC1C`));
5278
5837
  }
5279
5838
  console.log();
@@ -5287,12 +5846,12 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
5287
5846
  const publisher2 = new Publisher();
5288
5847
  const index = await curator.loadIndex();
5289
5848
  if (!index) {
5290
- console.log(chalk12.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
5291
- console.log(chalk12.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
5849
+ console.log(chalk13.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
5850
+ console.log(chalk13.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
5292
5851
  return;
5293
5852
  }
5294
- console.log(chalk12.blue("\n\u{1F4E4} Library \uBC30\uCE58\n"));
5295
- console.log(chalk12.gray(`\uCD1D ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8
5853
+ console.log(chalk13.blue("\n\u{1F4E4} Library \uBC30\uCE58\n"));
5854
+ console.log(chalk13.gray(`\uCD1D ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8
5296
5855
  `));
5297
5856
  if (options.clean) {
5298
5857
  await publisher2.clean(options.output);
@@ -5303,21 +5862,22 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
5303
5862
  generateSearchIndex: true
5304
5863
  });
5305
5864
  if (result.success) {
5306
- console.log(chalk12.green(`
5865
+ console.log(chalk13.green(`
5307
5866
  \u2713 \uBC30\uCE58 \uC644\uB8CC`));
5308
- console.log(chalk12.gray(` - \uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC: ${result.outputDir}`));
5309
- console.log(chalk12.gray(` - \uC0DD\uC131\uB41C \uD30C\uC77C: ${result.files.length}\uAC1C`));
5310
- console.log(chalk12.gray(` - \uCE74\uD14C\uACE0\uB9AC: ${result.stats.categoriesPublished}\uAC1C`));
5311
- console.log(chalk12.gray(` - \uAC80\uC0C9 \uC778\uB371\uC2A4: ${result.stats.searchIndexSize}\uAC1C \uD56D\uBAA9`));
5867
+ console.log(chalk13.gray(` - \uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC: ${result.outputDir}`));
5868
+ console.log(chalk13.gray(` - \uC0DD\uC131\uB41C \uD30C\uC77C: ${result.files.length}\uAC1C`));
5869
+ console.log(chalk13.gray(` - \uCE74\uD14C\uACE0\uB9AC: ${result.stats.categoriesPublished}\uAC1C`));
5870
+ console.log(chalk13.gray(` - \uAC80\uC0C9 \uC778\uB371\uC2A4: ${result.stats.searchIndexSize}\uAC1C \uD56D\uBAA9`));
5312
5871
  } else {
5313
- console.log(chalk12.red(`
5872
+ console.log(chalk13.red(`
5314
5873
  \u2717 \uBC30\uCE58 \uC2E4\uD328`));
5315
5874
  for (const error of result.errors) {
5316
- console.log(chalk12.red(` - ${error}`));
5875
+ console.log(chalk13.red(` - ${error}`));
5317
5876
  }
5318
5877
  }
5319
5878
  console.log();
5320
5879
  });
5880
+ registerRefreshAxisCommand(libraryCmd);
5321
5881
  registerSyncCommand(program);
5322
5882
  registerTemplateCommand(program);
5323
5883
  registerCheckCommand(program);