@beaket/ui 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,7 +18,36 @@ npx @beaket/ui add button
18
18
 
19
19
  ## Commands
20
20
 
21
- | Command | Description |
22
- | ----------------- | --------------------------- |
23
- | `init` | Setup project configuration |
24
- | `add <component>` | Add a component |
21
+ | Command | Description |
22
+ | --------------------------- | -------------------------------- |
23
+ | `init` | Setup project configuration |
24
+ | `init -y` | Setup with defaults (no prompts) |
25
+ | `add <component>` | Add a component |
26
+ | `add <component> [more...]` | Add multiple components at once |
27
+
28
+ ## Examples
29
+
30
+ ```bash
31
+ # Initialize with prompts
32
+ npx @beaket/ui init
33
+
34
+ # Initialize with defaults (skip prompts)
35
+ npx @beaket/ui init -y
36
+
37
+ # Add a single component
38
+ npx @beaket/ui add button
39
+
40
+ # Add multiple components
41
+ npx @beaket/ui add alert button label input
42
+
43
+ # Overwrite existing files
44
+ npx @beaket/ui add button --overwrite
45
+ ```
46
+
47
+ ## Help
48
+
49
+ ```bash
50
+ npx @beaket/ui --help
51
+ npx @beaket/ui init --help
52
+ npx @beaket/ui add --help
53
+ ```
package/dist/index.js ADDED
@@ -0,0 +1,308 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command } from "commander";
5
+
6
+ // src/commands/add.ts
7
+ import path3 from "path";
8
+ import pc from "picocolors";
9
+
10
+ // src/utils/config.ts
11
+ import fs from "fs-extra";
12
+ import path from "path";
13
+ var CONFIG_FILE = "beaket.ui.json";
14
+ async function getConfig() {
15
+ const configPath = path.join(process.cwd(), CONFIG_FILE);
16
+ if (!await fs.pathExists(configPath)) {
17
+ return null;
18
+ }
19
+ const content = await fs.readFile(configPath, "utf-8");
20
+ return JSON.parse(content);
21
+ }
22
+ async function writeConfig(config) {
23
+ const configPath = path.join(process.cwd(), CONFIG_FILE);
24
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2));
25
+ }
26
+
27
+ // src/utils/files.ts
28
+ import { spawn } from "child_process";
29
+ import fs2 from "fs-extra";
30
+ import path2 from "path";
31
+ import prompts from "prompts";
32
+ async function writeComponentFiles(baseDir, files, overwrite = false) {
33
+ const written = [];
34
+ const skipped = [];
35
+ for (const file of files) {
36
+ const relativePath = file.path.replace(/^components\//, "");
37
+ const targetPath = path2.join(baseDir, relativePath);
38
+ if (await fs2.pathExists(targetPath)) {
39
+ if (!overwrite) {
40
+ const { confirm } = await prompts({
41
+ type: "confirm",
42
+ name: "confirm",
43
+ message: `${path2.basename(targetPath)} already exists. Overwrite?`,
44
+ initial: false
45
+ });
46
+ if (!confirm) {
47
+ skipped.push(targetPath);
48
+ continue;
49
+ }
50
+ }
51
+ }
52
+ await fs2.ensureDir(path2.dirname(targetPath));
53
+ await fs2.writeFile(targetPath, file.content);
54
+ written.push(targetPath);
55
+ }
56
+ return { written, skipped };
57
+ }
58
+ async function installDependencies(deps) {
59
+ const packageManager = await detectPackageManager();
60
+ const installCmd = packageManager === "npm" ? "install" : "add";
61
+ return new Promise((resolve, reject) => {
62
+ const child = spawn(packageManager, [installCmd, ...deps], {
63
+ stdio: "inherit"
64
+ });
65
+ child.on("close", (code) => {
66
+ if (code === 0) {
67
+ resolve();
68
+ } else {
69
+ reject(new Error(`Failed to install dependencies (code ${code})`));
70
+ }
71
+ });
72
+ });
73
+ }
74
+ async function detectPackageManager() {
75
+ const cwd = process.cwd();
76
+ if (await fs2.pathExists(path2.join(cwd, "pnpm-lock.yaml"))) {
77
+ return "pnpm";
78
+ }
79
+ if (await fs2.pathExists(path2.join(cwd, "yarn.lock"))) {
80
+ return "yarn";
81
+ }
82
+ if (await fs2.pathExists(path2.join(cwd, "bun.lock"))) {
83
+ return "bun";
84
+ }
85
+ return "npm";
86
+ }
87
+
88
+ // src/utils/registry.ts
89
+ var GITHUB_RAW_BASE = "https://raw.githubusercontent.com/beaket/ui/main";
90
+ async function fetchRegistry() {
91
+ const url = `${GITHUB_RAW_BASE}/registry/registry.json`;
92
+ try {
93
+ const response = await fetch(url);
94
+ if (!response.ok) {
95
+ throw new Error(`HTTP ${response.status}`);
96
+ }
97
+ return await response.json();
98
+ } catch (error) {
99
+ throw new Error(`Failed to fetch registry from ${url}. Make sure the repository is public.`);
100
+ }
101
+ }
102
+ async function fetchComponent(componentDef) {
103
+ const files = [];
104
+ for (const filePath of componentDef.files) {
105
+ const url = `${GITHUB_RAW_BASE}/src/${filePath}`;
106
+ try {
107
+ const response = await fetch(url);
108
+ if (!response.ok) {
109
+ throw new Error(`HTTP ${response.status}`);
110
+ }
111
+ const content = await response.text();
112
+ files.push({ path: filePath, content });
113
+ } catch (error) {
114
+ throw new Error(`Failed to fetch ${filePath} from ${url}`);
115
+ }
116
+ }
117
+ return files;
118
+ }
119
+
120
+ // src/commands/add.ts
121
+ async function add(componentNames, options) {
122
+ console.log();
123
+ const config = await getConfig();
124
+ if (!config) {
125
+ console.log(pc.red("Error:"), "beaket.ui.json not found.");
126
+ console.log("Run", pc.cyan("npx @beaket/ui init"), "first.");
127
+ process.exit(1);
128
+ }
129
+ const registry = await fetchRegistry();
130
+ console.log(pc.green("\u2714"), "Checking registry.");
131
+ const notFound = [];
132
+ const componentDefs = componentNames.map((name) => {
133
+ const def = registry.components.find((c) => c.name === name);
134
+ if (!def) notFound.push(name);
135
+ return def;
136
+ });
137
+ if (notFound.length > 0) {
138
+ console.log(pc.red("Error:"), `Component(s) not found: ${notFound.join(", ")}`);
139
+ console.log();
140
+ console.log("Available components:");
141
+ registry.components.forEach((c) => {
142
+ console.log(` - ${c.name}`);
143
+ });
144
+ process.exit(1);
145
+ }
146
+ const allDependencies = /* @__PURE__ */ new Set();
147
+ for (const def of componentDefs) {
148
+ if (def) {
149
+ for (const dep of def.dependencies) {
150
+ allDependencies.add(dep);
151
+ }
152
+ }
153
+ }
154
+ if (allDependencies.size > 0) {
155
+ await installDependencies([...allDependencies]);
156
+ console.log(pc.green("\u2714"), "Installing dependencies.");
157
+ }
158
+ const componentsDir = path3.join(process.cwd(), config.components);
159
+ const allWritten = [];
160
+ const allSkipped = [];
161
+ for (const def of componentDefs) {
162
+ if (!def) continue;
163
+ const files = await fetchComponent(def);
164
+ const { written, skipped } = await writeComponentFiles(componentsDir, files, options.overwrite);
165
+ allWritten.push(...written);
166
+ allSkipped.push(...skipped);
167
+ }
168
+ if (allSkipped.length > 0) {
169
+ console.log(
170
+ pc.yellow("\u2139"),
171
+ `Skipped ${allSkipped.length} file(s): (use --overwrite to overwrite)`
172
+ );
173
+ allSkipped.forEach((f) => console.log(` - ${f}`));
174
+ }
175
+ if (allWritten.length === 0) {
176
+ console.log();
177
+ return;
178
+ }
179
+ console.log();
180
+ console.log("Added:");
181
+ allWritten.forEach((f) => console.log(pc.cyan(` ${f}`)));
182
+ console.log();
183
+ }
184
+
185
+ // src/commands/init.ts
186
+ import fs3 from "fs-extra";
187
+ import path4 from "path";
188
+ import pc2 from "picocolors";
189
+ import prompts2 from "prompts";
190
+
191
+ // ../../src/css-variables.css
192
+ var css_variables_default = "/*\n * Beaket UI Design System - Core Variables\n * This file is the single source of truth for CSS variables.\n * Used by: styles.css (via @import) and CLI init command (via build script)\n */\n\n@theme {\n --color-inverse: var(--paper);\n --shadow-offset: 2px 2px 0px 0px var(--chrome);\n --shadow-offset-dark: 2px 2px 0px 0px var(--aluminum);\n --shadow-offset-hover: 3px 3px 0px 0px var(--chrome);\n --shadow-offset-active: 1px 1px 0px 0px var(--chrome);\n}\n\n:root {\n /* Neutral palette */\n --graphite: #0d0d0d;\n --ink: #1a1a1a;\n --branch: #1c1f24;\n --iron: #2d2d2d;\n --slate: #404040;\n --zinc: #525252;\n --steel: #595959;\n --aluminum: #9e9e9e;\n --chrome: #d0d0d0;\n --silver: #dedede;\n --platinum: #e8e8e8;\n --frost: #f5f5f5;\n --paper: #fafafa;\n\n /* Signal colors */\n --signal-blue: #00449e;\n --signal-red: #c41e1e;\n --signal-red-hover: #b71c1c;\n --signal-red-active: #9a1919;\n --signal-green: #00794c;\n --signal-green-hover: #0f5f42;\n --signal-green-active: #0a4a32;\n --signal-amber: #b8860b;\n --signal-amber-hover: #9a7209;\n --signal-amber-active: #7a5a07;\n --signal-purple: #6f2da8;\n --signal-cyan: #1a6b7c;\n}\n";
193
+
194
+ // src/commands/init.ts
195
+ async function detectAliasPath() {
196
+ const cwd = process.cwd();
197
+ for (const configFile of ["tsconfig.json", "tsconfig.app.json"]) {
198
+ const configPath = path4.join(cwd, configFile);
199
+ if (await fs3.pathExists(configPath)) {
200
+ try {
201
+ const content = await fs3.readFile(configPath, "utf-8");
202
+ const tsconfig = JSON.parse(content);
203
+ const paths = tsconfig.compilerOptions?.paths;
204
+ if (paths?.["@/*"]) {
205
+ const aliasPath = paths["@/*"][0];
206
+ const prefix = aliasPath.replace(/^\.\/|\/?\*$/g, "");
207
+ return prefix ? `${prefix}/components/ui` : "components/ui";
208
+ }
209
+ } catch {
210
+ }
211
+ }
212
+ }
213
+ const pkgPath = path4.join(cwd, "package.json");
214
+ if (await fs3.pathExists(pkgPath)) {
215
+ try {
216
+ const content = await fs3.readFile(pkgPath, "utf-8");
217
+ const pkg = JSON.parse(content);
218
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
219
+ if (deps.next) {
220
+ return "components/ui";
221
+ }
222
+ } catch {
223
+ }
224
+ }
225
+ return "src/components/ui";
226
+ }
227
+ async function detectCssPath() {
228
+ const cwd = process.cwd();
229
+ const pkgPath = path4.join(cwd, "package.json");
230
+ if (await fs3.pathExists(pkgPath)) {
231
+ try {
232
+ const content = await fs3.readFile(pkgPath, "utf-8");
233
+ const pkg = JSON.parse(content);
234
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
235
+ if (deps.next) {
236
+ return "app/globals.css";
237
+ }
238
+ } catch {
239
+ }
240
+ }
241
+ return "src/index.css";
242
+ }
243
+ async function init(options) {
244
+ console.log();
245
+ console.log(pc2.bold("Initializing Beaket UI..."));
246
+ console.log();
247
+ const detectedComponentsPath = await detectAliasPath();
248
+ const detectedCssPath = await detectCssPath();
249
+ let response;
250
+ if (options.yes) {
251
+ response = { components: detectedComponentsPath, css: detectedCssPath };
252
+ } else {
253
+ response = await prompts2([
254
+ {
255
+ type: "text",
256
+ name: "components",
257
+ message: "Where should components be installed?",
258
+ initial: detectedComponentsPath
259
+ },
260
+ {
261
+ type: "text",
262
+ name: "css",
263
+ message: "Where is your Tailwind CSS file?",
264
+ initial: detectedCssPath
265
+ }
266
+ ]);
267
+ if (!response.components) {
268
+ console.log(pc2.red("Cancelled."));
269
+ process.exit(1);
270
+ }
271
+ }
272
+ const config = {
273
+ $schema: "https://beaket.dev/schema.json",
274
+ components: response.components
275
+ };
276
+ await writeConfig(config);
277
+ console.log(pc2.green("\u2714"), "Created beaket.ui.json");
278
+ if (response.css) {
279
+ const cssPath = path4.join(process.cwd(), response.css);
280
+ if (await fs3.pathExists(cssPath)) {
281
+ const cssContent = await fs3.readFile(cssPath, "utf-8");
282
+ if (!cssContent.includes("Beaket UI Design System")) {
283
+ await fs3.writeFile(cssPath, cssContent + css_variables_default);
284
+ console.log(pc2.green("\u2714"), `Added CSS variables to ${response.css}`);
285
+ } else {
286
+ console.log(pc2.yellow("\u2139"), "CSS variables already exist");
287
+ }
288
+ } else {
289
+ console.log(pc2.yellow("!"), `CSS file not found: ${response.css}`);
290
+ console.log(" Add CSS variables manually:");
291
+ console.log(pc2.cyan(" https://beaket.github.io/ui/installation"));
292
+ }
293
+ }
294
+ console.log();
295
+ console.log(pc2.green("Done!"), "Beaket UI is ready.");
296
+ console.log();
297
+ console.log("Add components:");
298
+ console.log(pc2.cyan(" npx @beaket/ui add button"));
299
+ console.log();
300
+ }
301
+
302
+ // src/index.ts
303
+ var version = "1.9.0";
304
+ var program = new Command();
305
+ program.name("@beaket/ui").description("CLI for adding Beaket UI components to your project").version(version);
306
+ program.command("init").description("Initialize Beaket UI in your project").option("-y, --yes", "Use defaults without prompting").action(init);
307
+ program.command("add").description("Add components to your project").argument("<components...>", "Component names to add").option("-o, --overwrite", "Overwrite existing files").action(add);
308
+ program.parse();
package/package.json CHANGED
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "name": "@beaket/ui",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "CLI tool for adding Beaket UI components to your project",
5
5
  "type": "module",
6
6
  "bin": {
7
- "ui": "./bin/cli.js"
7
+ "ui": "./dist/index.js"
8
8
  },
9
9
  "files": [
10
- "bin",
11
- "src"
10
+ "dist"
12
11
  ],
13
12
  "keywords": [
14
13
  "react",
@@ -31,9 +30,11 @@
31
30
  "devDependencies": {
32
31
  "@types/fs-extra": "^11.0.4",
33
32
  "@types/node": "^25.0.3",
34
- "@types/prompts": "^2.4.9"
33
+ "@types/prompts": "^2.4.9",
34
+ "tsup": "^8.5.1"
35
35
  },
36
36
  "scripts": {
37
+ "build": "tsup",
37
38
  "typecheck": "tsc --noEmit"
38
39
  }
39
40
  }
package/bin/cli.js DELETED
@@ -1,11 +0,0 @@
1
- #!/usr/bin/env node
2
- import { spawnSync } from "child_process";
3
- import { dirname, join } from "path";
4
- import { fileURLToPath } from "url";
5
-
6
- const __dirname = dirname(fileURLToPath(import.meta.url));
7
- const script = join(__dirname, "..", "src", "index.ts");
8
-
9
- spawnSync("npx", ["tsx", script, ...process.argv.slice(2)], {
10
- stdio: "inherit",
11
- });
@@ -1,69 +0,0 @@
1
- import path from "path";
2
- import pc from "picocolors";
3
- import { getConfig } from "../utils/config.ts";
4
- import { installDependencies, writeComponentFiles } from "../utils/files.ts";
5
- import { fetchComponent, fetchRegistry } from "../utils/registry.ts";
6
-
7
- interface AddOptions {
8
- overwrite?: boolean;
9
- }
10
-
11
- export async function add(componentName: string, options: AddOptions) {
12
- console.log();
13
-
14
- // Read config
15
- const config = await getConfig();
16
- if (!config) {
17
- console.log(pc.red("Error:"), "beaket.ui.json not found.");
18
- console.log("Run", pc.cyan("npx @beaket/ui init"), "first.");
19
- process.exit(1);
20
- }
21
-
22
- // Fetch registry
23
- const registry = await fetchRegistry();
24
- console.log(pc.green("✔"), "Checking registry.");
25
-
26
- const componentDef = registry.components.find((c) => c.name === componentName);
27
-
28
- if (!componentDef) {
29
- console.log(pc.red("Error:"), `Component "${componentName}" not found.`);
30
- console.log();
31
- console.log("Available components:");
32
- registry.components.forEach((c) => {
33
- console.log(` - ${c.name}`);
34
- });
35
- process.exit(1);
36
- }
37
-
38
- // Install dependencies
39
- if (componentDef.dependencies.length > 0) {
40
- await installDependencies(componentDef.dependencies);
41
- console.log(pc.green("✔"), "Installing dependencies.");
42
- }
43
-
44
- // Fetch component files
45
- const files = await fetchComponent(componentDef);
46
-
47
- // Write files
48
- const componentsDir = path.join(process.cwd(), config.components);
49
- const { written, skipped } = await writeComponentFiles(componentsDir, files, options.overwrite);
50
-
51
- // Show skipped files
52
- if (skipped.length > 0) {
53
- console.log(
54
- pc.yellow("ℹ"),
55
- `Skipped ${skipped.length} file(s): (use --overwrite to overwrite)`,
56
- );
57
- skipped.forEach((f) => console.log(` - ${f}`));
58
- }
59
-
60
- if (written.length === 0) {
61
- console.log();
62
- return;
63
- }
64
-
65
- console.log();
66
- console.log("Added:");
67
- written.forEach((f) => console.log(pc.cyan(` ${f}`)));
68
- console.log();
69
- }
@@ -1,180 +0,0 @@
1
- import fs from "fs-extra";
2
- import path from "path";
3
- import pc from "picocolors";
4
- import prompts from "prompts";
5
- import { writeConfig, type BeaketConfig } from "../utils/config.ts";
6
-
7
- interface TsConfig {
8
- compilerOptions?: {
9
- paths?: Record<string, string[]>;
10
- };
11
- }
12
-
13
- async function detectAliasPath(): Promise<string> {
14
- const cwd = process.cwd();
15
-
16
- // Try to read tsconfig.json or tsconfig.app.json
17
- for (const configFile of ["tsconfig.json", "tsconfig.app.json"]) {
18
- const configPath = path.join(cwd, configFile);
19
- if (await fs.pathExists(configPath)) {
20
- try {
21
- const content = await fs.readFile(configPath, "utf-8");
22
- const tsconfig: TsConfig = JSON.parse(content);
23
- const paths = tsconfig.compilerOptions?.paths;
24
- if (paths?.["@/*"]) {
25
- const aliasPath = paths["@/*"][0];
26
- // "./src/*" -> "src", "./*" -> ""
27
- const prefix = aliasPath.replace(/^\.\/|\/?\*$/g, "");
28
- return prefix ? `${prefix}/components/ui` : "components/ui";
29
- }
30
- } catch {
31
- // Ignore parse errors
32
- }
33
- }
34
- }
35
-
36
- // Fallback: detect from package.json
37
- const pkgPath = path.join(cwd, "package.json");
38
- if (await fs.pathExists(pkgPath)) {
39
- try {
40
- const content = await fs.readFile(pkgPath, "utf-8");
41
- const pkg = JSON.parse(content);
42
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
43
- // Next.js uses root alias by default
44
- if (deps.next) {
45
- return "components/ui";
46
- }
47
- } catch {
48
- // Ignore parse errors
49
- }
50
- }
51
-
52
- // Default to src/components/ui (Vite style)
53
- return "src/components/ui";
54
- }
55
-
56
- async function detectCssPath(): Promise<string> {
57
- const cwd = process.cwd();
58
- const pkgPath = path.join(cwd, "package.json");
59
-
60
- if (await fs.pathExists(pkgPath)) {
61
- try {
62
- const content = await fs.readFile(pkgPath, "utf-8");
63
- const pkg = JSON.parse(content);
64
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
65
- if (deps.next) {
66
- return "app/globals.css";
67
- }
68
- } catch {
69
- // Ignore parse errors
70
- }
71
- }
72
-
73
- return "src/index.css";
74
- }
75
-
76
- const CSS_VARIABLES = `
77
- /* Beaket UI Design System */
78
- @theme {
79
- --color-inverse: var(--paper);
80
- --shadow-offset: 2px 2px 0px 0px var(--chrome);
81
- --shadow-offset-dark: 2px 2px 0px 0px var(--aluminum);
82
- --shadow-offset-hover: 3px 3px 0px 0px var(--chrome);
83
- --shadow-offset-active: 1px 1px 0px 0px var(--chrome);
84
- }
85
-
86
- :root {
87
- --graphite: #0d0d0d;
88
- --ink: #1a1a1a;
89
- --branch: #1c1f24;
90
- --iron: #2d2d2d;
91
- --slate: #404040;
92
- --zinc: #525252;
93
- --steel: #595959;
94
- --aluminum: #9e9e9e;
95
- --chrome: #d0d0d0;
96
- --silver: #dedede;
97
- --platinum: #e8e8e8;
98
- --frost: #f5f5f5;
99
- --paper: #fafafa;
100
- --signal-blue: #00449e;
101
- --signal-red: #c41e1e;
102
- --signal-green: #00794c;
103
- --signal-amber: #b8860b;
104
- --signal-purple: #6f2da8;
105
- --signal-cyan: #1a6b7c;
106
- }
107
- `;
108
-
109
- interface InitOptions {
110
- yes?: boolean;
111
- }
112
-
113
- export async function init(options: InitOptions) {
114
- console.log();
115
- console.log(pc.bold("Initializing Beaket UI..."));
116
- console.log();
117
-
118
- const detectedComponentsPath = await detectAliasPath();
119
- const detectedCssPath = await detectCssPath();
120
-
121
- let response: { components: string; css: string };
122
-
123
- if (options.yes) {
124
- response = { components: detectedComponentsPath, css: detectedCssPath };
125
- } else {
126
- response = await prompts([
127
- {
128
- type: "text",
129
- name: "components",
130
- message: "Where should components be installed?",
131
- initial: detectedComponentsPath,
132
- },
133
- {
134
- type: "text",
135
- name: "css",
136
- message: "Where is your Tailwind CSS file?",
137
- initial: detectedCssPath,
138
- },
139
- ]);
140
-
141
- if (!response.components) {
142
- console.log(pc.red("Cancelled."));
143
- process.exit(1);
144
- }
145
- }
146
-
147
- // Write beaket.ui.json (only components path)
148
- const config: BeaketConfig = {
149
- $schema: "https://beaket.dev/schema.json",
150
- components: response.components,
151
- };
152
-
153
- await writeConfig(config);
154
- console.log(pc.green("✔"), "Created beaket.ui.json");
155
-
156
- // Inject CSS variables into Tailwind CSS file
157
- if (response.css) {
158
- const cssPath = path.join(process.cwd(), response.css);
159
- if (await fs.pathExists(cssPath)) {
160
- const cssContent = await fs.readFile(cssPath, "utf-8");
161
- if (!cssContent.includes("Beaket UI Design System")) {
162
- await fs.writeFile(cssPath, cssContent + CSS_VARIABLES);
163
- console.log(pc.green("✔"), `Added CSS variables to ${response.css}`);
164
- } else {
165
- console.log(pc.yellow("ℹ"), "CSS variables already exist");
166
- }
167
- } else {
168
- console.log(pc.yellow("!"), `CSS file not found: ${response.css}`);
169
- console.log(" Add CSS variables manually:");
170
- console.log(pc.cyan(" https://beaket.github.io/ui/installation"));
171
- }
172
- }
173
-
174
- console.log();
175
- console.log(pc.green("Done!"), "Beaket UI is ready.");
176
- console.log();
177
- console.log("Add components:");
178
- console.log(pc.cyan(" npx @beaket/ui add button"));
179
- console.log();
180
- }
package/src/index.ts DELETED
@@ -1,31 +0,0 @@
1
- #!/usr/bin/env -S npx tsx
2
- // Test comment for changeset verification
3
- import { Command } from "commander";
4
- import { createRequire } from "module";
5
- import { add } from "./commands/add.ts";
6
- import { init } from "./commands/init.ts";
7
-
8
- const require = createRequire(import.meta.url);
9
- const { version } = require("../package.json");
10
-
11
- const program = new Command();
12
-
13
- program
14
- .name("@beaket/ui")
15
- .description("CLI for adding Beaket UI components to your project")
16
- .version(version);
17
-
18
- program
19
- .command("init")
20
- .description("Initialize Beaket UI in your project")
21
- .option("-y, --yes", "Use defaults without prompting")
22
- .action(init);
23
-
24
- program
25
- .command("add")
26
- .description("Add a component to your project")
27
- .argument("<component>", "Component name to add")
28
- .option("-o, --overwrite", "Overwrite existing files")
29
- .action(add);
30
-
31
- program.parse();
@@ -1,25 +0,0 @@
1
- import fs from "fs-extra";
2
- import path from "path";
3
-
4
- export interface BeaketConfig {
5
- $schema?: string;
6
- components: string;
7
- }
8
-
9
- const CONFIG_FILE = "beaket.ui.json";
10
-
11
- export async function getConfig(): Promise<BeaketConfig | null> {
12
- const configPath = path.join(process.cwd(), CONFIG_FILE);
13
-
14
- if (!(await fs.pathExists(configPath))) {
15
- return null;
16
- }
17
-
18
- const content = await fs.readFile(configPath, "utf-8");
19
- return JSON.parse(content) as BeaketConfig;
20
- }
21
-
22
- export async function writeConfig(config: BeaketConfig): Promise<void> {
23
- const configPath = path.join(process.cwd(), CONFIG_FILE);
24
- await fs.writeFile(configPath, JSON.stringify(config, null, 2));
25
- }
@@ -1,82 +0,0 @@
1
- import { spawn } from "child_process";
2
- import fs from "fs-extra";
3
- import path from "path";
4
- import prompts from "prompts";
5
- import type { ComponentFile } from "./registry.ts";
6
-
7
- export interface WriteResult {
8
- written: string[];
9
- skipped: string[];
10
- }
11
-
12
- export async function writeComponentFiles(
13
- baseDir: string,
14
- files: ComponentFile[],
15
- overwrite: boolean = false,
16
- ): Promise<WriteResult> {
17
- const written: string[] = [];
18
- const skipped: string[] = [];
19
-
20
- for (const file of files) {
21
- // Transform file path: components/button.tsx -> button.tsx
22
- const relativePath = file.path.replace(/^components\//, "");
23
- const targetPath = path.join(baseDir, relativePath);
24
-
25
- // Check if file exists
26
- if (await fs.pathExists(targetPath)) {
27
- if (!overwrite) {
28
- const { confirm } = await prompts({
29
- type: "confirm",
30
- name: "confirm",
31
- message: `${path.basename(targetPath)} already exists. Overwrite?`,
32
- initial: false,
33
- });
34
- if (!confirm) {
35
- skipped.push(targetPath);
36
- continue;
37
- }
38
- }
39
- }
40
-
41
- await fs.ensureDir(path.dirname(targetPath));
42
- await fs.writeFile(targetPath, file.content);
43
- written.push(targetPath);
44
- }
45
-
46
- return { written, skipped };
47
- }
48
-
49
- export async function installDependencies(deps: string[]): Promise<void> {
50
- const packageManager = await detectPackageManager();
51
- const installCmd = packageManager === "npm" ? "install" : "add";
52
-
53
- return new Promise((resolve, reject) => {
54
- const child = spawn(packageManager, [installCmd, ...deps], {
55
- stdio: "inherit",
56
- });
57
-
58
- child.on("close", (code) => {
59
- if (code === 0) {
60
- resolve();
61
- } else {
62
- reject(new Error(`Failed to install dependencies (code ${code})`));
63
- }
64
- });
65
- });
66
- }
67
-
68
- async function detectPackageManager(): Promise<"npm" | "pnpm" | "yarn" | "bun"> {
69
- const cwd = process.cwd();
70
-
71
- if (await fs.pathExists(path.join(cwd, "pnpm-lock.yaml"))) {
72
- return "pnpm";
73
- }
74
- if (await fs.pathExists(path.join(cwd, "yarn.lock"))) {
75
- return "yarn";
76
- }
77
- if (await fs.pathExists(path.join(cwd, "bun.lock"))) {
78
- return "bun";
79
- }
80
-
81
- return "npm";
82
- }
@@ -1,54 +0,0 @@
1
- export interface ComponentDefinition {
2
- name: string;
3
- description?: string;
4
- dependencies: string[];
5
- registryDependencies: string[];
6
- files: string[];
7
- }
8
-
9
- export interface Registry {
10
- components: ComponentDefinition[];
11
- }
12
-
13
- export interface ComponentFile {
14
- path: string;
15
- content: string;
16
- }
17
-
18
- // GitHub raw URL base - update this to your repo
19
- const GITHUB_RAW_BASE = "https://raw.githubusercontent.com/beaket/ui/main";
20
-
21
- export async function fetchRegistry(): Promise<Registry> {
22
- const url = `${GITHUB_RAW_BASE}/registry/registry.json`;
23
-
24
- try {
25
- const response = await fetch(url);
26
- if (!response.ok) {
27
- throw new Error(`HTTP ${response.status}`);
28
- }
29
- return (await response.json()) as Registry;
30
- } catch (error) {
31
- throw new Error(`Failed to fetch registry from ${url}. Make sure the repository is public.`);
32
- }
33
- }
34
-
35
- export async function fetchComponent(componentDef: ComponentDefinition): Promise<ComponentFile[]> {
36
- const files: ComponentFile[] = [];
37
-
38
- for (const filePath of componentDef.files) {
39
- const url = `${GITHUB_RAW_BASE}/src/${filePath}`;
40
-
41
- try {
42
- const response = await fetch(url);
43
- if (!response.ok) {
44
- throw new Error(`HTTP ${response.status}`);
45
- }
46
- const content = await response.text();
47
- files.push({ path: filePath, content });
48
- } catch (error) {
49
- throw new Error(`Failed to fetch ${filePath} from ${url}`);
50
- }
51
- }
52
-
53
- return files;
54
- }