@axis-ds/cli 1.5.1 → 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
@@ -13,11 +13,11 @@ import {
13
13
  AXIS_SITE_URL,
14
14
  fetchTemplateDetail,
15
15
  fetchTemplateIndex
16
- } from "./chunk-NVGENR3K.js";
16
+ } from "./chunk-IQY3WUGG.js";
17
17
 
18
18
  // src/index.ts
19
19
  import { Command } from "commander";
20
- import chalk12 from "chalk";
20
+ import chalk13 from "chalk";
21
21
  import { createRequire as createRequire2 } from "module";
22
22
 
23
23
  // src/library/base-collector.ts
@@ -482,11 +482,11 @@ var ShadcnCollector = class extends BaseCollector {
482
482
  /**
483
483
  * 파일 타입 추론
484
484
  */
485
- getFileType(path16) {
486
- if (path16.includes("hook") || path16.startsWith("use")) return "hook";
487
- if (path16.includes("util") || path16.includes("lib")) return "util";
488
- if (path16.endsWith(".css")) return "style";
489
- 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";
490
490
  return "component";
491
491
  }
492
492
  };
@@ -865,9 +865,12 @@ import path2 from "path";
865
865
  var DEFAULT_PATHS = {
866
866
  uiReact: "packages/axis-ui-react/src",
867
867
  agenticUi: "packages/axis-agentic-ui/src",
868
- webComponents: "apps/web/src/app/components",
869
- 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"
870
872
  };
873
+ var NON_COMPONENT_FILE = /\.(test|spec|stories)\.tsx?$/;
871
874
  var AxisCollector = class extends BaseCollector {
872
875
  sourceType = "axis";
873
876
  rootDir;
@@ -877,28 +880,45 @@ var AxisCollector = class extends BaseCollector {
877
880
  this.rootDir = options.rootDir || process.cwd();
878
881
  this.paths = { ...DEFAULT_PATHS, ...options.paths };
879
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
+ }
880
890
  /**
881
891
  * AXIS 컴포넌트 목록 조회
882
892
  */
883
893
  async listComponents() {
884
894
  const items = [];
885
- items.push(...await this.scanPackage(this.paths.uiReact, "ui", "@axis-ds/ui-react"));
886
- items.push(...await this.scanPackage(this.paths.agenticUi, "agentic", "@axis-ds/agentic-ui"));
887
- items.push(...await this.scanWebDirectory(this.paths.webComponents, "ui"));
888
- items.push(...await this.scanWebDirectory(this.paths.webAgentic, "agentic"));
889
- const uniqueItems = /* @__PURE__ */ new Map();
890
- for (const item of items) {
891
- if (!uniqueItems.has(item.id)) {
892
- 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
+ });
893
913
  }
894
914
  }
895
- return [...uniqueItems.values()];
915
+ return items;
896
916
  }
897
917
  /**
898
918
  * 단일 컴포넌트 수집
899
919
  */
900
920
  async collectComponent(id) {
901
- const slug = id.replace("axis-", "");
921
+ const slug = id.replace(/^axis-/, "");
902
922
  const componentInfo = await this.findComponent(slug);
903
923
  if (!componentInfo) {
904
924
  throw new Error(`AXIS component not found: ${slug}`);
@@ -915,138 +935,100 @@ var AxisCollector = class extends BaseCollector {
915
935
  const mainContent = codeFiles.map((f) => f.content).join("\n");
916
936
  const meta = this.createBaseMeta(
917
937
  componentInfo.name,
918
- this.extractDescription(mainContent) || `AXIS ${componentInfo.name} component`,
938
+ this.extractDescription(mainContent, slug) || `AXIS ${componentInfo.name} component`,
919
939
  codeFiles,
920
940
  {
921
941
  registry: "@axis",
922
- url: this.getDocsUrl(slug, componentInfo.category)
942
+ url: await this.resolveDocsUrl(slug, componentInfo.route)
923
943
  }
924
944
  );
925
945
  meta.category = componentInfo.category;
926
946
  return meta;
927
947
  }
928
948
  /**
929
- * 패키지 디렉토리 스캔
949
+ * 문서 URL 을 정합니다(WI-0057 D3).
950
+ * ① `<docsApp>/<route>/<slug>/page.tsx` 가 있으면 그 경로 ② 없으면 별칭 표의 대상이 실재할 때 그 경로
951
+ * ③ 둘 다 없으면 빈 문자열(library 상세 화면은 빈 URL 이면 문서 링크를 그리지 않습니다).
930
952
  */
931
- async scanPackage(packagePath, defaultCategory, registry) {
932
- const items = [];
933
- const fullPath = path2.join(this.rootDir, packagePath);
934
- if (!await fs2.pathExists(fullPath)) {
935
- return items;
936
- }
937
- const entries = await fs2.readdir(fullPath, { withFileTypes: true });
938
- for (const entry of entries) {
939
- if (entry.isDirectory()) {
940
- const componentDir = path2.join(fullPath, entry.name);
941
- const indexFile = path2.join(componentDir, "index.tsx");
942
- if (await fs2.pathExists(indexFile)) {
943
- const content = await fs2.readFile(indexFile, "utf-8");
944
- const name = this.formatName(entry.name);
945
- items.push({
946
- id: `axis-${entry.name}`,
947
- name,
948
- description: this.extractDescription(content) || `AXIS ${name} component`,
949
- category: this.classifyCategory(entry.name, content) || defaultCategory,
950
- source: "axis"
951
- });
952
- }
953
- } else if (entry.name.endsWith(".tsx") && entry.name !== "index.tsx") {
954
- const name = entry.name.replace(".tsx", "");
955
- const filePath = path2.join(fullPath, entry.name);
956
- const content = await fs2.readFile(filePath, "utf-8");
957
- items.push({
958
- id: `axis-${name}`,
959
- name: this.formatName(name),
960
- description: this.extractDescription(content) || `AXIS ${name} component`,
961
- category: this.classifyCategory(name, content) || defaultCategory,
962
- source: "axis"
963
- });
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}`;
964
961
  }
965
962
  }
966
- return items;
963
+ return "";
964
+ }
965
+ async docsRouteExists(routePath) {
966
+ return fs2.pathExists(path2.join(this.rootDir, this.paths.docsApp, routePath, "page.tsx"));
967
967
  }
968
968
  /**
969
- * Web 디렉토리 스캔 (app router 구조)
969
+ * 패키지 src 바로 아래에서 index.tsx 가 있는 디렉터리 이름(정렬). 단일 파일(a11y.test.tsx 등)과
970
+ * index.tsx 가 없는 디렉터리(constants · test-utils)는 컴포넌트가 아닙니다.
970
971
  */
971
- async scanWebDirectory(webPath, defaultCategory) {
972
- const items = [];
973
- const fullPath = path2.join(this.rootDir, webPath);
972
+ async listComponentDirs(packagePath) {
973
+ const fullPath = path2.join(this.rootDir, packagePath);
974
974
  if (!await fs2.pathExists(fullPath)) {
975
- return items;
975
+ return [];
976
976
  }
977
977
  const entries = await fs2.readdir(fullPath, { withFileTypes: true });
978
+ const slugs = [];
978
979
  for (const entry of entries) {
979
- if (entry.isDirectory()) {
980
- const componentDir = path2.join(fullPath, entry.name);
981
- const pageFile = path2.join(componentDir, "page.tsx");
982
- if (await fs2.pathExists(pageFile)) {
983
- const content = await fs2.readFile(pageFile, "utf-8");
984
- const name = this.formatName(entry.name);
985
- items.push({
986
- id: `axis-${entry.name}`,
987
- name,
988
- description: this.extractDescription(content) || `AXIS ${name} component`,
989
- category: this.classifyCategory(entry.name, content) || defaultCategory,
990
- source: "axis"
991
- });
992
- }
980
+ if (!entry.isDirectory()) continue;
981
+ if (await fs2.pathExists(path2.join(fullPath, entry.name, "index.tsx"))) {
982
+ slugs.push(entry.name);
993
983
  }
994
984
  }
995
- return items;
985
+ return slugs.sort();
996
986
  }
997
987
  /**
998
988
  * 컴포넌트 찾기
999
989
  */
1000
990
  async findComponent(slug) {
1001
- const searchPaths = [
1002
- { base: this.paths.uiReact, category: "ui" },
1003
- { base: this.paths.agenticUi, category: "agentic" },
1004
- { base: this.paths.webComponents, category: "ui" },
1005
- { base: this.paths.webAgentic, category: "agentic" }
1006
- ];
1007
- for (const { base, category } of searchPaths) {
1008
- const fullBase = path2.join(this.rootDir, base);
1009
- const dirPath = path2.join(fullBase, slug);
1010
- if (await fs2.pathExists(dirPath)) {
1011
- const files = await this.getComponentFiles(dirPath);
1012
- if (files.length > 0) {
1013
- return {
1014
- name: this.formatName(slug),
1015
- files,
1016
- baseDir: dirPath,
1017
- category
1018
- };
1019
- }
1020
- }
1021
- const filePath = path2.join(fullBase, `${slug}.tsx`);
1022
- 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) {
1023
996
  return {
1024
997
  name: this.formatName(slug),
1025
- files: [filePath],
1026
- baseDir: fullBase,
1027
- category
998
+ files,
999
+ baseDir: dirPath,
1000
+ category: pkg.category,
1001
+ route: pkg.route
1028
1002
  };
1029
1003
  }
1030
1004
  }
1031
1005
  return null;
1032
1006
  }
1033
1007
  /**
1034
- * 컴포넌트 디렉토리에서 파일 목록 가져오기
1008
+ * 컴포넌트 디렉터리의 코드 파일(.ts · .tsx, 테스트 · 스토리 제외). 이름순으로 정렬해 결과가 매번 같습니다.
1035
1009
  */
1036
1010
  async getComponentFiles(dir) {
1037
- const files = [];
1038
1011
  const entries = await fs2.readdir(dir, { withFileTypes: true });
1039
- for (const entry of entries) {
1040
- if (entry.isFile() && (entry.name.endsWith(".tsx") || entry.name.endsWith(".ts"))) {
1041
- files.push(path2.join(dir, entry.name));
1042
- }
1043
- }
1044
- 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));
1045
1015
  }
1046
1016
  /**
1047
- * 설명 추출
1017
+ * 설명 추출. 컴포넌트 이름(slug 의 PascalCase)으로 선언된 곳 바로 앞의 JSDoc 첫 줄을 먼저 씁니다
1018
+ * (WI-0057: 파일 첫 JSDoc 은 Props 인터페이스 · 하위 컴포넌트 설명인 경우가 많았습니다).
1048
1019
  */
1049
- 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
+ }
1050
1032
  const jsdocMatch = code.match(/\/\*\*\s*\n\s*\*\s*(.+)\n/);
1051
1033
  if (jsdocMatch) {
1052
1034
  return jsdocMatch[1].trim();
@@ -1074,14 +1056,6 @@ var AxisCollector = class extends BaseCollector {
1074
1056
  if (name.endsWith(".d.ts") || name.includes("types")) return "type";
1075
1057
  return "component";
1076
1058
  }
1077
- /**
1078
- * 문서 URL 생성
1079
- */
1080
- getDocsUrl(slug, category) {
1081
- const baseUrl = AXIS_SITE_URL;
1082
- const route = category === "agentic" ? "agentic" : "components";
1083
- return `${baseUrl}/${route}/${slug}`;
1084
- }
1085
1059
  };
1086
1060
 
1087
1061
  // src/library/publisher.ts
@@ -1089,6 +1063,49 @@ import fs3 from "fs-extra";
1089
1063
  import path3 from "path";
1090
1064
  import chalk from "chalk";
1091
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
+ }
1092
1109
  var Publisher = class {
1093
1110
  defaultOutputDir = "apps/web/public/library";
1094
1111
  /**
@@ -1190,55 +1207,20 @@ var Publisher = class {
1190
1207
  updatedAt: index.updatedAt,
1191
1208
  stats: index.stats,
1192
1209
  categories: index.categories,
1193
- components: index.components.map((c) => ({
1194
- id: c.id,
1195
- slug: c.slug,
1196
- name: c.name,
1197
- description: c.description,
1198
- category: c.category,
1199
- source: c.source.type,
1200
- tags: c.tags,
1201
- status: c.status
1202
- }))
1210
+ components: index.components.map(toIndexEntry)
1203
1211
  };
1204
1212
  }
1205
1213
  /**
1206
1214
  * 공개용 컴포넌트 생성
1207
1215
  */
1208
1216
  createPublicComponent(component) {
1209
- return {
1210
- id: component.id,
1211
- slug: component.slug,
1212
- name: component.name,
1213
- description: component.description,
1214
- category: component.category,
1215
- source: {
1216
- type: component.source.type,
1217
- registry: component.source.registry,
1218
- url: component.source.url
1219
- },
1220
- tags: component.tags,
1221
- code: component.code,
1222
- preview: component.preview,
1223
- dependencies: component.dependencies,
1224
- status: component.status,
1225
- updatedAt: component.updatedAt
1226
- };
1217
+ return toPublicComponent(component);
1227
1218
  }
1228
1219
  /**
1229
1220
  * 검색 인덱스 생성
1230
1221
  */
1231
1222
  generateSearchIndex(index) {
1232
- return index.components.map((c) => ({
1233
- id: c.id,
1234
- slug: c.slug,
1235
- name: c.name,
1236
- description: c.description,
1237
- category: c.category,
1238
- source: c.source.type,
1239
- tags: c.tags,
1240
- url: `/library/${c.category}/${c.slug}`
1241
- }));
1223
+ return index.components.map(toSearchItem);
1242
1224
  }
1243
1225
  /**
1244
1226
  * JSON 파일 쓰기
@@ -1280,10 +1262,269 @@ var Publisher = class {
1280
1262
  };
1281
1263
  var publisher = new Publisher();
1282
1264
 
1283
- // src/library/index.ts
1265
+ // src/library/axis-refresh.ts
1284
1266
  import fs4 from "fs-extra";
1285
1267
  import path4 from "path";
1286
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";
1287
1528
  import ora2 from "ora";
1288
1529
  var DEFAULT_CATEGORIES = [
1289
1530
  { id: "ui", name: "UI", description: "\uAE30\uBCF8 UI \uCEF4\uD3EC\uB10C\uD2B8", icon: "layers", order: 1 },
@@ -1313,11 +1554,11 @@ var LibraryCurator = class {
1313
1554
  async collectAll(sources, options) {
1314
1555
  const results = /* @__PURE__ */ new Map();
1315
1556
  const targetSources = sources || ["shadcn", "monet", "v0", "axis"];
1316
- 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"));
1317
1558
  for (const source of targetSources) {
1318
1559
  const collector = this.collectors.get(source);
1319
1560
  if (!collector) {
1320
- console.log(chalk2.yellow(`\u26A0\uFE0F ${source} collector not found, skipping`));
1561
+ console.log(chalk3.yellow(`\u26A0\uFE0F ${source} collector not found, skipping`));
1321
1562
  continue;
1322
1563
  }
1323
1564
  const spinner = ora2(`${source} \uC218\uC9D1 \uC911...`).start();
@@ -1328,7 +1569,7 @@ var LibraryCurator = class {
1328
1569
  results.set(source, result);
1329
1570
  if (result.success) {
1330
1571
  spinner.succeed(
1331
- `${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)`) : "")
1332
1573
  );
1333
1574
  } else {
1334
1575
  spinner.fail(`${source}: \uC218\uC9D1 \uC2E4\uD328 - ${result.errors[0]?.error}`);
@@ -1388,15 +1629,15 @@ var LibraryCurator = class {
1388
1629
  * 인덱스 저장
1389
1630
  */
1390
1631
  async saveIndex(index) {
1391
- await fs4.ensureDir(this.dataDir);
1392
- const indexPath = path4.join(this.dataDir, "components.json");
1393
- await fs4.writeJSON(indexPath, index, { spaces: 2 });
1394
- const categoriesDir = path4.join(this.dataDir, "categories");
1395
- 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);
1396
1637
  for (const category of DEFAULT_CATEGORIES) {
1397
1638
  const categoryComponents = index.components.filter((c) => c.category === category.id);
1398
- const categoryPath = path4.join(categoriesDir, `${category.id}.json`);
1399
- await fs4.writeJSON(
1639
+ const categoryPath = path5.join(categoriesDir, `${category.id}.json`);
1640
+ await fs5.writeJSON(
1400
1641
  categoryPath,
1401
1642
  {
1402
1643
  category: category.id,
@@ -1406,17 +1647,17 @@ var LibraryCurator = class {
1406
1647
  { spaces: 2 }
1407
1648
  );
1408
1649
  }
1409
- console.log(chalk2.green(`
1650
+ console.log(chalk3.green(`
1410
1651
  \u2713 \uC778\uB371\uC2A4 \uC800\uC7A5 \uC644\uB8CC: ${indexPath}`));
1411
- 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`));
1412
1653
  }
1413
1654
  /**
1414
1655
  * 인덱스 로드
1415
1656
  */
1416
1657
  async loadIndex() {
1417
- const indexPath = path4.join(this.dataDir, "components.json");
1418
- if (await fs4.pathExists(indexPath)) {
1419
- 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);
1420
1661
  }
1421
1662
  return null;
1422
1663
  }
@@ -1471,26 +1712,26 @@ var LibraryCurator = class {
1471
1712
  async printStats() {
1472
1713
  const index = await this.loadIndex();
1473
1714
  if (!index) {
1474
- console.log(chalk2.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
1475
- 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"));
1476
1717
  return;
1477
1718
  }
1478
- console.log(chalk2.blue("\n\u{1F4CA} Library Curator - \uD1B5\uACC4\n"));
1479
- console.log(chalk2.bold("\uC804\uCCB4 \uCEF4\uD3EC\uB10C\uD2B8: ") + chalk2.cyan(`${index.stats.total}\uAC1C`));
1480
- 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}
1481
1722
  `));
1482
- console.log(chalk2.bold("\uC18C\uC2A4\uBCC4:"));
1723
+ console.log(chalk3.bold("\uC18C\uC2A4\uBCC4:"));
1483
1724
  for (const [source, count] of Object.entries(index.stats.bySource)) {
1484
- console.log(` ${chalk2.cyan(source.padEnd(10))} ${count}\uAC1C`);
1725
+ console.log(` ${chalk3.cyan(source.padEnd(10))} ${count}\uAC1C`);
1485
1726
  }
1486
- console.log(chalk2.bold("\n\uCE74\uD14C\uACE0\uB9AC\uBCC4:"));
1727
+ console.log(chalk3.bold("\n\uCE74\uD14C\uACE0\uB9AC\uBCC4:"));
1487
1728
  for (const [category, count] of Object.entries(index.stats.byCategory)) {
1488
- console.log(` ${chalk2.cyan(category.padEnd(15))} ${count}\uAC1C`);
1729
+ console.log(` ${chalk3.cyan(category.padEnd(15))} ${count}\uAC1C`);
1489
1730
  }
1490
- console.log(chalk2.bold("\n\uC778\uAE30 \uD0DC\uADF8:"));
1731
+ console.log(chalk3.bold("\n\uC778\uAE30 \uD0DC\uADF8:"));
1491
1732
  const topTags = index.tags.slice(0, 10);
1492
1733
  for (const tag of topTags) {
1493
- console.log(` ${chalk2.cyan(tag.name.padEnd(15))} ${tag.count}\uAC1C`);
1734
+ console.log(` ${chalk3.cyan(tag.name.padEnd(15))} ${tag.count}\uAC1C`);
1494
1735
  }
1495
1736
  console.log();
1496
1737
  }
@@ -1498,61 +1739,61 @@ var LibraryCurator = class {
1498
1739
  var libraryCurator = new LibraryCurator();
1499
1740
 
1500
1741
  // src/template/index.ts
1501
- import chalk7 from "chalk";
1742
+ import chalk8 from "chalk";
1502
1743
  import ora5 from "ora";
1503
1744
 
1504
1745
  // src/template/template-apply.ts
1505
- import fs7 from "fs-extra";
1506
- import path7 from "path";
1507
- import chalk4 from "chalk";
1746
+ import fs8 from "fs-extra";
1747
+ import path8 from "path";
1748
+ import chalk5 from "chalk";
1508
1749
  import ora3 from "ora";
1509
1750
  import prompts from "prompts";
1510
1751
 
1511
1752
  // src/template/post-install.ts
1512
- import fs5 from "fs-extra";
1513
- import path5 from "path";
1514
- import chalk3 from "chalk";
1753
+ import fs6 from "fs-extra";
1754
+ import path6 from "path";
1755
+ import chalk4 from "chalk";
1515
1756
  async function runPostInstall(patches, baseDir, dryRun = false) {
1516
1757
  for (const patch of patches) {
1517
- const filePath = path5.resolve(baseDir, patch.file);
1758
+ const filePath = path6.resolve(baseDir, patch.file);
1518
1759
  if (dryRun) {
1519
- console.log(chalk3.gray(` [dry-run] patch ${patch.type}: ${patch.file}`));
1760
+ console.log(chalk4.gray(` [dry-run] patch ${patch.type}: ${patch.file}`));
1520
1761
  continue;
1521
1762
  }
1522
- if (!await fs5.pathExists(filePath)) {
1523
- 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}`));
1524
1765
  continue;
1525
1766
  }
1526
1767
  switch (patch.type) {
1527
1768
  case "replace": {
1528
1769
  if (!patch.search || patch.value === void 0) break;
1529
- let content = await fs5.readFile(filePath, "utf-8");
1770
+ let content = await fs6.readFile(filePath, "utf-8");
1530
1771
  content = content.replace(patch.search, patch.value);
1531
- await fs5.writeFile(filePath, content);
1532
- console.log(chalk3.gray(` patch replace: ${patch.file}`));
1772
+ await fs6.writeFile(filePath, content);
1773
+ console.log(chalk4.gray(` patch replace: ${patch.file}`));
1533
1774
  break;
1534
1775
  }
1535
1776
  case "append": {
1536
1777
  if (patch.value === void 0) break;
1537
- const content = await fs5.readFile(filePath, "utf-8");
1538
- await fs5.writeFile(filePath, content + patch.value);
1539
- 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}`));
1540
1781
  break;
1541
1782
  }
1542
1783
  case "prepend": {
1543
1784
  if (patch.value === void 0) break;
1544
- const content = await fs5.readFile(filePath, "utf-8");
1545
- await fs5.writeFile(filePath, patch.value + content);
1546
- 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}`));
1547
1788
  break;
1548
1789
  }
1549
1790
  case "json-merge": {
1550
1791
  if (!patch.merge) break;
1551
- const raw = await fs5.readFile(filePath, "utf-8");
1792
+ const raw = await fs6.readFile(filePath, "utf-8");
1552
1793
  const json = JSON.parse(raw);
1553
1794
  deepMerge(json, patch.merge);
1554
- await fs5.writeJSON(filePath, json, { spaces: 2 });
1555
- 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}`));
1556
1797
  break;
