@axis-ds/cli 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,202 @@
1
+ // src/v0.ts
2
+ import chalk from "chalk";
3
+ import fs from "fs-extra";
4
+ import path from "path";
5
+ import prompts from "prompts";
6
+ var V0_CONVERSION_RULES = [
7
+ // import 경로 변환
8
+ { from: /@\/components\/ui\//g, to: "@/components/ui/" },
9
+ { from: /from ['"]@\/lib\/utils['"]/g, to: 'from "@/lib/utils"' },
10
+ // shadcn 컴포넌트를 AXIS 컴포넌트로 매핑
11
+ { from: /from ['"]@\/components\/ui\/button['"]/g, to: 'from "@axis-ds/ui-react/button"' },
12
+ { from: /from ['"]@\/components\/ui\/card['"]/g, to: 'from "@axis-ds/ui-react/card"' },
13
+ { from: /from ['"]@\/components\/ui\/input['"]/g, to: 'from "@axis-ds/ui-react/input"' },
14
+ { from: /from ['"]@\/components\/ui\/badge['"]/g, to: 'from "@axis-ds/ui-react/badge"' },
15
+ { from: /from ['"]@\/components\/ui\/dialog['"]/g, to: 'from "@axis-ds/ui-react/dialog"' },
16
+ { from: /from ['"]@\/components\/ui\/select['"]/g, to: 'from "@axis-ds/ui-react/select"' },
17
+ { from: /from ['"]@\/components\/ui\/tabs['"]/g, to: 'from "@axis-ds/ui-react/tabs"' },
18
+ { from: /from ['"]@\/components\/ui\/label['"]/g, to: 'from "@axis-ds/ui-react/label"' },
19
+ // Lucide 아이콘 유지
20
+ { from: /from ['"]lucide-react['"]/g, to: 'from "lucide-react"' }
21
+ ];
22
+ var V0Client = class {
23
+ // V0 코드 변환
24
+ async convertCode(code, options = {}) {
25
+ let result = code;
26
+ if (!options.preserveImports) {
27
+ for (const rule of V0_CONVERSION_RULES) {
28
+ result = result.replace(rule.from, rule.to);
29
+ }
30
+ }
31
+ if (result.includes("cn(") && !result.includes('from "@/lib/utils"')) {
32
+ result = `import { cn } from "@/lib/utils";
33
+ ${result}`;
34
+ }
35
+ return result;
36
+ }
37
+ // 파일 변환
38
+ async convertFile(filePath, outputPath) {
39
+ const absolutePath = path.resolve(filePath);
40
+ if (!await fs.pathExists(absolutePath)) {
41
+ console.log(chalk.red(`
42
+ \u274C \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${filePath}
43
+ `));
44
+ return;
45
+ }
46
+ const content = await fs.readFile(absolutePath, "utf-8");
47
+ const converted = await this.convertCode(content);
48
+ const outPath = outputPath || absolutePath.replace(".tsx", ".axis.tsx");
49
+ await fs.writeFile(outPath, converted);
50
+ console.log(chalk.green(`
51
+ \u2713 \uBCC0\uD658 \uC644\uB8CC: ${outPath}
52
+ `));
53
+ this.showConversionSummary(content, converted);
54
+ }
55
+ // 변환 요약 출력
56
+ showConversionSummary(original, converted) {
57
+ const changes = [];
58
+ if (original.includes("@/components/ui/") && converted.includes("@axis-ds/ui-react")) {
59
+ changes.push("shadcn/ui \u2192 @axis-ds/ui-react import \uBCC0\uD658");
60
+ }
61
+ if (changes.length > 0) {
62
+ console.log(chalk.bold("\uBCC0\uACBD \uC0AC\uD56D:"));
63
+ changes.forEach((c) => console.log(chalk.gray(` - ${c}`)));
64
+ console.log();
65
+ }
66
+ console.log(chalk.yellow("\uD655\uC778 \uD544\uC694:"));
67
+ console.log(chalk.gray(" - \uCEE4\uC2A4\uD140 \uCEF4\uD3EC\uB10C\uD2B8 import \uACBD\uB85C"));
68
+ console.log(chalk.gray(" - \uD504\uB85C\uC81D\uD2B8\uBCC4 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218"));
69
+ console.log(chalk.gray(" - \uD658\uACBD \uBCC0\uC218 \uBC0F API \uC5D4\uB4DC\uD3EC\uC778\uD2B8\n"));
70
+ }
71
+ // V0 URL에서 가져오기 안내
72
+ async importFromUrl() {
73
+ console.log(chalk.blue("\n\u{1F517} V0 URL\uC5D0\uC11C \uCEF4\uD3EC\uB10C\uD2B8 \uAC00\uC838\uC624\uAE30\n"));
74
+ console.log(chalk.yellow("V0\uB294 \uC9C1\uC811 API\uB97C \uC81C\uACF5\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."));
75
+ console.log(chalk.gray("\uB2E4\uC74C \uBC29\uBC95\uC73C\uB85C \uCF54\uB4DC\uB97C \uAC00\uC838\uC62C \uC218 \uC788\uC2B5\uB2C8\uB2E4:\n"));
76
+ console.log(chalk.bold("\uBC29\uBC95 1: \uC6F9\uC5D0\uC11C \uB2E4\uC6B4\uB85C\uB4DC"));
77
+ console.log(chalk.gray(" 1. v0.app\uC5D0\uC11C \uD504\uB85C\uC81D\uD2B8 \uC5F4\uAE30"));
78
+ console.log(chalk.gray(" 2. \uC6B0\uCE21 \uC0C1\uB2E8 '...' \uBA54\uB274 \uD074\uB9AD"));
79
+ console.log(chalk.gray(" 3. 'Download' \uC120\uD0DD (ZIP \uD30C\uC77C)\n"));
80
+ console.log(chalk.bold("\uBC29\uBC95 2: GitHub \uB3D9\uAE30\uD654"));
81
+ console.log(chalk.gray(" 1. v0.app\uC5D0\uC11C 'Push to GitHub' \uD074\uB9AD"));
82
+ console.log(chalk.gray(" 2. \uC800\uC7A5\uC18C \uC120\uD0DD \uB610\uB294 \uC0DD\uC131"));
83
+ console.log(chalk.gray(" 3. git clone\uC73C\uB85C \uB85C\uCEEC\uC5D0 \uAC00\uC838\uC624\uAE30\n"));
84
+ console.log(chalk.bold("\uBC29\uBC95 3: \uCF54\uB4DC \uBCF5\uC0AC"));
85
+ console.log(chalk.gray(" 1. v0.app\uC5D0\uC11C \uCF54\uB4DC \uD0ED \uC5F4\uAE30"));
86
+ console.log(chalk.gray(" 2. \uD30C\uC77C\uBCC4\uB85C \uCF54\uB4DC \uBCF5\uC0AC"));
87
+ console.log(chalk.gray(" 3. axis-cli v0 convert\uB85C \uBCC0\uD658\n"));
88
+ const { method } = await prompts({
89
+ type: "select",
90
+ name: "method",
91
+ message: "\uC5B4\uB5A4 \uBC29\uBC95\uC744 \uC0AC\uC6A9\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
92
+ choices: [
93
+ { title: "GitHub\uC5D0\uC11C \uD074\uB860", value: "github" },
94
+ { title: "\uB2E4\uC6B4\uB85C\uB4DC\uD55C ZIP \uD30C\uC77C \uBCC0\uD658", value: "zip" },
95
+ { title: "\uD074\uB9BD\uBCF4\uB4DC\uC5D0\uC11C \uBCC0\uD658", value: "clipboard" },
96
+ { title: "\uCDE8\uC18C", value: "cancel" }
97
+ ]
98
+ });
99
+ switch (method) {
100
+ case "github":
101
+ await this.setupGitHubSync();
102
+ break;
103
+ case "zip":
104
+ await this.convertFromZip();
105
+ break;
106
+ case "clipboard":
107
+ await this.convertFromClipboard();
108
+ break;
109
+ }
110
+ }
111
+ // GitHub 동기화 설정
112
+ async setupGitHubSync() {
113
+ console.log(chalk.blue("\n\u{1F504} V0 \u2192 GitHub \uB3D9\uAE30\uD654 \uC124\uC815\n"));
114
+ console.log(chalk.bold("1. V0\uC5D0\uC11C GitHub \uC5F0\uACB0:"));
115
+ console.log(chalk.cyan(" https://v0.app/settings/github\n"));
116
+ console.log(chalk.bold("2. \uD504\uB85C\uC81D\uD2B8 Push:"));
117
+ console.log(chalk.gray(" V0 \uD504\uB85C\uC81D\uD2B8\uC5D0\uC11C 'Push to GitHub' \uBC84\uD2BC \uD074\uB9AD\n"));
118
+ console.log(chalk.bold("3. \uB85C\uCEEC\uC5D0\uC11C \uD074\uB860:"));
119
+ console.log(chalk.cyan(" git clone https://github.com/your-org/v0-project.git\n"));
120
+ console.log(chalk.bold("4. AXIS \uBCC0\uD658:"));
121
+ console.log(chalk.cyan(" axis-cli v0 convert ./v0-project/components/*.tsx\n"));
122
+ console.log(chalk.gray("\uD301: GitHub Actions\uB85C \uC790\uB3D9 \uBCC0\uD658 \uC6CC\uD06C\uD50C\uB85C\uB3C4 \uC124\uC815 \uAC00\uB2A5\uD569\uB2C8\uB2E4.\n"));
123
+ }
124
+ // ZIP 파일에서 변환
125
+ async convertFromZip() {
126
+ console.log(chalk.blue("\n\u{1F4E6} ZIP \uD30C\uC77C\uC5D0\uC11C \uBCC0\uD658\n"));
127
+ const { zipPath } = await prompts({
128
+ type: "text",
129
+ name: "zipPath",
130
+ message: "\uB2E4\uC6B4\uB85C\uB4DC\uD55C ZIP \uD30C\uC77C \uACBD\uB85C:",
131
+ validate: (v) => v.length > 0 ? true : "\uACBD\uB85C\uB97C \uC785\uB825\uD558\uC138\uC694"
132
+ });
133
+ if (!zipPath) return;
134
+ console.log(chalk.yellow("\nZIP \uBCC0\uD658 \uAE30\uB2A5\uC740 \uCD94\uD6C4 \uAD6C\uD604 \uC608\uC815\uC785\uB2C8\uB2E4."));
135
+ console.log(chalk.gray("\uD604\uC7AC\uB294 \uC218\uB3D9\uC73C\uB85C \uC555\uCD95 \uD574\uC81C \uD6C4 convert \uBA85\uB839\uC5B4\uB97C \uC0AC\uC6A9\uD558\uC138\uC694:\n"));
136
+ console.log(chalk.cyan(" unzip v0-project.zip -d ./v0-project"));
137
+ console.log(chalk.cyan(" axis-cli v0 convert ./v0-project/components/*.tsx\n"));
138
+ }
139
+ // 클립보드에서 변환
140
+ async convertFromClipboard() {
141
+ console.log(chalk.blue("\n\u{1F4CB} \uD074\uB9BD\uBCF4\uB4DC\uC5D0\uC11C V0 \uCF54\uB4DC \uBCC0\uD658\n"));
142
+ const { componentName } = await prompts({
143
+ type: "text",
144
+ name: "componentName",
145
+ message: "\uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984 (\uC608: hero-section):",
146
+ validate: (v) => v.length > 0 ? true : "\uC774\uB984\uC744 \uC785\uB825\uD558\uC138\uC694"
147
+ });
148
+ if (!componentName) return;
149
+ console.log(chalk.gray("\nV0\uC5D0\uC11C \uBCF5\uC0AC\uD55C \uCF54\uB4DC\uB97C \uBD99\uC5EC\uB123\uC73C\uC138\uC694."));
150
+ console.log(chalk.gray("(\uC785\uB825 \uC644\uB8CC \uD6C4 \uBE48 \uC904\uC5D0\uC11C Enter \uB450 \uBC88)\n"));
151
+ const { code } = await prompts({
152
+ type: "text",
153
+ name: "code",
154
+ message: "\uCF54\uB4DC:"
155
+ });
156
+ if (!code) {
157
+ console.log(chalk.yellow("\n\uCF54\uB4DC\uAC00 \uC785\uB825\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."));
158
+ return;
159
+ }
160
+ const converted = await this.convertCode(code);
161
+ const outputDir = "./src/components/v0";
162
+ const fileName = `${componentName}.tsx`;
163
+ const filePath = path.join(outputDir, fileName);
164
+ await fs.ensureDir(outputDir);
165
+ await fs.writeFile(filePath, converted);
166
+ console.log(chalk.green(`
167
+ \u2713 ${filePath} \uC800\uC7A5 \uC644\uB8CC`));
168
+ this.showConversionSummary(code, converted);
169
+ }
170
+ // 변환 가이드 출력
171
+ showGuide() {
172
+ console.log(chalk.blue("\n\u{1F4D6} V0 \u2192 AXIS \uBCC0\uD658 \uAC00\uC774\uB4DC\n"));
173
+ console.log(chalk.bold("1. Import \uBCC0\uD658"));
174
+ console.log(chalk.gray(" V0 (shadcn/ui):"));
175
+ console.log(chalk.red(' import { Button } from "@/components/ui/button"'));
176
+ console.log(chalk.gray(" AXIS:"));
177
+ console.log(chalk.green(' import { Button } from "@axis-ds/ui-react/button"\n'));
178
+ console.log(chalk.bold("2. \uD638\uD658 \uCEF4\uD3EC\uB10C\uD2B8"));
179
+ console.log(chalk.gray(" Button, Card, Input, Badge, Dialog, Select, Tabs, Label"));
180
+ console.log(chalk.gray(" \u2192 \uB3D9\uC77C\uD55C props \uC778\uD130\uD398\uC774\uC2A4 \uC720\uC9C0\n"));
181
+ console.log(chalk.bold("3. \uC2A4\uD0C0\uC77C \uBCC0\uD658"));
182
+ console.log(chalk.gray(" Tailwind CSS \uD074\uB798\uC2A4\uB294 \uADF8\uB300\uB85C \uC0AC\uC6A9 \uAC00\uB2A5"));
183
+ console.log(chalk.gray(" AXIS \uD14C\uB9C8 \uBCC0\uC218\uB294 \uC790\uB3D9 \uC801\uC6A9\n"));
184
+ console.log(chalk.bold("4. Agentic UI \uD655\uC7A5"));
185
+ console.log(chalk.gray(" AI/LLM \uAD00\uB828 UI\uC5D0\uB294 @axis-ds/agentic-ui \uC0AC\uC6A9:"));
186
+ console.log(chalk.cyan(" import { StreamingText } from '@axis-ds/agentic-ui'\n"));
187
+ console.log(chalk.bold("5. \uC790\uB3D9 \uBCC0\uD658"));
188
+ console.log(chalk.cyan(" axis-cli v0 convert <file.tsx>\n"));
189
+ }
190
+ };
191
+ function getV0Url(path2 = "") {
192
+ return `https://v0.app${path2}`;
193
+ }
194
+ function isV0Code(code) {
195
+ return code.includes("@/components/ui/") || code.includes("shadcn") || code.includes("from 'lucide-react'");
196
+ }
197
+
198
+ export {
199
+ V0Client,
200
+ getV0Url,
201
+ isV0Code
202
+ };
@@ -0,0 +1,173 @@
1
+ // src/monet.ts
2
+ import chalk from "chalk";
3
+ import fs from "fs-extra";
4
+ import path from "path";
5
+ import prompts from "prompts";
6
+ var MONET_CATEGORIES = [
7
+ { id: "hero", name: "Hero Sections", count: 120 },
8
+ { id: "feature", name: "Feature Sections", count: 191 },
9
+ { id: "testimonial", name: "Testimonials", count: 47 },
10
+ { id: "pricing", name: "Pricing Tables", count: 35 },
11
+ { id: "cta", name: "Call to Action", count: 42 },
12
+ { id: "stats", name: "Statistics", count: 28 },
13
+ { id: "footer", name: "Footers", count: 38 },
14
+ { id: "header", name: "Headers/Navigation", count: 45 },
15
+ { id: "logo-cloud", name: "Logo Clouds", count: 22 },
16
+ { id: "team", name: "Team Sections", count: 31 },
17
+ { id: "faq", name: "FAQ Sections", count: 24 },
18
+ { id: "contact", name: "Contact Forms", count: 29 },
19
+ { id: "newsletter", name: "Newsletter", count: 18 },
20
+ { id: "landing", name: "Full Landing Pages", count: 28 }
21
+ ];
22
+ var MonetClient = class {
23
+ apiKey;
24
+ baseUrl = "https://www.monet.design";
25
+ constructor(apiKey) {
26
+ this.apiKey = apiKey || process.env.MONET_API_KEY;
27
+ }
28
+ // 카테고리 목록 출력
29
+ async listCategories() {
30
+ console.log(chalk.blue("\n\u{1F3A8} Monet Design \uCE74\uD14C\uACE0\uB9AC\n"));
31
+ console.log(chalk.gray("https://monet.design - 1000+ React UI \uCEF4\uD3EC\uB10C\uD2B8\n"));
32
+ for (const cat of MONET_CATEGORIES) {
33
+ console.log(
34
+ ` ${chalk.cyan(cat.id.padEnd(15))} ${cat.name.padEnd(25)} ${chalk.gray(`(${cat.count}\uAC1C)`)}`
35
+ );
36
+ }
37
+ console.log(chalk.gray("\n\uC0AC\uC6A9\uBC95:"));
38
+ console.log(chalk.gray(" axis-cli monet browse <category> # \uCE74\uD14C\uACE0\uB9AC \uCEF4\uD3EC\uB10C\uD2B8 \uBCF4\uAE30"));
39
+ console.log(chalk.gray(" axis-cli monet search <query> # \uCEF4\uD3EC\uB10C\uD2B8 \uAC80\uC0C9\n"));
40
+ }
41
+ // 컴포넌트 검색 (웹 URL 안내)
42
+ async searchComponents(query) {
43
+ console.log(chalk.blue(`
44
+ \u{1F50D} "${query}" \uAC80\uC0C9 \uC911...
45
+ `));
46
+ const searchUrl = `${this.baseUrl}/c?q=${encodeURIComponent(query)}`;
47
+ console.log(chalk.yellow("Monet\uC740 \uC9C1\uC811 API\uB97C \uC81C\uACF5\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."));
48
+ console.log(chalk.gray("\uB2E4\uC74C \uBC29\uBC95\uC73C\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uAC00\uC838\uC62C \uC218 \uC788\uC2B5\uB2C8\uB2E4:\n"));
49
+ console.log(chalk.bold("1. \uC6F9\uC5D0\uC11C \uAC80\uC0C9:"));
50
+ console.log(chalk.cyan(` ${searchUrl}
51
+ `));
52
+ console.log(chalk.bold("2. MCP \uC5F0\uB3D9 (Claude Code):"));
53
+ console.log(chalk.gray(" .claude/mcp.json\uC5D0 monet \uC11C\uBC84 \uD65C\uC131\uD654 \uD6C4"));
54
+ console.log(chalk.cyan(' "monet\uC5D0\uC11C hero \uCEF4\uD3EC\uB10C\uD2B8 \uCC3E\uC544\uC918"'));
55
+ console.log(chalk.gray(" \u2192 API \uD0A4 \uD544\uC694: https://monet.design/mcp\n"));
56
+ console.log(chalk.bold("3. \uC218\uB3D9 \uBCF5\uC0AC-\uBD99\uC5EC\uB123\uAE30:"));
57
+ console.log(chalk.gray(" \uC6F9\uC5D0\uC11C \uCEF4\uD3EC\uB10C\uD2B8 \uC120\uD0DD \u2192 Copy Code \u2192 \uD504\uB85C\uC81D\uD2B8\uC5D0 \uBD99\uC5EC\uB123\uAE30\n"));
58
+ }
59
+ // 카테고리별 컴포넌트 브라우징
60
+ async browseCategory(category) {
61
+ const cat = MONET_CATEGORIES.find((c) => c.id === category);
62
+ if (!cat) {
63
+ console.log(chalk.red(`
64
+ \u274C '${category}' \uCE74\uD14C\uACE0\uB9AC\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
65
+ `));
66
+ console.log(chalk.gray("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uCE74\uD14C\uACE0\uB9AC:"));
67
+ MONET_CATEGORIES.forEach((c) => console.log(chalk.cyan(` ${c.id}`)));
68
+ return;
69
+ }
70
+ console.log(chalk.blue(`
71
+ \u{1F4C2} ${cat.name} (${cat.count}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8)
72
+ `));
73
+ const browseUrl = `${this.baseUrl}/c?category=${category}`;
74
+ console.log(chalk.gray("\uC6F9\uC5D0\uC11C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD655\uC778\uD558\uC138\uC694:"));
75
+ console.log(chalk.cyan(`${browseUrl}
76
+ `));
77
+ console.log(chalk.bold("\uC778\uAE30 \uCEF4\uD3EC\uB10C\uD2B8 \uC608\uC2DC:"));
78
+ const examples = this.getCategoryExamples(category);
79
+ examples.forEach((ex) => {
80
+ console.log(` ${chalk.cyan(ex.id.padEnd(30))} ${chalk.gray(ex.desc)}`);
81
+ });
82
+ console.log(chalk.gray("\n\uCEF4\uD3EC\uB10C\uD2B8 \uAC00\uC838\uC624\uAE30:"));
83
+ console.log(chalk.gray(" 1. \uC6F9\uC5D0\uC11C \uCEF4\uD3EC\uB10C\uD2B8 \uC120\uD0DD"));
84
+ console.log(chalk.gray(" 2. Copy Code \uBC84\uD2BC \uD074\uB9AD"));
85
+ console.log(chalk.gray(" 3. axis-cli monet import \uC2E4\uD589\n"));
86
+ }
87
+ // 카테고리별 예시 컴포넌트
88
+ getCategoryExamples(category) {
89
+ const examples = {
90
+ hero: [
91
+ { id: "hero-with-image", desc: "\uC774\uBBF8\uC9C0 \uBC30\uACBD \uD788\uC5B4\uB85C" },
92
+ { id: "hero-centered", desc: "\uC911\uC559 \uC815\uB82C \uD788\uC5B4\uB85C" },
93
+ { id: "hero-split", desc: "\uBD84\uD560 \uB808\uC774\uC544\uC6C3 \uD788\uC5B4\uB85C" }
94
+ ],
95
+ feature: [
96
+ { id: "feature-grid", desc: "\uADF8\uB9AC\uB4DC \uD615\uC2DD \uAE30\uB2A5 \uC18C\uAC1C" },
97
+ { id: "feature-alternating", desc: "\uAD50\uCC28 \uB808\uC774\uC544\uC6C3 \uAE30\uB2A5" },
98
+ { id: "feature-icons", desc: "\uC544\uC774\uCF58 \uAE30\uBC18 \uAE30\uB2A5" }
99
+ ],
100
+ pricing: [
101
+ { id: "pricing-three-tiers", desc: "3\uB2E8 \uC694\uAE08\uC81C" },
102
+ { id: "pricing-comparison", desc: "\uBE44\uAD50 \uD14C\uC774\uBE14 \uC694\uAE08\uC81C" },
103
+ { id: "pricing-toggle", desc: "\uC6D4/\uC5F0 \uD1A0\uAE00 \uC694\uAE08\uC81C" }
104
+ ],
105
+ landing: [
106
+ { id: "deepcon-ai-landing", desc: "AI SaaS \uB79C\uB529\uD398\uC774\uC9C0" },
107
+ { id: "saas-landing", desc: "SaaS \uC2A4\uD0C0\uD130 \uB79C\uB529" },
108
+ { id: "agency-landing", desc: "\uC5D0\uC774\uC804\uC2DC \uB79C\uB529\uD398\uC774\uC9C0" }
109
+ ]
110
+ };
111
+ return examples[category] || [{ id: `${category}-basic`, desc: "\uAE30\uBCF8 \uD15C\uD50C\uB9BF" }];
112
+ }
113
+ // 클립보드에서 Monet 코드 가져오기
114
+ async importFromClipboard() {
115
+ console.log(chalk.blue("\n\u{1F4CB} \uD074\uB9BD\uBCF4\uB4DC\uC5D0\uC11C Monet \uCEF4\uD3EC\uB10C\uD2B8 \uAC00\uC838\uC624\uAE30\n"));
116
+ console.log(chalk.yellow("\uC900\uBE44 \uB2E8\uACC4:"));
117
+ console.log(chalk.gray(" 1. monet.design\uC5D0\uC11C \uCEF4\uD3EC\uB10C\uD2B8 \uC120\uD0DD"));
118
+ console.log(chalk.gray(" 2. 'Copy Code' \uBC84\uD2BC\uC73C\uB85C \uCF54\uB4DC \uBCF5\uC0AC"));
119
+ console.log(chalk.gray(" 3. \uC774 \uBA85\uB839\uC5B4 \uC2E4\uD589\n"));
120
+ const { componentName } = await prompts({
121
+ type: "text",
122
+ name: "componentName",
123
+ message: "\uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984 (\uC608: hero-section):",
124
+ validate: (v) => v.length > 0 ? true : "\uC774\uB984\uC744 \uC785\uB825\uD558\uC138\uC694"
125
+ });
126
+ if (!componentName) return;
127
+ const { componentCode } = await prompts({
128
+ type: "text",
129
+ name: "componentCode",
130
+ message: "\uBCF5\uC0AC\uD55C \uCF54\uB4DC\uB97C \uBD99\uC5EC\uB123\uC73C\uC138\uC694 (\uD55C \uC904\uB85C):"
131
+ });
132
+ if (!componentCode) {
133
+ console.log(chalk.yellow("\n\uCF54\uB4DC\uAC00 \uC785\uB825\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."));
134
+ return;
135
+ }
136
+ const configPath = path.resolve("axis.config.json");
137
+ let componentsDir = "./src/components/monet";
138
+ if (await fs.pathExists(configPath)) {
139
+ const config = await fs.readJSON(configPath);
140
+ componentsDir = config.monetDir || path.join(path.dirname(config.componentsDir), "monet");
141
+ }
142
+ const fileName = `${componentName}.tsx`;
143
+ const filePath = path.join(componentsDir, fileName);
144
+ await fs.ensureDir(componentsDir);
145
+ await fs.writeFile(filePath, componentCode);
146
+ console.log(chalk.green(`
147
+ \u2713 ${filePath} \uC800\uC7A5 \uC644\uB8CC`));
148
+ console.log(chalk.gray("\n\uB2E4\uC74C \uB2E8\uACC4:"));
149
+ console.log(chalk.gray(" 1. \uD30C\uC77C\uC744 \uC5F4\uC5B4 import \uACBD\uB85C \uC218\uC815"));
150
+ console.log(chalk.gray(" 2. \uD544\uC694\uD55C \uC758\uC874\uC131 \uC124\uCE58 (pnpm add ...)"));
151
+ console.log(chalk.gray(" 3. \uCEF4\uD3EC\uB10C\uD2B8 \uC0AC\uC6A9\n"));
152
+ }
153
+ };
154
+ function getMonetUrl(path2) {
155
+ return `https://monet.design${path2}`;
156
+ }
157
+ function getMonetMcpConfig() {
158
+ return {
159
+ monet: {
160
+ url: "https://www.monet.design/api/remote/mcp",
161
+ headers: {
162
+ Authorization: "Bearer ${MONET_API_KEY}"
163
+ }
164
+ }
165
+ };
166
+ }
167
+
168
+ export {
169
+ MONET_CATEGORIES,
170
+ MonetClient,
171
+ getMonetUrl,
172
+ getMonetMcpConfig
173
+ };
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node