1557
1798
  }
1558
1799
  }
@@ -1570,9 +1811,9 @@ function deepMerge(target, source) {
1570
1811
  }
1571
1812
  }
1572
1813
 
1573
- // src/config/axis-config.ts
1574
- import fs6 from "fs-extra";
1575
- import path6 from "path";
1814
+ // ../axis-registry-core/src/config/axis-config.ts
1815
+ import fs7 from "fs-extra";
1816
+ import path7 from "path";
1576
1817
  var AXIS_CONFIG_SCHEMA_URL = `${AXIS_SITE_URL}/schema.json`;
1577
1818
  var AXIS_CONFIG_FILE = "axis.config.json";
1578
1819
  function createInitConfig(answers, registry) {
@@ -1595,9 +1836,9 @@ function createTemplateConfig(template) {
1595
1836
  };
1596
1837
  }
1597
1838
  async function readAxisConfig(baseDir) {
1598
- const configPath = path6.join(baseDir, AXIS_CONFIG_FILE);
1599
- if (!await fs6.pathExists(configPath)) return null;
1600
- 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);
1601
1842
  }
1602
1843
 
1603
1844
  // src/template/template-apply.ts
@@ -1611,19 +1852,19 @@ async function applyTemplate(slug, options) {
1611
1852
  spinner.fail(err.message);
1612
1853
  process.exit(1);
1613
1854
  }
1614
- const baseDir = path7.resolve(options.dir || ".");
1855
+ const baseDir = path8.resolve(options.dir || ".");
1615
1856
  const conflicts = [];
1616
1857
  for (const file of detail.files) {
1617
- const dest = path7.join(baseDir, file.path);
1618
- if (await fs7.pathExists(dest)) {
1858
+ const dest = path8.join(baseDir, file.path);
1859
+ if (await fs8.pathExists(dest)) {
1619
1860
  conflicts.push(file.path);
1620
1861
  }
1621
1862
  }
1622
1863
  if (conflicts.length > 0 && !options.yes && !options.dryRun) {
1623
- console.log(chalk4.yellow(`
1864
+ console.log(chalk5.yellow(`
1624
1865
  \uAE30\uC874 \uD30C\uC77C\uACFC \uCDA9\uB3CC\uD558\uB294 ${conflicts.length}\uAC1C \uD30C\uC77C:`));
1625
1866
  for (const c of conflicts) {
1626
- console.log(chalk4.gray(` - ${c}`));
1867
+ console.log(chalk5.gray(` - ${c}`));
1627
1868
  }
1628
1869
  const { proceed } = await prompts({
1629
1870
  type: "confirm",
@@ -1632,59 +1873,59 @@ async function applyTemplate(slug, options) {
1632
1873
  initial: false
1633
1874
  });
1634
1875
  if (!proceed) {
1635
- console.log(chalk4.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1876
+ console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1636
1877
  return;
1637
1878
  }
1638
1879
  }
1639
1880
  if (options.dryRun) {
1640
- 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:"));
1641
1882
  for (const file of detail.files) {
1642
- const dest = path7.join(baseDir, file.path);
1883
+ const dest = path8.join(baseDir, file.path);
1643
1884
  const exists = conflicts.includes(file.path);
1644
- 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");
1645
1886
  console.log(` ${label} ${dest}`);
1646
1887
  }
1647
1888
  if (detail.postInstall?.length) {
1648
- 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:"));
1649
1890
  for (const p of detail.postInstall) {
1650
- console.log(chalk4.gray(` ${p.type}: ${p.file}`));
1891
+ console.log(chalk5.gray(` ${p.type}: ${p.file}`));
1651
1892
  }
1652
1893
  }
1653
1894
  return;
1654
1895
  }
1655
1896
  const writeSpinner = ora3("\uD30C\uC77C \uC0DD\uC131 \uC911...").start();
1656
1897
  for (const file of detail.files) {
1657
- const dest = path7.join(baseDir, file.path);
1658
- await fs7.ensureDir(path7.dirname(dest));
1659
- 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);
1660
1901
  }
1661
1902
  writeSpinner.succeed(`${detail.files.length}\uAC1C \uD30C\uC77C \uC0DD\uC131 \uC644\uB8CC`);
1662
1903
  if (detail.postInstall?.length) {
1663
- console.log(chalk4.blue("\npostInstall \uD328\uCE58 \uC2E4\uD589 \uC911..."));
1904
+ console.log(chalk5.blue("\npostInstall \uD328\uCE58 \uC2E4\uD589 \uC911..."));
1664
1905
  await runPostInstall(detail.postInstall, baseDir);
1665
1906
  }
1666
1907
  if (!options.skipDeps) {
1667
1908
  const allDeps = { ...detail.dependencies, ...detail.devDependencies };
1668
1909
  const depList = Object.entries(allDeps);
1669
1910
  if (depList.length > 0) {
1670
- console.log(chalk4.yellow("\n\uD544\uC694\uD55C \uC758\uC874\uC131:"));
1911
+ console.log(chalk5.yellow("\n\uD544\uC694\uD55C \uC758\uC874\uC131:"));
1671
1912
  const deps = Object.entries(detail.dependencies || {}).map(([k, v]) => `${k}@${v}`).join(" ");
1672
1913
  const devDeps = Object.entries(detail.devDependencies || {}).map(([k, v]) => `${k}@${v}`).join(" ");
1673
1914
  if (deps) {
1674
- console.log(chalk4.cyan(` pnpm add ${deps}`));
1915
+ console.log(chalk5.cyan(` pnpm add ${deps}`));
1675
1916
  }
1676
1917
  if (devDeps) {
1677
- console.log(chalk4.cyan(` pnpm add -D ${devDeps}`));
1918
+ console.log(chalk5.cyan(` pnpm add -D ${devDeps}`));
1678
1919
  }
1679
1920
  }
1680
1921
  }
1681
- console.log(chalk4.green(`
1922
+ console.log(chalk5.green(`
1682
1923
  '${detail.name}' \uD15C\uD50C\uB9BF \uC801\uC6A9 \uC644\uB8CC!`));
1683
1924
  }
1684
1925
  async function initTemplate(slug, options) {
1685
1926
  let selectedSlug = slug;
1686
1927
  if (!selectedSlug) {
1687
- const { fetchTemplateIndex: fetchTemplateIndex2 } = await import("./registry-client-BJ2XYT73.js");
1928
+ const { fetchTemplateIndex: fetchTemplateIndex2 } = await import("./registry-client-6WSGKPF2.js");
1688
1929
  const index = await fetchTemplateIndex2();
1689
1930
  const { choice } = await prompts({
1690
1931
  type: "select",
@@ -1697,7 +1938,7 @@ async function initTemplate(slug, options) {
1697
1938
  }))
1698
1939
  });
1699
1940
  if (!choice) {
1700
- console.log(chalk4.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1941
+ console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1701
1942
  return;
1702
1943
  }
1703
1944
  selectedSlug = choice;
@@ -1711,14 +1952,14 @@ async function initTemplate(slug, options) {
1711
1952
  initial: selectedSlug
1712
1953
  });
1713
1954
  if (!dir) {
1714
- console.log(chalk4.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1955
+ console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
1715
1956
  return;
1716
1957
  }
1717
1958
  targetDir = dir;
1718
1959
  }
1719
- const resolved = path7.resolve(targetDir);
1720
- if (await fs7.pathExists(resolved)) {
1721
- 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);
1722
1963
  if (entries.length > 0) {
1723
1964
  const { proceed } = await prompts({
1724
1965
  type: "confirm",
@@ -1729,26 +1970,26 @@ async function initTemplate(slug, options) {
1729
1970
  if (!proceed) return;
1730
1971
  }
1731
1972
  } else {
1732
- await fs7.ensureDir(resolved);
1973
+ await fs8.ensureDir(resolved);
1733
1974
  }
1734
1975
  await applyTemplate(selectedSlug, { dir: targetDir, yes: true });
1735
- const configPath = path7.join(resolved, "axis.config.json");
1736
- if (!await fs7.pathExists(configPath)) {
1976
+ const configPath = path8.join(resolved, "axis.config.json");
1977
+ if (!await fs8.pathExists(configPath)) {
1737
1978
  const axisConfig = createTemplateConfig(selectedSlug);
1738
- await fs7.writeJSON(configPath, axisConfig, { spaces: 2 });
1739
- 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"));
1740
1981
  }
1741
- console.log(chalk4.blue(`
1982
+ console.log(chalk5.blue(`
1742
1983
  \uB2E4\uC74C \uB2E8\uACC4:`));
1743
- console.log(chalk4.cyan(` cd ${targetDir}`));
1744
- console.log(chalk4.cyan(` pnpm install`));
1745
- 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`));
1746
1987
  }
1747
1988
 
1748
1989
  // src/template/template-diff.ts
1749
- import fs8 from "fs-extra";
1750
- import path8 from "path";
1751
- import chalk5 from "chalk";
1990
+ import fs9 from "fs-extra";
1991
+ import path9 from "path";
1992
+ import chalk6 from "chalk";
1752
1993
  import ora4 from "ora";
1753
1994
  async function diffTemplate(slug, options) {
1754
1995
  const spinner = ora4(`'${slug}' \uD15C\uD50C\uB9BF \uAC00\uC838\uC624\uB294 \uC911...`).start();
@@ -1760,15 +2001,15 @@ async function diffTemplate(slug, options) {
1760
2001
  spinner.fail(err.message);
1761
2002
  process.exit(1);
1762
2003
  }
1763
- const baseDir = path8.resolve(options.dir || ".");
2004
+ const baseDir = path9.resolve(options.dir || ".");
1764
2005
  const entries = [];
1765
2006
  for (const file of detail.files) {
1766
- const localPath = path8.join(baseDir, file.path);
1767
- if (!await fs8.pathExists(localPath)) {
2007
+ const localPath = path9.join(baseDir, file.path);
2008
+ if (!await fs9.pathExists(localPath)) {
1768
2009
  entries.push({ path: file.path, status: "added" });
1769
2010
  continue;
1770
2011
  }
1771
- const localContent = await fs8.readFile(localPath, "utf-8");
2012
+ const localContent = await fs9.readFile(localPath, "utf-8");
1772
2013
  if (localContent === file.content) {
1773
2014
  entries.push({ path: file.path, status: "unchanged" });
1774
2015
  } else {
@@ -1789,14 +2030,14 @@ async function diffTemplate(slug, options) {
1789
2030
  }
1790
2031
  }
1791
2032
  }
1792
- console.log(chalk5.blue(`
2033
+ console.log(chalk6.blue(`
1793
2034
  '${detail.name}' \uD15C\uD50C\uB9BF diff \uACB0\uACFC:
1794
2035
  `));
1795
2036
  const statusIcon = {
1796
- added: chalk5.green("+ \uCD94\uAC00 \uD544\uC694"),
1797
- modified: chalk5.yellow("~ \uBCC0\uACBD\uB428"),
1798
- unchanged: chalk5.gray("= \uB3D9\uC77C"),
1799
- 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")
1800
2041
  };
1801
2042
  let added = 0;
1802
2043
  let modified = 0;
@@ -1807,7 +2048,7 @@ async function diffTemplate(slug, options) {
1807
2048
  console.log(` ${icon.padEnd(28)} ${entry.path}`);
1808
2049
  if (entry.status === "modified" && options.verbose) {
1809
2050
  console.log(
1810
- chalk5.gray(
2051
+ chalk6.gray(
1811
2052
  ` \uB85C\uCEEC ${entry.localLines}\uC904 / \uC6D0\uBCF8 ${entry.remoteLines}\uC904`
1812
2053
  )
1813
2054
  );
@@ -1827,9 +2068,9 @@ async function diffTemplate(slug, options) {
1827
2068
  break;
1828
2069
  }
1829
2070
  }
1830
- console.log(chalk5.blue("\n\uC694\uC57D:"));
2071
+ console.log(chalk6.blue("\n\uC694\uC57D:"));
1831
2072
  console.log(
1832
- ` \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))}` : ""}`
1833
2074
  );
1834
2075
  }
1835
2076
  async function collectLocalFiles(dir, base) {
@@ -1838,27 +2079,27 @@ async function collectLocalFiles(dir, base) {
1838
2079
  const results = [];
1839
2080
  let entries;
1840
2081
  try {
1841
- entries = await fs8.readdir(dir, { withFileTypes: true });
2082
+ entries = await fs9.readdir(dir, { withFileTypes: true });
1842
2083
  } catch {
1843
2084
  return results;
1844
2085
  }
1845
2086
  for (const entry of entries) {
1846
2087
  if (ignore.has(entry.name)) continue;
1847
- const fullPath = path8.join(dir, entry.name);
2088
+ const fullPath = path9.join(dir, entry.name);
1848
2089
  if (entry.isDirectory()) {
1849
2090
  const nested = await collectLocalFiles(fullPath, root);
1850
2091
  results.push(...nested);
1851
2092
  } else {
1852
- results.push(path8.relative(root, fullPath).replace(/\\/g, "/"));
2093
+ results.push(path9.relative(root, fullPath).replace(/\\/g, "/"));
1853
2094
  }
1854
2095
  }
1855
2096
  return results;
1856
2097
  }
1857
2098
 
1858
2099
  // src/template/template-check.ts
1859
- import fs9 from "fs-extra";
1860
- import path9 from "path";
1861
- import chalk6 from "chalk";
2100
+ import fs10 from "fs-extra";
2101
+ import path10 from "path";
2102
+ import chalk7 from "chalk";
1862
2103
 
1863
2104
  // src/theme/brand-core.ts
1864
2105
  import { existsSync, readFileSync, statSync } from "fs";
@@ -2104,7 +2345,7 @@ function getBrand(baseDir, name) {
2104
2345
  };
2105
2346
  }
2106
2347
 
2107
- // src/template/tailwind-core.ts
2348
+ // ../axis-registry-core/src/template/tailwind-core.ts
2108
2349
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
2109
2350
  import { join as join2, resolve as resolve2 } from "path";
2110
2351
  function hasDependency(pkg, name) {
@@ -2525,9 +2766,9 @@ function checkTailwindSetup(baseDirInput) {
2525
2766
  return { name: "tailwind.config", severity: "warn", message: "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070 \uC124\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4" };
2526
2767
  }
2527
2768
  for (const file of otherFiles) {
2528
- const path16 = join2(baseDir, file);
2529
- if (existsSync2(path16)) {
2530
- if (hasTokensPresetReference(readFileSync2(path16, "utf8"))) {
2769
+ const path18 = join2(baseDir, file);
2770
+ if (existsSync2(path18)) {
2771
+ if (hasTokensPresetReference(readFileSync2(path18, "utf8"))) {
2531
2772
  return { name: "tailwind.config", severity: "pass", message: `${file}${PRESET_PASS_SUFFIX}` };
2532
2773
  }
2533
2774
  return { name: "tailwind.config", severity: "warn", message: `${file} \uC874\uC7AC (TypeScript \uAD8C\uC7A5)` };
@@ -2538,12 +2779,12 @@ function checkTailwindSetup(baseDirInput) {
2538
2779
 
2539
2780
  // src/template/template-check.ts
2540
2781
  var SEVERITY_ICON = {
2541
- pass: chalk6.green("PASS"),
2542
- warn: chalk6.yellow("WARN"),
2543
- fail: chalk6.red("FAIL")
2782
+ pass: chalk7.green("PASS"),
2783
+ warn: chalk7.yellow("WARN"),
2784
+ fail: chalk7.red("FAIL")
2544
2785
  };
2545
2786
  async function collectCheckResults(dir) {
2546
- const baseDir = path9.resolve(dir || ".");
2787
+ const baseDir = path10.resolve(dir || ".");
2547
2788
  const results = [];
2548
2789
  results.push(await checkFileExists(baseDir, "axis.config.json", "axis.config.json"));
2549
2790
  results.push(checkTailwindSetup(baseDir));
@@ -2556,7 +2797,7 @@ async function collectCheckResults(dir) {
2556
2797
  }
2557
2798
  async function runCheck(dir) {
2558
2799
  const results = await collectCheckResults(dir);
2559
- 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"));
2560
2801
  let passCount = 0;
2561
2802
  let warnCount = 0;
2562
2803
  let failCount = 0;
@@ -2576,19 +2817,19 @@ async function runCheck(dir) {
2576
2817
  }
2577
2818
  console.log();
2578
2819
  console.log(
2579
- ` \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`)}`
2580
2821
  );
2581
2822
  if (failCount > 0) {
2582
- 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."));
2583
2824
  } else if (warnCount > 0) {
2584
- 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."));
2585
2826
  } else {
2586
- 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!"));
2587
2828
  }
2588
2829
  return { pass: passCount, warn: warnCount, fail: failCount };
2589
2830
  }
2590
2831
  async function checkFileExists(baseDir, fileName, label) {
2591
- const exists = await fs9.pathExists(path9.join(baseDir, fileName));
2832
+ const exists = await fs10.pathExists(path10.join(baseDir, fileName));
2592
2833
  return {
2593
2834
  name: label,
2594
2835
  severity: exists ? "pass" : "fail",
@@ -2604,9 +2845,9 @@ async function checkUtils(baseDir) {
2604
2845
  "utils.ts"
2605
2846
  ];
2606
2847
  for (const candidate of candidates) {
2607
- const fullPath = path9.join(baseDir, candidate);
2608
- if (await fs9.pathExists(fullPath)) {
2609
- 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");
2610
2851
  const hasCn = content.includes("function cn");
2611
2852
  return {
2612
2853
  name: "utils.ts",
@@ -2622,15 +2863,15 @@ async function checkUtils(baseDir) {
2622
2863
  };
2623
2864
  }
2624
2865
  async function checkDependencies(baseDir) {
2625
- const pkgPath = path9.join(baseDir, "package.json");
2626
- if (!await fs9.pathExists(pkgPath)) {
2866
+ const pkgPath = path10.join(baseDir, "package.json");
2867
+ if (!await fs10.pathExists(pkgPath)) {
2627
2868
  return {
2628
2869
  name: "package.json",
2629
2870
  severity: "fail",
2630
2871
  message: "package.json \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
2631
2872
  };
2632
2873
  }
2633
- const pkg = await fs9.readJSON(pkgPath);
2874
+ const pkg = await fs10.readJSON(pkgPath);
2634
2875
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
2635
2876
  const required = ["tailwindcss"];
2636
2877
  const recommended = ["clsx", "tailwind-merge"];
@@ -2704,10 +2945,10 @@ function registerTemplateCommand(program2) {
2704
2945
  templates = templates.filter((t) => t.category === options.category);
2705
2946
  }
2706
2947
  if (templates.length === 0) {
2707
- 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"));
2708
2949
  return;
2709
2950
  }
2710
- console.log(chalk7.blue(`
2951
+ console.log(chalk8.blue(`
2711
2952
  \u{1F4E6} AXIS \uD15C\uD50C\uB9BF (${templates.length}\uAC1C)
2712
2953
  `));
2713
2954
  const byCategory = /* @__PURE__ */ new Map();
@@ -2718,16 +2959,16 @@ function registerTemplateCommand(program2) {
2718
2959
  byCategory.get(t.category).push(t);
2719
2960
  }
2720
2961
  for (const [category, items] of byCategory) {
2721
- console.log(chalk7.bold(` ${category}`));
2962
+ console.log(chalk8.bold(` ${category}`));
2722
2963
  for (const t of items) {
2723
2964
  console.log(
2724
- ` ${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))}`
2725
2966
  );
2726
2967
  }
2727
2968
  console.log();
2728
2969
  }
2729
- console.log(chalk7.gray("\uC0AC\uC6A9\uBC95: axis template info <name>"));
2730
- 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"));
2731
2972
  } catch (err) {
2732
2973
  spinner.fail(err.message);
2733
2974
  process.exit(1);
@@ -2738,30 +2979,30 @@ function registerTemplateCommand(program2) {
2738
2979
  try {
2739
2980
  const detail = await fetchTemplateDetail(name);
2740
2981
  spinner.stop();
2741
- console.log(chalk7.blue(`
2982
+ console.log(chalk8.blue(`
2742
2983
  \u{1F4CB} ${detail.name}
2743
2984
  `));
2744
- console.log(` ${chalk7.bold("\uC124\uBA85")}: ${detail.description}`);
2745
- console.log(` ${chalk7.bold("\uCE74\uD14C\uACE0\uB9AC")}: ${detail.category}`);
2746
- 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}`);
2747
2988
  if (detail.tags.length > 0) {
2748
- console.log(` ${chalk7.bold("\uD0DC\uADF8")}: ${detail.tags.join(", ")}`);
2989
+ console.log(` ${chalk8.bold("\uD0DC\uADF8")}: ${detail.tags.join(", ")}`);
2749
2990
  }
2750
2991
  if (detail.features.length > 0) {
2751
- console.log(chalk7.bold("\n \uAE30\uB2A5:"));
2992
+ console.log(chalk8.bold("\n \uAE30\uB2A5:"));
2752
2993
  for (const f of detail.features) {
2753
2994
  console.log(` - ${f}`);
2754
2995
  }
2755
2996
  }
2756
- console.log(chalk7.bold(`
2997
+ console.log(chalk8.bold(`
2757
2998
  \uD30C\uC77C (${detail.files.length}\uAC1C):`));
2758
2999
  for (const f of detail.files) {
2759
- console.log(` ${chalk7.cyan(f.path)} ${chalk7.gray(`(${f.type})`)}`);
3000
+ console.log(` ${chalk8.cyan(f.path)} ${chalk8.gray(`(${f.type})`)}`);
2760
3001
  }
2761
3002
  const deps = Object.keys(detail.dependencies || {});
2762
3003
  const devDeps = Object.keys(detail.devDependencies || {});
2763
3004
  if (deps.length > 0 || devDeps.length > 0) {
2764
- console.log(chalk7.bold("\n \uC758\uC874\uC131:"));
3005
+ console.log(chalk8.bold("\n \uC758\uC874\uC131:"));
2765
3006
  if (deps.length > 0) {
2766
3007
  console.log(` dependencies: ${deps.join(", ")}`);
2767
3008
  }
@@ -2769,7 +3010,7 @@ function registerTemplateCommand(program2) {
2769
3010
  console.log(` devDependencies: ${devDeps.join(", ")}`);
2770
3011
  }
2771
3012
  }
2772
- console.log(chalk7.gray(`
3013
+ console.log(chalk8.gray(`
2773
3014
  \uC0AC\uC6A9\uBC95: axis template apply ${name}
2774
3015
  `));
2775
3016
  } catch (err) {
@@ -2795,16 +3036,40 @@ function registerCheckCommand(program2) {
2795
3036
  }
2796
3037
 
2797
3038
  // src/theme/index.ts
2798
- 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";
2799
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
+ }
2800
3067
 
2801
3068
  // src/theme/theme-add.ts
2802
- import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync3, realpathSync, unlinkSync, writeFileSync } from "fs";
2803
- import path10 from "path";
2804
3069
  var TOKENS_DEPENDENCY_RANGE = `^${MIN_BRAND_TOKENS_VERSION}`;
2805
3070
  var THEME_PACKAGE = "@axis-ds/theme";
2806
3071
  function readText(file) {
2807
- return existsSync3(file) ? readFileSync3(file, "utf8") : null;
3072
+ return existsSync4(file) ? readFileSync3(file, "utf8") : null;
2808
3073
  }
2809
3074
  function eolOf(text) {
2810
3075
  return text.includes("\r\n") ? "\r\n" : "\n";
@@ -2872,33 +3137,15 @@ function compareVersions(a, b) {
2872
3137
  function realPathInside(baseDir, file) {
2873
3138
  const realBase = realpathSync(baseDir);
2874
3139
  const realPath = realpathSync(file);
2875
- const relPath = path10.relative(realBase, realPath);
2876
- const inside = relPath !== "" && !relPath.startsWith("..") && !path10.isAbsolute(relPath);
3140
+ const relPath = path12.relative(realBase, realPath);
3141
+ const inside = relPath !== "" && !relPath.startsWith("..") && !path12.isAbsolute(relPath);
2877
3142
  return { inside, realPath };
2878
3143
  }
2879
3144
  function isStylesheet(realPath) {
2880
- return path10.extname(realPath).toLowerCase() === ".css";
2881
- }
2882
- function detectInstallCommand(baseDir) {
2883
- if (existsSync3(path10.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
2884
- if (existsSync3(path10.join(baseDir, "yarn.lock"))) return "yarn install";
2885
- if (existsSync3(path10.join(baseDir, "package-lock.json"))) return "npm install";
2886
- return "pnpm install";
2887
- }
2888
- function hasDependency2(pkg, name) {
2889
- for (const field of ["dependencies", "devDependencies"]) {
2890
- const deps = pkg[field];
2891
- if (typeof deps === "object" && deps !== null && name in deps) {
2892
- return String(deps[name]);
2893
- }
2894
- }
2895
- return void 0;
2896
- }
2897
- function isPlainObject2(value) {
2898
- return typeof value === "object" && value !== null && !Array.isArray(value);
3145
+ return path12.extname(realPath).toLowerCase() === ".css";
2899
3146
  }
2900
3147
  function planThemeAdd(baseDirInput, brand) {
2901
- const baseDir = path10.resolve(baseDirInput);
3148
+ const baseDir = path12.resolve(baseDirInput);
2902
3149
  const plan = {
2903
3150
  baseDir,
2904
3151
  brand,
@@ -2910,7 +3157,7 @@ function planThemeAdd(baseDirInput, brand) {
2910
3157
  installCommand: detectInstallCommand(baseDir),
2911
3158
  writes: []
2912
3159
  };
2913
- const configFile = path10.join(baseDir, AXIS_CONFIG_FILE);
3160
+ const configFile = path12.join(baseDir, AXIS_CONFIG_FILE);
2914
3161
  const configText = readText(configFile);
2915
3162
  if (configText === null) {
2916
3163
  plan.errors.push({ kind: "no-config" });
@@ -2976,7 +3223,7 @@ function planThemeAdd(baseDirInput, brand) {
2976
3223
  } else {
2977
3224
  plan.css = { configuredMissing: location.configuredMissing, action: "manual", otherBrands: [] };
2978
3225
  }
2979
- const pkgFile = path10.join(baseDir, "package.json");
3226
+ const pkgFile = path12.join(baseDir, "package.json");
2980
3227
  const pkgText = readText(pkgFile);
2981
3228
  const installed = plan.tokens.version;
2982
3229
  const upgrade = installed !== void 0 && (compareVersions(installed, MIN_BRAND_TOKENS_VERSION) ?? 0) < 0;
@@ -3036,8 +3283,8 @@ function applyThemeAdd(plan) {
3036
3283
  if (current !== w.before) {
3037
3284
  throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
3038
3285
  }
3039
- const where = realPathInside(plan.baseDir, w.before === null ? path10.dirname(w.file) : w.file);
3040
- 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)) {
3041
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.`);
3042
3289
  }
3043
3290
  if (!w.file.endsWith(".json") && !isStylesheet(where.realPath)) {
@@ -3049,7 +3296,7 @@ function applyThemeAdd(plan) {
3049
3296
  throw new Error(`${w.file}: \uBE0C\uB79C\uB4DC import \uAC00 \uC815\uD655\uD788 1\uC904\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
3050
3297
  }
3051
3298
  try {
3052
- 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);
3053
3300
  } catch (err) {
3054
3301
  throw new Error(`${w.file} \uC5D0 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errorMessage(err)}).`);
3055
3302
  }
@@ -3088,22 +3335,22 @@ function tokensStatusGuide(status, version) {
3088
3335
  switch (status) {
3089
3336
  case "not-installed":
3090
3337
  return [
3091
- chalk8.yellow(`${TOKENS_PACKAGE} \uAC00 \uC124\uCE58\uB3FC \uC788\uC9C0 \uC54A\uC544 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`),
3092
- ` \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)}`
3093
3340
  ];
3094
3341
  case "unsupported":
3095
3342
  return [
3096
- chalk8.yellow(
3343
+ chalk9.yellow(
3097
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).`
3098
3345
  ),
3099
- ` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk8.cyan(TOKENS_INSTALL_COMMAND)}`
3346
+ ` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
3100
3347
  ];
3101
3348
  case "not-built":
3102
3349
  return [
3103
- chalk8.yellow(
3350
+ chalk9.yellow(
3104
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.`
3105
3352
  ),
3106
- ` \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)}`
3107
3354
  ];
3108
3355
  }
3109
3356
  }
@@ -3113,22 +3360,22 @@ function renderThemeList(result) {
3113
3360
  }
3114
3361
  if (result.brands.length === 0) {
3115
3362
  return {
3116
- 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.`), ""],
3117
3364
  exitCode: 0
3118
3365
  };
3119
3366
  }
3120
3367
  const width = Math.max(...result.brands.map((b) => b.name.length));
3121
3368
  const lines = [
3122
3369
  "",
3123
- 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 ?? ""})`),
3124
3371
  ""
3125
3372
  ];
3126
3373
  for (const b of result.brands) {
3127
3374
  lines.push(
3128
- ` ${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 ")})`)}`
3129
3376
  );
3130
3377
  }
3131
- lines.push("", chalk8.gray("\uC0AC\uC6A9\uBC95: axis theme info <brand>"), "");
3378
+ lines.push("", chalk9.gray("\uC0AC\uC6A9\uBC95: axis theme info <brand>"), "");
3132
3379
  return { lines, exitCode: 0 };
3133
3380
  }
3134
3381
  function a11yValue(value) {
@@ -3144,13 +3391,13 @@ function tokenTable(brand) {
3144
3391
  const header = ["\uD1A0\uD070", "\uB77C\uC774\uD2B8", "\uB2E4\uD06C"];
3145
3392
  const w0 = Math.max(header[0].length, ...rows.map((r) => r[0].length));
3146
3393
  const w1 = Math.max(header[1].length, ...rows.map((r) => r[1].length));
3147
- 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]}`));
3148
3395
  for (const [k, l, d] of rows) {
3149
3396
  lines.push(` ${k.padEnd(w0)} ${l.padEnd(w1)} ${d}`);
3150
3397
  }
3151
3398
  }
3152
3399
  if (missing.length > 0) {
3153
- 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(", ")}`));
3154
3401
  }
3155
3402
  return lines;
3156
3403
  }
@@ -3163,9 +3410,9 @@ function renderThemeInfo(result, name) {
3163
3410
  return {
3164
3411
  lines: [
3165
3412
  "",
3166
- 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.`),
3167
3414
  ` \uC124\uCE58\uB41C \uBE0C\uB79C\uB4DC: ${result.available.length > 0 ? result.available.join(", ") : "(\uC5C6\uC74C)"}`,
3168
- chalk8.gray(" \uBAA9\uB85D: axis theme list"),
3415
+ chalk9.gray(" \uBAA9\uB85D: axis theme list"),
3169
3416
  ""
3170
3417
  ],
3171
3418
  exitCode: 1
@@ -3173,34 +3420,34 @@ function renderThemeInfo(result, name) {
3173
3420
  }
3174
3421
  const lines = [
3175
3422
  "",
3176
- chalk8.blue(`\uBE0C\uB79C\uB4DC ${brand.name}`),
3423
+ chalk9.blue(`\uBE0C\uB79C\uB4DC ${brand.name}`),
3177
3424
  ` \uC124\uBA85: ${brand.description}`,
3178
3425
  ` \uD14C\uB9C8: ${brand.themes.join(" \xB7 ")}`,
3179
3426
  "",
3180
- 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)"),
3181
3428
  ` @import "${brand.importPath}";`,
3182
3429
  "",
3183
- chalk8.bold("Provider (@axis-ds/theme 1.3.0 \uC774\uC0C1)"),
3430
+ chalk9.bold("Provider (@axis-ds/theme 1.3.0 \uC774\uC0C1)"),
3184
3431
  ...brand.providerExample.split("\n").map((l) => l ? ` ${l}` : ""),
3185
- chalk8.gray(
3432
+ chalk9.gray(
3186
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.`
3187
3434
  ),
3188
3435
  "",
3189
- chalk8.bold("\uC8FC\uC694 \uD1A0\uD070"),
3436
+ chalk9.bold("\uC8FC\uC694 \uD1A0\uD070"),
3190
3437
  ...tokenTable(brand),
3191
3438
  "",
3192
- chalk8.bold("\uBCF4\uC815 \uB0B4\uC5ED"),
3439
+ chalk9.bold("\uBCF4\uC815 \uB0B4\uC5ED"),
3193
3440
  ` a11y \uC0C1\uD0DC: ${a11yValue(brand.adjustments.a11y.status)}`,
3194
3441
  ` \uC810\uAC80\uC77C: ${a11yValue(brand.adjustments.a11y.checkedAt)}`,
3195
3442
  ` \uAC8C\uC774\uD2B8: ${a11yValue(brand.adjustments.a11y.gate)}`,
3196
3443
  ` \uADFC\uAC70 \uBB38\uC11C: ${brand.adjustments.reference}`,
3197
- 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."),
3198
3445
  ""
3199
3446
  ];
3200
3447
  return { lines, exitCode: 0 };
3201
3448
  }
3202
3449
  function rel(plan, file) {
3203
- return path11.relative(plan.baseDir, file) || file;
3450
+ return path13.relative(plan.baseDir, file) || file;
3204
3451
  }
3205
3452
  function renderThemeAdd(plan, written) {
3206
3453
  const error = plan.errors[0];
@@ -3209,24 +3456,24 @@ function renderThemeAdd(plan, written) {
3209
3456
  switch (error.kind) {
3210
3457
  case "no-config":
3211
3458
  lines2.push(
3212
- chalk8.red("axis.config.json \uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."),
3213
- ` \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.`
3214
3461
  );
3215
3462
  break;
3216
3463
  case "invalid-config":
3217
- 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.`));
3218
3465
  break;
3219
3466
  case "invalid-package-json":
3220
- 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.`));
3221
3468
  break;
3222
3469
  case "invalid-name":
3223
3470
  lines2.push(
3224
- 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.`)
3225
3472
  );
3226
3473
  break;
3227
3474
  case "css-outside-project":
3228
3475
  lines2.push(
3229
- chalk8.red(
3476
+ chalk9.red(
3230
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.`
3231
3478
  ),
3232
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}";`
@@ -3234,25 +3481,25 @@ function renderThemeAdd(plan, written) {
3234
3481
  break;
3235
3482
  case "css-not-stylesheet":
3236
3483
  lines2.push(
3237
- 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.`),
3238
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}";`
3239
3486
  );
3240
3487
  break;
3241
3488
  case "unknown-brand":
3242
3489
  lines2.push(
3243
- 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.`),
3244
3491
  ` \uC124\uCE58\uB41C \uBE0C\uB79C\uB4DC: ${error.available.length > 0 ? error.available.join(", ") : "(\uC5C6\uC74C)"}`,
3245
- chalk8.gray(" \uBAA9\uB85D: axis theme list")
3492
+ chalk9.gray(" \uBAA9\uB85D: axis theme list")
3246
3493
  );
3247
3494
  break;
3248
3495
  }
3249
3496
  lines2.push("");
3250
3497
  return { lines: lines2, exitCode: 1 };
3251
3498
  }
3252
- const lines = ["", chalk8.blue(`\uBE0C\uB79C\uB4DC ${plan.brand} \uC801\uC6A9`), ""];
3499
+ const lines = ["", chalk9.blue(`\uBE0C\uB79C\uB4DC ${plan.brand} \uC801\uC6A9`), ""];
3253
3500
  if (plan.unverifiedBrand) {
3254
3501
  lines.push(
3255
- chalk8.yellow(
3502
+ chalk9.yellow(
3256
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.`
3257
3504
  )
3258
3505
  );
@@ -3260,24 +3507,24 @@ function renderThemeAdd(plan, written) {
3260
3507
  const css = plan.css;
3261
3508
  if (css?.configuredMissing) {
3262
3509
  lines.push(
3263
- chalk8.yellow(
3510
+ chalk9.yellow(
3264
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.`
3265
3512
  )
3266
3513
  );
3267
3514
  }
3268
3515
  if (css?.action === "add" && css.file) {
3269
- 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`);
3270
3517
  } else if (css?.action === "exists" && css.file) {
3271
- 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`);
3272
3519
  } else {
3273
3520
  lines.push(
3274
- 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."),
3275
3522
  ` \uC804\uC5ED CSS \uB9E8 \uC55E(@charset \xB7 \uB2E4\uB978 @import \uB2E4\uC74C)\uC5D0 \uC9C1\uC811 \uB123\uC73C\uC138\uC694: @import "${plan.importPath}";`
3276
3523
  );
3277
3524
  }
3278
3525
  if (css && css.otherBrands.length > 0) {
3279
3526
  lines.push(
3280
- chalk8.yellow(
3527
+ chalk9.yellow(
3281
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.`
3282
3529
  )
3283
3530
  );
@@ -3285,60 +3532,60 @@ function renderThemeAdd(plan, written) {
3285
3532
  const dep = plan.dependency;
3286
3533
  if (dep?.action === "add") {
3287
3534
  lines.push(
3288
- ` ${chalk8.green("\u2713")} package.json: dependencies \uC5D0 "${TOKENS_PACKAGE}": "${TOKENS_DEPENDENCY_RANGE}" \uCD94\uAC00`,
3289
- ` \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)}`
3290
3537
  );
3291
3538
  } else if (dep?.action === "present") {
3292
- 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`);
3293
3540
  } else if (dep?.action === "no-package-json") {
3294
3541
  lines.push(
3295
- 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}`)
3296
3543
  );
3297
3544
  }
3298
3545
  if (dep?.upgrade) {
3299
3546
  lines.push(
3300
- chalk8.yellow(
3547
+ chalk9.yellow(
3301
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).`
3302
3549
  ),
3303
- ` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk8.cyan(TOKENS_INSTALL_COMMAND)}`
3550
+ ` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
3304
3551
  );
3305
3552
  }
3306
3553
  if (plan.configChanged) {
3307
- 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`);
3308
3555
  } else {
3309
- 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}"`);
3310
3557
  }
3311
3558
  lines.push(
3312
3559
  "",
3313
- chalk8.bold(`Provider (${THEME_PACKAGE} 1.3.0 \uC774\uC0C1)`),
3560
+ chalk9.bold(`Provider (${THEME_PACKAGE} 1.3.0 \uC774\uC0C1)`),
3314
3561
  ...providerExample(plan.brand).split("\n").map((l) => l ? ` ${l}` : ""),
3315
- chalk8.gray(
3562
+ chalk9.gray(
3316
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.`
3317
3564
  )
3318
3565
  );
3319
3566
  if (dep?.themeMissing) {
3320
- 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`)}`);
3321
3568
  }
3322
- 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."), "");
3323
3570
  return { lines, exitCode: 0 };
3324
3571
  }
3325
3572
  function renderThemeAddFailure(plan, err) {
3326
3573
  const lines = [""];
3327
3574
  if (err instanceof ThemeApplyError) {
3328
- lines.push(chalk8.red(err.message));
3575
+ lines.push(chalk9.red(err.message));
3329
3576
  if (err.restored.length > 0) {
3330
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(", ")}`);
3331
3578
  }
3332
3579
  if (err.restoreFailed.length > 0) {
3333
3580
  lines.push(
3334
- 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(", ")}`)
3335
3582
  );
3336
3583
  }
3337
3584
  if (err.restored.length === 0 && err.restoreFailed.length === 0) {
3338
3585
  lines.push(" \uBC14\uB010 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
3339
3586
  }
3340
3587
  } else {
3341
- 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.");
3342
3589
  }
3343
3590
  lines.push("");
3344
3591
  return { lines, exitCode: 1 };
@@ -3350,15 +3597,15 @@ function print(output) {
3350
3597
  function registerThemeCommand(program2) {
3351
3598
  const themeCmd = program2.command("theme").description("\uBE0C\uB79C\uB4DC \uD14C\uB9C8 (@axis-ds/tokens \uBE0C\uB79C\uB4DC)");
3352
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) => {
3353
- const baseDir = path11.resolve(options.dir || ".");
3600
+ const baseDir = path13.resolve(options.dir || ".");
3354
3601
  print(renderThemeList(listBrands(baseDir)));
3355
3602
  });
3356
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) => {
3357
- const baseDir = path11.resolve(options.dir || ".");
3604
+ const baseDir = path13.resolve(options.dir || ".");
3358
3605
  print(renderThemeInfo(getBrand(baseDir, name), name));
3359
3606
  });
3360
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) => {
3361
- const baseDir = path11.resolve(options.dir || ".");
3608
+ const baseDir = path13.resolve(options.dir || ".");
3362
3609
  const plan = planThemeAdd(baseDir, name);
3363
3610
  let written = [];
3364
3611
  if (plan.errors.length === 0) {
@@ -3374,10 +3621,10 @@ function registerThemeCommand(program2) {
3374
3621
  }
3375
3622
 
3376
3623
  // src/init/index.ts
3377
- import chalk10 from "chalk";
3624
+ import chalk11 from "chalk";
3378
3625
  import prompts2 from "prompts";
3379
3626
 
3380
- // src/registry/schema.ts
3627
+ // ../axis-registry-core/src/registry/schema.ts
3381
3628
  import { createHash } from "crypto";
3382
3629
  var REGISTRY_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
3383
3630
  var REGISTRY_NAME_MAX_LENGTH = 64;
@@ -3581,7 +3828,7 @@ function checkItemSha256(item, entry, where = `${item.name}.json`) {
3581
3828
  }
3582
3829
  }
3583
3830
 
3584
- // src/registry/remote.ts
3831
+ // ../axis-registry-core/src/registry/remote.ts
3585
3832
  var DEFAULT_REGISTRY_URL = REGISTRY_PUBLIC_BASE_URL;
3586
3833
  var DEFAULT_REGISTRY_TIMEOUT_MS = 5e3;
3587
3834
  var LEGACY_DEFAULT_REGISTRY_URL = "https://axis.minu.best/r";
@@ -3650,10 +3897,18 @@ async function fetchRegistryJson(url, options = {}) {
3650
3897
  try {
3651
3898
  let res;
3652
3899
  try {
3653
- 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
+ });
3654
3905
  } catch (error) {
3655
3906
  throw describe(error);
3656
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
+ }
3657
3912
  if (!res.ok) {
3658
3913
  await res.text().catch(() => void 0);
3659
3914
  throw new RegistryAccessError(`${shown}: HTTP ${res.status}`);
@@ -3670,15 +3925,15 @@ async function fetchRegistryJson(url, options = {}) {
3670
3925
  }
3671
3926
 
3672
3927
  // src/init/init.ts
3673
- 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";
3674
- import path13 from "path";
3675
- import chalk9 from "chalk";
3676
- 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";
3677
3932
 
3678
- // src/add/safe-write.ts
3679
- import { constants as fsConstants, existsSync as existsSync4, lstatSync, realpathSync as realpathSync2, statSync as statSync2 } from "fs";
3680
- import path12 from "path";
3681
- 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";
3682
3937
  var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
3683
3938
  var OVERWRITE_FLAGS = fsConstants.O_WRONLY | (fsConstants.O_NOFOLLOW ?? 0);
3684
3939
  var HARDLINK_ERROR_CODE = "EAXISHARDLINK";
@@ -3688,15 +3943,15 @@ function codedError(code, message) {
3688
3943
  e.code = code;
3689
3944
  return e;
3690
3945
  }
3691
- function isSameOrInside(parent, child, impl = path12) {
3946
+ function isSameOrInside(parent, child, impl = path14) {
3692
3947
  const rel3 = impl.relative(parent, child);
3693
3948
  if (rel3 === "") return true;
3694
3949
  return !(rel3 === ".." || rel3.startsWith(`..${impl.sep}`) || impl.isAbsolute(rel3));
3695
3950
  }
3696
3951
  function nearestExisting(p) {
3697
3952
  let cur = p;
3698
- while (!existsSync4(cur)) {
3699
- const up = path12.dirname(cur);
3953
+ while (!existsSync5(cur)) {
3954
+ const up = path14.dirname(cur);
3700
3955
  if (up === cur) return cur;
3701
3956
  cur = up;
3702
3957
  }
@@ -3704,10 +3959,10 @@ function nearestExisting(p) {
3704
3959
  }
3705
3960
  function escapeReason(root, target, options = {}) {
3706
3961
  const realRoot = realpathSync2(root);
3707
- 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)) {
3708
3963
  return `\uACBD\uB85C\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4(${target})`;
3709
3964
  }
3710
- const anchor = nearestExisting(path12.dirname(target));
3965
+ const anchor = nearestExisting(path14.dirname(target));
3711
3966
  const realAnchor = realpathSync2(anchor);
3712
3967
  if (!isSameOrInside(realRoot, realAnchor)) {
3713
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`;
@@ -3720,7 +3975,7 @@ function escapeReason(root, target, options = {}) {
3720
3975
  }
3721
3976
  if (st) {
3722
3977
  if (st.isDirectory()) return `\uAC19\uC740 \uC774\uB984\uC758 \uB514\uB809\uD130\uB9AC\uAC00 \uC788\uC2B5\uB2C8\uB2E4(${target})`;
3723
- 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("/");
3724
3979
  let realTarget;
3725
3980
  try {
3726
3981
  realTarget = realpathSync2(target);
@@ -3788,50 +4043,50 @@ async function writeNoFollow(target, content, mode) {
3788
4043
  let fd;
3789
4044
  if (mode === "overwrite") {
3790
4045
  try {
3791
- fd = await fs10.open(target, OVERWRITE_FLAGS);
4046
+ fd = await fs11.open(target, OVERWRITE_FLAGS);
3792
4047
  } catch (e) {
3793
4048
  if (e.code !== "ENOENT") throw e;
3794
4049
  actual = "new";
3795
- fd = await fs10.open(target, NEW_FILE_FLAGS, 438);
4050
+ fd = await fs11.open(target, NEW_FILE_FLAGS, 438);
3796
4051
  }
3797
4052
  } else {
3798
- fd = await fs10.open(target, NEW_FILE_FLAGS, 438);
4053
+ fd = await fs11.open(target, NEW_FILE_FLAGS, 438);
3799
4054
  }
3800
4055
  try {
3801
4056
  if (actual === "overwrite") {
3802
- const st = await fs10.fstat(fd);
4057
+ const st = await fs11.fstat(fd);
3803
4058
  if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
3804
4059
  if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
3805
- await fs10.ftruncate(fd, 0);
4060
+ await fs11.ftruncate(fd, 0);
3806
4061
  }
3807
- await fs10.writeFile(fd, content);
4062
+ await fs11.writeFile(fd, content);
3808
4063
  } finally {
3809
- await fs10.close(fd);
4064
+ await fs11.close(fd);
3810
4065
  }
3811
4066
  return actual;
3812
4067
  }
3813
4068
  async function overwriteFollowingLinks(target, content) {
3814
- 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);
3815
4070
  try {
3816
- const st = await fs10.fstat(fd);
4071
+ const st = await fs11.fstat(fd);
3817
4072
  if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
3818
4073
  if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
3819
- await fs10.ftruncate(fd, 0);
3820
- await fs10.writeFile(fd, content);
4074
+ await fs11.ftruncate(fd, 0);
4075
+ await fs11.writeFile(fd, content);
3821
4076
  } finally {
3822
- await fs10.close(fd);
4077
+ await fs11.close(fd);
3823
4078
  }
3824
4079
  }
3825
4080
  function checkParentInside(root, target) {
3826
4081
  const realRoot = realpathSync2(root);
3827
- const realParent = realpathSync2(path12.dirname(target));
4082
+ const realParent = realpathSync2(path14.dirname(target));
3828
4083
  if (!isSameOrInside(realRoot, realParent)) {
3829
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`;
3830
4085
  }
3831
4086
  return escapeReason(root, target);
3832
4087
  }
3833
4088
 
3834
- // src/init/init.ts
4089
+ // ../axis-registry-core/src/utils-deps.ts
3835
4090
  var CLSX_RANGE = "^2.1.1";
3836
4091
  var TAILWIND_MERGE_RANGES = {
3837
4092
  tailwind4: "^3.4.0",
@@ -3843,6 +4098,8 @@ function selectUtilsDependencies(tailwind) {
3843
4098
  "tailwind-merge": tailwind.major !== void 0 && tailwind.major >= 4 ? TAILWIND_MERGE_RANGES.tailwind4 : TAILWIND_MERGE_RANGES.tailwind3
3844
4099
  };
3845
4100
  }
4101
+
4102
+ // src/init/init.ts
3846
4103
  function tailwindWarnings(tailwind, installCommand) {
3847
4104
  const out = [];
3848
4105
  if (tailwind.source === "none" && tailwind.value !== void 0) {
@@ -3906,7 +4163,7 @@ var TAILWIND4_TOKENS_VERSION = TAILWIND4_MIN_AXIS_VERSION;
3906
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.";
3907
4164
  function readPackageJsonSafe(baseDir) {
3908
4165
  try {
3909
- const text = readFileSync4(path13.join(baseDir, "package.json"), "utf8");
4166
+ const text = readFileSync4(path15.join(baseDir, "package.json"), "utf8");
3910
4167
  const parsed = JSON.parse(text.startsWith(BOM) ? text.slice(1) : text);
3911
4168
  return isPlainObject2(parsed) ? parsed : void 0;
3912
4169
  } catch {
@@ -3971,7 +4228,7 @@ function addCommandFor(installCommand, deps) {
3971
4228
  return `pnpm add ${specs}`;
3972
4229
  }
3973
4230
  function planUtilsDependencies(baseDirInput) {
3974
- const baseDir = path13.resolve(baseDirInput);
4231
+ const baseDir = path15.resolve(baseDirInput);
3975
4232
  const installCommand = detectInstallCommand(baseDir);
3976
4233
  const tailwind0 = detectTailwind(baseDir);
3977
4234
  const ranges0 = selectUtilsDependencies(tailwind0);
@@ -3984,8 +4241,8 @@ function planUtilsDependencies(baseDirInput) {
3984
4241
  installCommand,
3985
4242
  addCommand: addCommandFor(installCommand, ranges0)
3986
4243
  };
3987
- const pkgFile = path13.join(baseDir, "package.json");
3988
- if (!existsSync5(pkgFile)) return plan;
4244
+ const pkgFile = path15.join(baseDir, "package.json");
4245
+ if (!existsSync6(pkgFile)) return plan;
3989
4246
  const unwritable = (reason) => ({ ...plan, action: "unwritable", reason });
3990
4247
  let where;
3991
4248
  try {
@@ -4038,8 +4295,8 @@ var defaultWriteFile = (file, data) => writeFileSync2(file, data);
4038
4295
  function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile) {
4039
4296
  const w = plan.write;
4040
4297
  if (plan.action !== "add" || !w) return false;
4041
- const baseDir = path13.resolve(baseDirInput);
4042
- 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;
4043
4300
  if (current !== w.before) {
4044
4301
  throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
4045
4302
  }
@@ -4068,25 +4325,25 @@ function reportDependencies(plan, log) {
4068
4325
  const presentText = plan.present.map((p) => `${p.name} (${p.range})`).join(", ");
4069
4326
  const basis = ` tailwind-merge \uBC94\uC704 \uAE30\uC900: ${describeTailwindBasis(plan.tailwind)}`;
4070
4327
  const logBasis = () => {
4071
- log(chalk9.gray(basis));
4072
- 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}`));
4073
4330
  };
4074
4331
  if (plan.action === "add") {
4075
4332
  const addedText = plan.added.map((n) => `${n}@${plan.ranges[n]}`).join(", ");
4076
- log(chalk9.green(`\u2713 package.json dependencies \uC5D0 \uCD94\uAC00: ${addedText}`));
4077
- 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}`));
4078
4335
  if (plan.added.includes("tailwind-merge")) logBasis();
4079
- 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)}`));
4080
4337
  } else if (plan.action === "present") {
4081
- log(chalk9.green(`\u2713 utils.ts \uC758\uC874\uC131\uC774 package.json \uC5D0 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
4082
- 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)}`));
4083
4340
  } else if (plan.action === "no-package-json") {
4084
- 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."));
4085
- 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)}`));
4086
4343
  logBasis();
4087
4344
  } else {
4088
- log(chalk9.yellow(`! package.json \uC744 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(${plan.reason}).`));
4089
- 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)}`));
4090
4347
  if (plan.addCommand.includes('"tailwind-merge@')) logBasis();
4091
4348
  }
4092
4349
  }
@@ -4109,8 +4366,8 @@ function errCode(e) {
4109
4366
  return e.code ?? e.message;
4110
4367
  }
4111
4368
  function planUtilsWrite(baseDirInput, utilsPath) {
4112
- const baseDir = path13.resolve(baseDirInput);
4113
- 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;
4114
4371
  let st;
4115
4372
  try {
4116
4373
  st = lstatSync2(utilsPath);
@@ -4171,7 +4428,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
4171
4428
  return { action: "overwrite" };
4172
4429
  }
4173
4430
  async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
4174
- const baseDir = path13.resolve(baseDirInput);
4431
+ const baseDir = path15.resolve(baseDirInput);
4175
4432
  const current = await existingConfig(baseDir);
4176
4433
  const existingRegistry = nonEmptyString(current?.registry);
4177
4434
  const migratedRegistry = existingRegistry !== void 0 && isLegacyDefaultRegistryUrl(existingRegistry);
@@ -4188,13 +4445,13 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
4188
4445
  },
4189
4446
  registry
4190
4447
  );
4191
- const configPath = path13.join(baseDir, "axis.config.json");
4448
+ const configPath = path15.join(baseDir, "axis.config.json");
4192
4449
  const nextText = `${JSON.stringify(axisConfig, null, 2)}
4193
4450
  `;
4194
4451
  const rejects = [];
4195
4452
  let previousText = null;
4196
4453
  try {
4197
- previousText = await fs11.readFile(configPath, "utf8");
4454
+ previousText = await fs12.readFile(configPath, "utf8");
4198
4455
  } catch (e) {
4199
4456
  if (e.code !== "ENOENT") {
4200
4457
  rejects.push(`\uAE30\uC874 axis.config.json \uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})`);
@@ -4207,79 +4464,79 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
4207
4464
  } catch {
4208
4465
  }
4209
4466
  }
4210
- const utilsPath = path13.resolve(baseDir, answers.componentsDir, "utils.ts");
4467
+ const utilsPath = path15.resolve(baseDir, answers.componentsDir, "utils.ts");
4211
4468
  const utilsPlan = planUtilsWrite(baseDir, utilsPath);
4212
4469
  if (utilsPlan.action === "reject") rejects.push(utilsPlan.reason);
4213
4470
  if (rejects.length > 0) {
4214
- 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)."));
4215
- 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}`));
4216
4473
  process.exitCode = 1;
4217
4474
  return;
4218
4475
  }
4219
4476
  let configState;
4220
4477
  if (previousText === null) {
4221
4478
  try {
4222
- await fs11.writeFile(configPath, nextText, { flag: "wx" });
4479
+ await fs12.writeFile(configPath, nextText, { flag: "wx" });
4223
4480
  } catch (err) {
4224
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;
4225
- 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.`));
4226
4483
  process.exitCode = 1;
4227
4484
  return;
4228
4485
  }
4229
4486
  configState = "created";
4230
- log(chalk9.green("\u2713 axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
4487
+ log(chalk10.green("\u2713 axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
4231
4488
  } else if (previousText === nextText) {
4232
4489
  configState = "kept";
4233
- 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)"));
4234
4491
  } else {
4235
4492
  try {
4236
4493
  await overwriteFollowingLinks(configPath, nextText);
4237
4494
  } catch (err) {
4238
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;
4239
- 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.`));
4240
4497
  process.exitCode = 1;
4241
4498
  return;
4242
4499
  }
4243
4500
  configState = "updated";
4244
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";
4245
4502
  const agenticNote = existingAgenticDir !== void 0 ? ", agenticDir \uB294 \uAE30\uC874 \uAC12 \uC720\uC9C0" : "";
4246
- 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})`));
4247
4504
  if (migratedRegistry && existingRegistry !== void 0) {
4248
4505
  log(
4249
- chalk9.yellow(
4506
+ chalk10.yellow(
4250
4507
  ` registry \uB97C \uC0C8 \uAE30\uBCF8 \uC8FC\uC18C(${redactRegistryUrl(registry)})\uB85C \uAC31\uC2E0\uD588\uC2B5\uB2C8\uB2E4(\uC885\uC804 axis.minu.best: ${redactRegistryUrl(existingRegistry)}).`
4251
4508
  )
4252
4509
  );
4253
4510
  }
4254
4511
  const dropped = current ? Object.keys(current).filter((k) => !(k in axisConfig) && current[k] !== void 0) : [];
4255
4512
  if (dropped.length > 0) {
4256
- 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)`));
4257
4514
  }
4258
4515
  }
4259
4516
  let utilsStateNote = "utils.ts \uB294 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9).";
4260
4517
  if (utilsPlan.action === "keep") {
4261
- if (utilsPlan.link === void 0) log(chalk9.green("\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9)"));
4262
- else if (utilsPlan.link.outside === null) log(chalk9.green("\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9, \uB9C1\uD06C)"));
4263
- 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})`));
4264
4521
  } else {
4265
4522
  let actual;
4266
4523
  try {
4267
- await fs11.ensureDir(path13.dirname(utilsPath));
4524
+ await fs12.ensureDir(path15.dirname(utilsPath));
4268
4525
  actual = await writeNoFollow(utilsPath, UTILS_TS_CONTENT, utilsPlan.action === "create" ? "new" : "overwrite");
4269
4526
  } catch (err) {
4270
4527
  const code = err.code;
4271
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;
4272
4529
  log(
4273
- chalk9.red(
4530
+ chalk10.red(
4274
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.`
4275
4532
  )
4276
4533
  );
4277
- log(chalk9.yellow(` ${configStateNote(configState)}`));
4534
+ log(chalk10.yellow(` ${configStateNote(configState)}`));
4278
4535
  process.exitCode = 1;
4279
4536
  return;
4280
4537
  }
4281
4538
  log(
4282
- chalk9.green(
4539
+ chalk10.green(
4283
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)"
4284
4541
  )
4285
4542
  );
@@ -4288,9 +4545,9 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
4288
4545
  try {
4289
4546
  applyUtilsDependencies(baseDir, plan);
4290
4547
  } catch (err) {
4291
- log(chalk9.red(`\u2717 package.json \uC744 \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${err.message}`));
4292
- log(chalk9.yellow(` ${configStateNote(configState)} ${utilsStateNote}`));
4293
- 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)}`));
4294
4551
  process.exitCode = 1;
4295
4552
  return;
4296
4553
  }
@@ -4302,19 +4559,19 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
4302
4559
  answers.globalCss,
4303
4560
  baseDir
4304
4561
  );
4305
- log(chalk9.blue(`
4562
+ log(chalk10.blue(`
4306
4563
  ${head}`));
4307
- 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));
4308
4565
  }
4309
- 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:"));
4310
- 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}
4311
4568
  `));
4312
4569
  }
4313
4570
 
4314
4571
  // src/init/index.ts
4315
4572
  function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL) {
4316
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) => {
4317
- 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"));
4318
4575
  const tailwind4 = isTailwind4(planUtilsDependencies(process.cwd()).tailwind);
4319
4576
  const config = options.yes ? { ...INIT_DEFAULTS } : await prompts2([
4320
4577
  {
@@ -4341,27 +4598,27 @@ function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL) {
4341
4598
  }
4342
4599
 
4343
4600
  // src/add/index.ts
4344
- import chalk11 from "chalk";
4601
+ import chalk12 from "chalk";
4345
4602
  import prompts3 from "prompts";
4346
4603
 
4347
- // src/add/add.ts
4348
- import { existsSync as existsSync7, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
4349
- import path15 from "path";
4350
- 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";
4351
4608
 
4352
- // src/registry/bundled.ts
4353
- import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
4354
- 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";
4355
4612
  import { fileURLToPath } from "url";
4356
4613
  function findBundledRegistryDir(moduleUrl = import.meta.url) {
4357
- const here = path14.dirname(fileURLToPath(moduleUrl));
4358
- for (const dir of [path14.join(here, "registry"), path14.join(here, "..", "registry")]) {
4359
- 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;
4360
4617
  }
4361
4618
  return null;
4362
4619
  }
4363
4620
  function readBundledJson(dir, fileName) {
4364
- const file = path14.join(dir, fileName);
4621
+ const file = path16.join(dir, fileName);
4365
4622
  let text;
4366
4623
  try {
4367
4624
  text = readFileSync5(file, "utf8");
@@ -4371,7 +4628,238 @@ function readBundledJson(dir, fileName) {
4371
4628
  return parseJsonText(text, `\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC ${fileName}`);
4372
4629
  }
4373
4630
 
4374
- // 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
4375
4863
  var RegistryError = class extends Error {
4376
4864
  constructor(code, message) {
4377
4865
  super(message);
@@ -4379,15 +4867,16 @@ var RegistryError = class extends Error {
4379
4867
  this.name = "RegistryError";
4380
4868
  }
4381
4869
  };
4382
- 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) {
4383
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";
4384
- 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})`;
4385
4874
  }
4386
4875
  function fallbackKindOf(error) {
4387
4876
  return error instanceof RegistryAccessError ? "access" : "invalid";
4388
4877
  }
4389
- function versionMismatchMessage(remoteVersion, bundledVersion) {
4390
- 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.`;
4391
4880
  }
4392
4881
  function messageOf(error) {
4393
4882
  return error instanceof Error ? error.message : String(error);
@@ -4399,6 +4888,10 @@ var RegistryClient = class {
4399
4888
  timeoutMs;
4400
4889
  fetchImpl;
4401
4890
  notify;
4891
+ bundledLabel;
4892
+ rawUrl;
4893
+ urlSource;
4894
+ rejectRedirects;
4402
4895
  mode = null;
4403
4896
  indexPromise = null;
4404
4897
  bundledIndex = null;
@@ -4421,6 +4914,15 @@ var RegistryClient = class {
4421
4914
  this.timeoutMs = options.timeoutMs ?? DEFAULT_REGISTRY_TIMEOUT_MS;
4422
4915
  this.fetchImpl = options.fetchImpl;
4423
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 };
4424
4926
  }
4425
4927
  /** 지금 쓰는 출처. index 를 읽기 전에는 null 입니다 */
4426
4928
  get origin() {
@@ -4464,7 +4966,11 @@ var RegistryClient = class {
4464
4966
  return bases;
4465
4967
  }
4466
4968
  fetchOptions() {
4467
- 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
+ };
4468
4974
  }
4469
4975
  async loadIndex() {
4470
4976
  let remoteError;
@@ -4488,7 +4994,7 @@ var RegistryClient = class {
4488
4994
  /** 동봉본 index 를 읽습니다(성공하면 한 번만). 실패하면 이유를 돌려줍니다 */
4489
4995
  loadBundledIndex() {
4490
4996
  if (this.bundledIndex) return { index: this.bundledIndex };
4491
- 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` };
4492
4998
  try {
4493
4999
  this.bundledIndex = validateRegistryIndex(readBundledJson(this.bundledDir, "index.json"), "\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC index.json");
4494
5000
  return { index: this.bundledIndex };
@@ -4499,7 +5005,7 @@ var RegistryClient = class {
4499
5005
  warnVersionMismatch(remoteVersion) {
4500
5006
  const bundled = this.loadBundledIndex();
4501
5007
  if ("index" in bundled && bundled.index.version !== remoteVersion) {
4502
- this.notify(versionMismatchMessage(remoteVersion, bundled.index.version));
5008
+ this.notify(versionMismatchMessage(remoteVersion, bundled.index.version, this.bundledLabel));
4503
5009
  }
4504
5010
  }
4505
5011
  async switchToBundled(reason, kind = "access") {
@@ -4514,7 +5020,7 @@ var RegistryClient = class {
4514
5020
  this.indexPromise = Promise.resolve(bundled.index);
4515
5021
  if (!this.fallbackAnnounced) {
4516
5022
  this.fallbackAnnounced = true;
4517
- this.notify(bundledFallbackMessage(bundled.index.version, reason, kind));
5023
+ this.notify(bundledFallbackMessage(bundled.index.version, reason, kind, this.bundledLabel));
4518
5024
  }
4519
5025
  return bundled.index;
4520
5026
  }
@@ -4524,7 +5030,7 @@ var RegistryClient = class {
4524
5030
  if (!index || !entry || !this.bundledDir) {
4525
5031
  throw new RegistryError(
4526
5032
  "not-found",
4527
- `'${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`
4528
5034
  );
4529
5035
  }
4530
5036
  try {
@@ -4532,18 +5038,23 @@ var RegistryClient = class {
4532
5038
  checkItemSha256(item, entry);
4533
5039
  return item;
4534
5040
  } catch (error) {
4535
- 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)}`);
4536
5042
  }
4537
5043
  }
4538
5044
  };
4539
5045
 
4540
- // src/add/add.ts
5046
+ // ../axis-registry-core/src/add/add.ts
4541
5047
  var AGENTIC_PREFIX = "agentic-";
5048
+ var CLI_ADD_HINTS = {
5049
+ listCommand: "npx @axis-ds/cli list",
5050
+ overwrite: "--overwrite",
5051
+ agenticFlag: true
5052
+ };
4542
5053
  function applyAgenticAlias(name, agentic) {
4543
5054
  if (!agentic || name.startsWith(AGENTIC_PREFIX)) return name;
4544
5055
  return `${AGENTIC_PREFIX}${name}`;
4545
5056
  }
4546
- function describeMissingName(requested, resolved, index, agentic) {
5057
+ function describeMissingName(requested, resolved, index, agentic, agenticFlag = true) {
4547
5058
  const names = new Set(index.items.map((it) => it.name));
4548
5059
  if (!isValidRegistryName(resolved)) {
4549
5060
  return `'${requested}': \uC774\uB984 \uADDC\uCE59(\uC18C\uBB38\uC790 \xB7 \uC22B\uC790 \xB7 \uD558\uC774\uD508)\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`;
@@ -4552,6 +5063,9 @@ function describeMissingName(requested, resolved, index, agentic) {
4552
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`;
4553
5064
  }
4554
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
+ }
4555
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`;
4556
5070
  }
4557
5071
  return `'${requested}': \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`;
@@ -4566,10 +5080,10 @@ function layoutFromConfig(root, config) {
4566
5080
  throw new Error("axis.config.json \uC758 agenticDir \uAC00 \uBB38\uC790\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4");
4567
5081
  }
4568
5082
  const componentsDir = componentsRaw.replace(/\\/g, "/");
4569
- const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") : path15.posix.join(path15.posix.dirname(componentsDir), "agentic");
4570
- 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 };
4571
5085
  }
4572
- function toPosix(p, impl = path15) {
5086
+ function toPosix(p, impl = path17) {
4573
5087
  return p.split(impl.sep).join("/");
4574
5088
  }
4575
5089
  function itemKind(item) {
@@ -4591,12 +5105,12 @@ function placeFile(layout, item, filePath, target) {
4591
5105
  const problem = registryPathProblem(p);
4592
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})`);
4593
5107
  }
4594
- const base = path15.posix.basename(filePath);
5108
+ const base = path17.posix.basename(filePath);
4595
5109
  if (!INSTALL_FILE_NAME_PATTERN.test(base)) {
4596
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)`);
4597
5111
  }
4598
5112
  const dir = itemKind(item) === "agentic" ? layout.agenticDir : layout.componentsDir;
4599
- return path15.resolve(layout.root, dir, base);
5113
+ return path17.resolve(layout.root, dir, base);
4600
5114
  }
4601
5115
  function stripExt(p) {
4602
5116
  return p.replace(/\.(?:tsx?|jsx?|mjs|cjs)$/, "");
@@ -4607,7 +5121,7 @@ function buildImportTargets(entries) {
4607
5121
  for (const { item, file, target } of entries) {
4608
5122
  const rel3 = stripExt(file.path.replace(/\\/g, "/").replace(/^\.?\//, ""));
4609
5123
  exact.set(`@/${rel3}`, target);
4610
- if (itemKind(item) === "lib") lib.set(path15.posix.basename(rel3), target);
5124
+ if (itemKind(item) === "lib") lib.set(path17.posix.basename(rel3), target);
4611
5125
  }
4612
5126
  return { exact, lib };
4613
5127
  }
@@ -4683,7 +5197,7 @@ function insideRanges(ranges, at) {
4683
5197
  }
4684
5198
  var SPECIFIER_PATTERN = /(\bfrom\s*|\bimport\s*\(\s*|\bimport\s+|\brequire\s*\(\s*)(["'])(@\/[^"'\n]+)\2/g;
4685
5199
  var STANDARD_LIB_PATTERN = /^@\/registry\/[^/]+\/lib\/(.+)$/;
4686
- function relativeSpecifier(fromFile, toFile, impl = path15) {
5200
+ function relativeSpecifier(fromFile, toFile, impl = path17) {
4687
5201
  let rel3 = toPosix(impl.relative(impl.dirname(fromFile), stripExt(toFile)), impl);
4688
5202
  if (!rel3.startsWith(".")) rel3 = `./${rel3}`;
4689
5203
  return rel3;
@@ -4711,7 +5225,7 @@ function rewriteImports(content, fileTarget, targets) {
4711
5225
  }
4712
5226
  var RESOLVE_EXTS = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", "/index.ts", "/index.tsx", "/index.js"];
4713
5227
  function relativeSpecifierResolves(fromFile, spec) {
4714
- const base = path15.resolve(path15.dirname(fromFile), spec);
5228
+ const base = path17.resolve(path17.dirname(fromFile), spec);
4715
5229
  return RESOLVE_EXTS.some((ext) => {
4716
5230
  try {
4717
5231
  return statSync4(base + ext).isFile();
@@ -4763,7 +5277,7 @@ function planFiles(layout, items) {
4763
5277
  }
4764
5278
  const prev = byTarget.get(target);
4765
5279
  if (prev !== void 0) {
4766
- 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)`);
4767
5281
  continue;
4768
5282
  }
4769
5283
  byTarget.set(target, item.name);
@@ -4789,7 +5303,7 @@ function missingDependencies(root, items) {
4789
5303
  const installCommand = detectInstallCommand(root);
4790
5304
  let pkg;
4791
5305
  try {
4792
- const text = readFileSync6(path15.join(root, "package.json"), "utf8").replace(/^/, "");
5306
+ const text = readFileSync6(path17.join(root, "package.json"), "utf8").replace(/^/, "");
4793
5307
  const parsed = JSON.parse(text);
4794
5308
  pkg = isPlainObject2(parsed) ? parsed : void 0;
4795
5309
  } catch {
@@ -4821,15 +5335,16 @@ function addCommandForSpecs(installCommand, specs) {
4821
5335
  return `pnpm add ${args}`;
4822
5336
  }
4823
5337
  function rel2(root, p) {
4824
- return toPosix(path15.relative(root, p));
5338
+ return toPosix(path17.relative(root, p));
4825
5339
  }
4826
5340
  async function runAdd(cwd, requested, options, ctx) {
4827
5341
  const log = ctx.log ?? console.log;
4828
5342
  const error = ctx.error ?? console.error;
4829
- const root = path15.resolve(cwd);
5343
+ const hints = { ...CLI_ADD_HINTS, ...ctx.hints };
5344
+ const root = path17.resolve(cwd);
4830
5345
  const result = { exitCode: 1, written: [], overwritten: [], unchanged: [], skipped: [] };
4831
5346
  if (requested.length === 0) {
4832
- 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}`);
4833
5348
  return result;
4834
5349
  }
4835
5350
  let config;
@@ -4839,6 +5354,11 @@ async function runAdd(cwd, requested, options, ctx) {
4839
5354
  error(`axis.config.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`);
4840
5355
  return result;
4841
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
+ }
4842
5362
  if (!config) {
4843
5363
  error(
4844
5364
  `axis.config.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
@@ -4866,13 +5386,13 @@ async function runAdd(cwd, requested, options, ctx) {
4866
5386
  const missing = [];
4867
5387
  for (const req of requested) {
4868
5388
  const name = applyAgenticAlias(req, options.agentic);
4869
- 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));
4870
5390
  else if (!resolved.includes(name)) resolved.push(name);
4871
5391
  }
4872
5392
  if (missing.length > 0) {
4873
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}).`);
4874
5394
  for (const m of missing) error(` - ${m}`);
4875
- error(" \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBAA9\uB85D: npx @axis-ds/cli list");
5395
+ error(` \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBAA9\uB85D: ${hints.listCommand}`);
4876
5396
  return result;
4877
5397
  }
4878
5398
  let items;
@@ -4884,6 +5404,7 @@ async function runAdd(cwd, requested, options, ctx) {
4884
5404
  return result;
4885
5405
  }
4886
5406
  items = collected.items;
5407
+ result.items = items.map((it) => it.name);
4887
5408
  } catch (e) {
4888
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}`;
4889
5410
  error(msg);
@@ -4898,7 +5419,7 @@ async function runAdd(cwd, requested, options, ctx) {
4898
5419
  const existing = /* @__PURE__ */ new Map();
4899
5420
  const readErrors = [];
4900
5421
  for (const file of plan.files) {
4901
- if (!existsSync7(file.target)) {
5422
+ if (!existsSync8(file.target)) {
4902
5423
  existing.set(file, null);
4903
5424
  continue;
4904
5425
  }
@@ -4977,7 +5498,7 @@ async function runAdd(cwd, requested, options, ctx) {
4977
5498
  try {
4978
5499
  const before = escapeReason(root, d.file.target);
4979
5500
  if (before) return stopWriting(p, before);
4980
- await fs12.ensureDir(path15.dirname(d.file.target));
5501
+ await fs13.ensureDir(path17.dirname(d.file.target));
4981
5502
  const after = checkParentInside(root, d.file.target);
4982
5503
  if (after) return stopWriting(p, after);
4983
5504
  actual = await writeNoFollow(d.file.target, d.file.content, actual);
@@ -5033,7 +5554,7 @@ async function runAdd(cwd, requested, options, ctx) {
5033
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)`);
5034
5555
  }
5035
5556
  if (result.skipped.length > 0) {
5036
- 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}):`);
5037
5558
  for (const p of result.skipped) log(outsideRel.has(p) ? ` - ${p} (\uB9C1\uD06C \uB300\uC0C1\uC774 \uD504\uB85C\uC81D\uD2B8 \uBC16)` : ` - ${p}`);
5038
5559
  }
5039
5560
  if (broken.length > 0) {
@@ -5043,8 +5564,9 @@ async function runAdd(cwd, requested, options, ctx) {
5043
5564
  }
5044
5565
  const deps = missingDependencies(root, items);
5045
5566
  if (Object.keys(deps.specs).length > 0) {
5567
+ result.dependencyCommand = addCommandForSpecs(deps.installCommand, deps.specs);
5046
5568
  log("\npackage.json \uC5D0 \uC5C6\uB294 \uC758\uC874\uC131(\uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4):");
5047
- log(` ${addCommandForSpecs(deps.installCommand, deps.specs)}`);
5569
+ log(` ${result.dependencyCommand}`);
5048
5570
  }
5049
5571
  return { ...result, exitCode: 0 };
5050
5572
  }
@@ -5059,17 +5581,50 @@ function groupIndex(index) {
5059
5581
  }
5060
5582
  return { ui, agentic };
5061
5583
  }
5062
- async function createClientFor(cwd, notify, env = process.env) {
5584
+ async function createClientFor(cwd, notify, env = process.env, clientOptions = {}) {
5585
+ const { guardConfigRegistry, ...options } = clientOptions;
5063
5586
  let config = null;
5064
5587
  try {
5065
- config = await readAxisConfig(path15.resolve(cwd));
5588
+ config = await readAxisConfig(path17.resolve(cwd));
5066
5589
  } catch {
5067
5590
  config = null;
5068
5591
  }
5069
- const resolved = resolveRegistryUrl({ config, env });
5592
+ let resolved = resolveRegistryUrl({ config, env });
5070
5593
  const say = notify ?? ((message) => console.warn(message));
5071
5594
  if (resolved.migratedFrom !== void 0) say(LEGACY_REGISTRY_NOTICE);
5072
- 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`;
5073
5628
  }
5074
5629
 
5075
5630
  // src/add/index.ts
@@ -5080,7 +5635,7 @@ function createConfirm(interactive) {
5080
5635
  return overwrite === true;
5081
5636
  };
5082
5637
  }
5083
- var defaultCreateClient = (cwd) => createClientFor(cwd, (m) => console.warn(chalk11.yellow(m)));
5638
+ var defaultCreateClient = (cwd) => createClientFor(cwd, (m) => console.warn(chalk12.yellow(m)));
5084
5639
  function registerAddCommand(program2, deps = {}) {
5085
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) => {
5086
5641
  const client = await (deps.createClient ?? defaultCreateClient)(process.cwd());
@@ -5088,7 +5643,7 @@ function registerAddCommand(program2, deps = {}) {
5088
5643
  const result = await runAdd(process.cwd(), components, options, {
5089
5644
  client,
5090
5645
  log: (...a) => console.log(...a),
5091
- error: (...a) => console.error(chalk11.red(a.map(String).join(" "))),
5646
+ error: (...a) => console.error(chalk12.red(a.map(String).join(" "))),
5092
5647
  ...confirm ? { confirm } : {}
5093
5648
  });
5094
5649
  process.exitCode = result.exitCode;
@@ -5097,7 +5652,7 @@ function registerAddCommand(program2, deps = {}) {
5097
5652
  function registerListCommand(program2, deps = {}) {
5098
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) => {
5099
5654
  if (options.category !== void 0 && options.category !== "ui" && options.category !== "agentic") {
5100
- 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})`));
5101
5656
  process.exitCode = 1;
5102
5657
  return;
5103
5658
  }
@@ -5109,26 +5664,26 @@ function registerListCommand(program2, deps = {}) {
5109
5664
  groups = groupIndex(index);
5110
5665
  version = index.version;
5111
5666
  } catch (e) {
5112
- 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}`));
5113
5668
  process.exitCode = 1;
5114
5669
  return;
5115
5670
  }
5116
5671
  const total = groups.ui.length + groups.agentic.length;
5117
5672
  const origin = client.origin === "bundled" ? "CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC" : "\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC";
5118
- console.log(chalk11.blue(`
5673
+ console.log(chalk12.blue(`
5119
5674
  \u{1F4E6} AXIS Design System \uCEF4\uD3EC\uB10C\uD2B8 ${total}\uAC1C (${origin}, version ${version})
5120
5675
  `));
5121
5676
  const show = (label, items) => {
5122
- console.log(chalk11.bold(`${label} (${items.length})`));
5677
+ console.log(chalk12.bold(`${label} (${items.length})`));
5123
5678
  for (const c of items) {
5124
- 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 ?? "")}`);
5125
5680
  }
5126
5681
  console.log();
5127
5682
  };
5128
5683
  if (!options.category || options.category === "ui") show("Core UI", groups.ui);
5129
5684
  if (!options.category || options.category === "agentic") show("Agentic UI", groups.agentic);
5130
- console.log(chalk11.gray("\uC0AC\uC6A9\uBC95: npx @axis-ds/cli add <\uC774\uB984...> (\uC608: add button input card)"));
5131
- 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"));
5132
5687
  });
5133
5688
  }
5134
5689
 
@@ -5157,24 +5712,24 @@ monetCmd.command("import").alias("i").description("\uD074\uB9BD\uBCF4\uB4DC\uC5D
5157
5712
  await client.importFromClipboard();
5158
5713
  });
5159
5714
  monetCmd.command("setup").description("Monet MCP \uC11C\uBC84 \uC124\uC815 \uC548\uB0B4").action(() => {
5160
- console.log(chalk12.blue("\n\u{1F527} Monet MCP \uC11C\uBC84 \uC124\uC815\n"));
5161
- console.log(chalk12.bold("1. API \uD0A4 \uBC1C\uAE09:"));
5162
- console.log(chalk12.cyan(" https://monet.design/mcp\n"));
5163
- console.log(chalk12.bold("2. \uD658\uACBD \uBCC0\uC218 \uC124\uC815:"));
5164
- console.log(chalk12.gray(" .env \uD30C\uC77C\uC5D0 \uCD94\uAC00:"));
5165
- console.log(chalk12.cyan(" MONET_API_KEY=your-api-key-here\n"));
5166
- console.log(chalk12.bold("3. Claude Code MCP \uC124\uC815:"));
5167
- 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"));
5168
5723
  console.log(
5169
- chalk12.cyan(` "monet": {
5724
+ chalk13.cyan(` "monet": {
5170
5725
  "url": "https://www.monet.design/api/remote/mcp",
5171
5726
  "headers": { "Authorization": "Bearer \${MONET_API_KEY}" },
5172
5727
  "disabled": false
5173
5728
  }
5174
5729
  `)
5175
5730
  );
5176
- console.log(chalk12.bold("4. Claude Code \uC7AC\uC2DC\uC791 \uD6C4 \uC0AC\uC6A9:"));
5177
- 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'));
5178
5733
  });
5179
5734
  var v0Cmd = program.command("v0").description("V0 (v0.app) \uCF54\uB4DC \uBCC0\uD658 \uBC0F \uD1B5\uD569");
5180
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) => {
@@ -5211,18 +5766,18 @@ libraryCmd.command("collect").alias("c").description("\uC678\uBD80 \uC18C\uC2A4\
5211
5766
  total += result.collected;
5212
5767
  failed += result.failed;
5213
5768
  }
5214
- console.log(chalk12.blue(`
5769
+ console.log(chalk13.blue(`
5215
5770
  \u{1F4CA} \uC218\uC9D1 \uC644\uB8CC: ${total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8`));
5216
5771
  if (failed > 0) {
5217
- console.log(chalk12.yellow(` \uC2E4\uD328: ${failed}\uAC1C`));
5772
+ console.log(chalk13.yellow(` \uC2E4\uD328: ${failed}\uAC1C`));
5218
5773
  }
5219
5774
  });
5220
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) => {
5221
5776
  const curator = new LibraryCurator();
5222
5777
  const index = await curator.loadIndex();
5223
5778
  if (!index) {
5224
- console.log(chalk12.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
5225
- 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"));
5226
5781
  return;
5227
5782
  }
5228
5783
  let components = index.components;
@@ -5232,7 +5787,7 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
5232
5787
  if (options.source) {
5233
5788
  components = components.filter((c) => c.source.type === options.source);
5234
5789
  }
5235
- console.log(chalk12.blue(`
5790
+ console.log(chalk13.blue(`
5236
5791
  \u{1F4E6} Library Components (${components.length}\uAC1C)
5237
5792
  `));
5238
5793
  const byCategory = /* @__PURE__ */ new Map();
@@ -5244,14 +5799,14 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
5244
5799
  byCategory.get(cat).push(comp);
5245
5800
  }
5246
5801
  for (const [category, items] of byCategory) {
5247
- console.log(chalk12.bold(`${category} (${items.length})`));
5802
+ console.log(chalk13.bold(`${category} (${items.length})`));
5248
5803
  for (const item of items.slice(0, 10)) {
5249
5804
  console.log(
5250
- ` ${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))}`
5251
5806
  );
5252
5807
  }
5253
5808
  if (items.length > 10) {
5254
- console.log(chalk12.gray(` ... \uC678 ${items.length - 10}\uAC1C`));
5809
+ console.log(chalk13.gray(` ... \uC678 ${items.length - 10}\uAC1C`));
5255
5810
  }
5256
5811
  console.log();
5257
5812
  }
@@ -5263,21 +5818,21 @@ libraryCmd.command("search <query>").alias("s").description("\uCEF4\uD3EC\uB10C\
5263
5818
  source: options.source
5264
5819
  });
5265
5820
  if (results.length === 0) {
5266
- console.log(chalk12.yellow(`
5821
+ console.log(chalk13.yellow(`
5267
5822
  '${query}'\uC5D0 \uB300\uD55C \uAC80\uC0C9 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
5268
5823
  `));
5269
5824
  return;
5270
5825
  }
5271
- console.log(chalk12.blue(`
5826
+ console.log(chalk13.blue(`
5272
5827
  \u{1F50D} '${query}' \uAC80\uC0C9 \uACB0\uACFC (${results.length}\uAC1C)
5273
5828
  `));
5274
5829
  for (const comp of results.slice(0, 20)) {
5275
5830
  console.log(
5276
- ` ${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))}`
5277
5832
  );
5278
5833
  }
5279
5834
  if (results.length > 20) {
5280
- console.log(chalk12.gray(`
5835
+ console.log(chalk13.gray(`
5281
5836
  ... \uC678 ${results.length - 20}\uAC1C`));
5282
5837
  }
5283
5838
  console.log();
@@ -5291,12 +5846,12 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
5291
5846
  const publisher2 = new Publisher();
5292
5847
  const index = await curator.loadIndex();
5293
5848
  if (!index) {
5294
- console.log(chalk12.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
5295
- 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"));
5296
5851
  return;
5297
5852
  }
5298
- console.log(chalk12.blue("\n\u{1F4E4} Library \uBC30\uCE58\n"));
5299
- 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
5300
5855
  `));
5301
5856
  if (options.clean) {
5302
5857
  await publisher2.clean(options.output);
@@ -5307,21 +5862,22 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
5307
5862
  generateSearchIndex: true
5308
5863
  });
5309
5864
  if (result.success) {
5310
- console.log(chalk12.green(`
5865
+ console.log(chalk13.green(`
5311
5866
  \u2713 \uBC30\uCE58 \uC644\uB8CC`));
5312
- console.log(chalk12.gray(` - \uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC: ${result.outputDir}`));
5313
- console.log(chalk12.gray(` - \uC0DD\uC131\uB41C \uD30C\uC77C: ${result.files.length}\uAC1C`));
5314
- console.log(chalk12.gray(` - \uCE74\uD14C\uACE0\uB9AC: ${result.stats.categoriesPublished}\uAC1C`));
5315
- 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`));
5316
5871
  } else {
5317
- console.log(chalk12.red(`
5872
+ console.log(chalk13.red(`
5318
5873
  \u2717 \uBC30\uCE58 \uC2E4\uD328`));
5319
5874
  for (const error of result.errors) {
5320
- console.log(chalk12.red(` - ${error}`));
5875
+ console.log(chalk13.red(` - ${error}`));
5321
5876
  }
5322
5877
  }
5323
5878
  console.log();
5324
5879
  });
5880
+ registerRefreshAxisCommand(libraryCmd);
5325
5881
  registerSyncCommand(program);
5326
5882
  registerTemplateCommand(program);
5327
5883
  registerCheckCommand(program);