velyx 1.0.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 ADDED
@@ -0,0 +1,123 @@
1
+ # Velar CLI
2
+
3
+ Velar CLI is a command-line tool for adding UI components to Laravel projects.
4
+
5
+ It delivers composable UI components built with **Blade**, **Alpine.js**, and **Tailwind CSS v4**.
6
+ Inspired by shadcn, Velar gives you the code, not a dependency.
7
+
8
+ ---
9
+
10
+ ## What Velar is
11
+
12
+ - A **code delivery tool** for Laravel UI components
13
+ - A way to **copy components into your project**
14
+ - A workflow that keeps **you in control of your code**
15
+
16
+ ## What Velar is not
17
+
18
+ - Not a UI framework
19
+ - Not a runtime dependency
20
+ - Not an auto-updating system
21
+ - Not magic
22
+
23
+ Once components are added, they belong to your project.
24
+
25
+ ---
26
+
27
+ ## Requirements
28
+
29
+ Velar assumes a modern Laravel setup:
30
+
31
+ - Laravel
32
+ - Blade
33
+ - Alpine.js
34
+ - Tailwind CSS **v4 or higher**
35
+
36
+ Tailwind v3 is not supported.
37
+
38
+ ---
39
+
40
+ ## Usage
41
+
42
+ Velar can be executed without installation.
43
+
44
+ ### Initialize Velar in a project
45
+
46
+ ```bash
47
+ npx velar init
48
+ ```
49
+
50
+ This command:
51
+
52
+ - checks your environment
53
+ - prepares the UI components directory
54
+
55
+ ---
56
+
57
+ ### Add a component
58
+
59
+ ```bash
60
+ npx velar add button
61
+ ```
62
+
63
+ Velar will:
64
+
65
+ - fetch the component from the registry
66
+ - resolve its dependencies
67
+ - copy the files into your project
68
+
69
+ By default, components are placed in:
70
+
71
+ ```bash
72
+ resources/views/components/ui
73
+ ```
74
+
75
+ ---
76
+
77
+ ### List available components
78
+
79
+ ```bash
80
+ npx velar list
81
+ ```
82
+
83
+ ---
84
+
85
+ ## How updates work
86
+
87
+ Velar does **not** update your code automatically.
88
+
89
+ If a component changes in the registry and you want the new version:
90
+
91
+ - run `velar add <component>` again
92
+ - review the changes
93
+ - decide what to keep
94
+
95
+ This is intentional.
96
+
97
+ ---
98
+
99
+ ## Philosophy
100
+
101
+ Velar follows a simple principle:
102
+
103
+ > You own your UI code.
104
+
105
+ There are no hidden abstractions and no vendor lock-in.
106
+ Velar exists to help you move faster, not to take control away from you.
107
+
108
+ ---
109
+
110
+ ## Documentation
111
+
112
+ Full documentation lives in the `docs` repository:
113
+
114
+ - Introduction
115
+ - Getting started
116
+ - Component reference
117
+ - Project philosophy
118
+
119
+ ---
120
+
121
+ ## License
122
+
123
+ MIT
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "gray",
3
+ "label": "Gray",
4
+ "cssVars": {
5
+ "light": {
6
+ "background": "0 0% 100%",
7
+ "foreground": "224 71.4% 4.1%",
8
+ "card": "0 0% 100%",
9
+ "card-foreground": "224 71.4% 4.1%",
10
+ "popover": "0 0% 100%",
11
+ "popover-foreground": "224 71.4% 4.1%",
12
+ "primary": "220.9 39.3% 11%",
13
+ "primary-foreground": "210 20% 98%",
14
+ "secondary": "220 14.3% 95.9%",
15
+ "secondary-foreground": "220.9 39.3% 11%",
16
+ "muted": "220 14.3% 95.9%",
17
+ "muted-foreground": "220 8.9% 46.1%",
18
+ "accent": "220 14.3% 95.9%",
19
+ "accent-foreground": "220.9 39.3% 11%",
20
+ "destructive": "0 84.2% 60.2%",
21
+ "destructive-foreground": "210 20% 98%",
22
+ "border": "220 13% 91%",
23
+ "input": "220 13% 91%",
24
+ "ring": "224 71.4% 4.1%",
25
+ "chart-1": "12 76% 61%",
26
+ "chart-2": "173 58% 39%",
27
+ "chart-3": "197 37% 24%",
28
+ "chart-4": "43 74% 66%",
29
+ "chart-5": "27 87% 67%"
30
+ },
31
+ "dark": {
32
+ "background": "224 71.4% 4.1%",
33
+ "foreground": "210 20% 98%",
34
+ "card": "224 71.4% 4.1%",
35
+ "card-foreground": "210 20% 98%",
36
+ "popover": "224 71.4% 4.1%",
37
+ "popover-foreground": "210 20% 98%",
38
+ "primary": "210 20% 98%",
39
+ "primary-foreground": "220.9 39.3% 11%",
40
+ "secondary": "215 27.9% 16.9%",
41
+ "secondary-foreground": "210 20% 98%",
42
+ "muted": "215 27.9% 16.9%",
43
+ "muted-foreground": "217.9 10.6% 64.9%",
44
+ "accent": "215 27.9% 16.9%",
45
+ "accent-foreground": "210 20% 98%",
46
+ "destructive": "0 62.8% 30.6%",
47
+ "destructive-foreground": "210 20% 98%",
48
+ "border": "215 27.9% 16.9%",
49
+ "input": "215 27.9% 16.9%",
50
+ "ring": "216 12.2% 83.9%",
51
+ "chart-1": "220 70% 50%",
52
+ "chart-2": "160 60% 45%",
53
+ "chart-3": "30 80% 55%",
54
+ "chart-4": "280 65% 60%",
55
+ "chart-5": "340 75% 55%"
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "neutral",
3
+ "label": "Neutral",
4
+ "cssVars": {
5
+ "light": {
6
+ "background": "0 0% 100%",
7
+ "foreground": "0 0% 3.9%",
8
+ "card": "0 0% 100%",
9
+ "card-foreground": "0 0% 3.9%",
10
+ "popover": "0 0% 100%",
11
+ "popover-foreground": "0 0% 3.9%",
12
+ "primary": "0 0% 9%",
13
+ "primary-foreground": "0 0% 98%",
14
+ "secondary": "0 0% 96.1%",
15
+ "secondary-foreground": "0 0% 9%",
16
+ "muted": "0 0% 96.1%",
17
+ "muted-foreground": "0 0% 45.1%",
18
+ "accent": "0 0% 96.1%",
19
+ "accent-foreground": "0 0% 9%",
20
+ "destructive": "0 84.2% 60.2%",
21
+ "destructive-foreground": "0 0% 98%",
22
+ "border": "0 0% 89.8%",
23
+ "input": "0 0% 89.8%",
24
+ "ring": "0 0% 3.9%",
25
+ "chart-1": "12 76% 61%",
26
+ "chart-2": "173 58% 39%",
27
+ "chart-3": "197 37% 24%",
28
+ "chart-4": "43 74% 66%",
29
+ "chart-5": "27 87% 67%"
30
+ },
31
+ "dark": {
32
+ "background": "0 0% 3.9%",
33
+ "foreground": "0 0% 98%",
34
+ "card": "0 0% 3.9%",
35
+ "card-foreground": "0 0% 98%",
36
+ "popover": "0 0% 3.9%",
37
+ "popover-foreground": "0 0% 98%",
38
+ "primary": "0 0% 98%",
39
+ "primary-foreground": "0 0% 9%",
40
+ "secondary": "0 0% 14.9%",
41
+ "secondary-foreground": "0 0% 98%",
42
+ "muted": "0 0% 14.9%",
43
+ "muted-foreground": "0 0% 63.9%",
44
+ "accent": "0 0% 14.9%",
45
+ "accent-foreground": "0 0% 98%",
46
+ "destructive": "0 62.8% 30.6%",
47
+ "destructive-foreground": "0 0% 98%",
48
+ "border": "0 0% 14.9%",
49
+ "input": "0 0% 14.9%",
50
+ "ring": "0 0% 83.1%",
51
+ "chart-1": "220 70% 50%",
52
+ "chart-2": "160 60% 45%",
53
+ "chart-3": "30 80% 55%",
54
+ "chart-4": "280 65% 60%",
55
+ "chart-5": "340 75% 55%"
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "slate",
3
+ "label": "Slate",
4
+ "cssVars": {
5
+ "light": {
6
+ "background": "0 0% 100%",
7
+ "foreground": "222.2 84% 4.9%",
8
+ "card": "0 0% 100%",
9
+ "card-foreground": "222.2 84% 4.9%",
10
+ "popover": "0 0% 100%",
11
+ "popover-foreground": "222.2 84% 4.9%",
12
+ "primary": "222.2 47.4% 11.2%",
13
+ "primary-foreground": "210 40% 98%",
14
+ "secondary": "210 40% 96.1%",
15
+ "secondary-foreground": "222.2 47.4% 11.2%",
16
+ "muted": "210 40% 96.1%",
17
+ "muted-foreground": "215.4 16.3% 46.9%",
18
+ "accent": "210 40% 96.1%",
19
+ "accent-foreground": "222.2 47.4% 11.2%",
20
+ "destructive": "0 84.2% 60.2%",
21
+ "destructive-foreground": "210 40% 98%",
22
+ "border": "214.3 31.8% 91.4%",
23
+ "input": "214.3 31.8% 91.4%",
24
+ "ring": "222.2 84% 4.9%",
25
+ "chart-1": "12 76% 61%",
26
+ "chart-2": "173 58% 39%",
27
+ "chart-3": "197 37% 24%",
28
+ "chart-4": "43 74% 66%",
29
+ "chart-5": "27 87% 67%"
30
+ },
31
+ "dark": {
32
+ "background": "222.2 84% 4.9%",
33
+ "foreground": "210 40% 98%",
34
+ "card": "222.2 84% 4.9%",
35
+ "card-foreground": "210 40% 98%",
36
+ "popover": "222.2 84% 4.9%",
37
+ "popover-foreground": "210 40% 98%",
38
+ "primary": "210 40% 98%",
39
+ "primary-foreground": "222.2 47.4% 11.2%",
40
+ "secondary": "217.2 32.6% 17.5%",
41
+ "secondary-foreground": "210 40% 98%",
42
+ "muted": "217.2 32.6% 17.5%",
43
+ "muted-foreground": "215 20.2% 65.1%",
44
+ "accent": "217.2 32.6% 17.5%",
45
+ "accent-foreground": "210 40% 98%",
46
+ "destructive": "0 62.8% 30.6%",
47
+ "destructive-foreground": "210 40% 98%",
48
+ "border": "217.2 32.6% 17.5%",
49
+ "input": "217.2 32.6% 17.5%",
50
+ "ring": "212.7 26.8% 83.9%",
51
+ "chart-1": "220 70% 50%",
52
+ "chart-2": "160 60% 45%",
53
+ "chart-3": "30 80% 55%",
54
+ "chart-4": "280 65% 60%",
55
+ "chart-5": "340 75% 55%"
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "stone",
3
+ "label": "Stone",
4
+ "cssVars": {
5
+ "light": {
6
+ "background": "0 0% 100%",
7
+ "foreground": "20 14.3% 4.1%",
8
+ "card": "0 0% 100%",
9
+ "card-foreground": "20 14.3% 4.1%",
10
+ "popover": "0 0% 100%",
11
+ "popover-foreground": "20 14.3% 4.1%",
12
+ "primary": "24 9.8% 10%",
13
+ "primary-foreground": "60 9.1% 97.8%",
14
+ "secondary": "60 4.8% 95.9%",
15
+ "secondary-foreground": "24 9.8% 10%",
16
+ "muted": "60 4.8% 95.9%",
17
+ "muted-foreground": "25 5.3% 44.7%",
18
+ "accent": "60 4.8% 95.9%",
19
+ "accent-foreground": "24 9.8% 10%",
20
+ "destructive": "0 84.2% 60.2%",
21
+ "destructive-foreground": "60 9.1% 97.8%",
22
+ "border": "20 5.9% 90%",
23
+ "input": "20 5.9% 90%",
24
+ "ring": "20 14.3% 4.1%",
25
+ "chart-1": "12 76% 61%",
26
+ "chart-2": "173 58% 39%",
27
+ "chart-3": "197 37% 24%",
28
+ "chart-4": "43 74% 66%",
29
+ "chart-5": "27 87% 67%"
30
+ },
31
+ "dark": {
32
+ "background": "20 14.3% 4.1%",
33
+ "foreground": "60 9.1% 97.8%",
34
+ "card": "20 14.3% 4.1%",
35
+ "card-foreground": "60 9.1% 97.8%",
36
+ "popover": "20 14.3% 4.1%",
37
+ "popover-foreground": "60 9.1% 97.8%",
38
+ "primary": "60 9.1% 97.8%",
39
+ "primary-foreground": "24 9.8% 10%",
40
+ "secondary": "12 6.5% 15.1%",
41
+ "secondary-foreground": "60 9.1% 97.8%",
42
+ "muted": "12 6.5% 15.1%",
43
+ "muted-foreground": "24 5.4% 63.9%",
44
+ "accent": "12 6.5% 15.1%",
45
+ "accent-foreground": "60 9.1% 97.8%",
46
+ "destructive": "0 62.8% 30.6%",
47
+ "destructive-foreground": "60 9.1% 97.8%",
48
+ "border": "12 6.5% 15.1%",
49
+ "input": "12 6.5% 15.1%",
50
+ "ring": "24 5.7% 82.9%",
51
+ "chart-1": "220 70% 50%",
52
+ "chart-2": "160 60% 45%",
53
+ "chart-3": "30 80% 55%",
54
+ "chart-4": "280 65% 60%",
55
+ "chart-5": "340 75% 55%"
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "zinc",
3
+ "label": "Zinc",
4
+ "cssVars": {
5
+ "light": {
6
+ "background": "0 0% 100%",
7
+ "foreground": "240 10% 3.9%",
8
+ "card": "0 0% 100%",
9
+ "card-foreground": "240 10% 3.9%",
10
+ "popover": "0 0% 100%",
11
+ "popover-foreground": "240 10% 3.9%",
12
+ "primary": "240 5.9% 10%",
13
+ "primary-foreground": "0 0% 98%",
14
+ "secondary": "240 4.8% 95.9%",
15
+ "secondary-foreground": "240 5.9% 10%",
16
+ "muted": "240 4.8% 95.9%",
17
+ "muted-foreground": "240 3.8% 46.1%",
18
+ "accent": "240 4.8% 95.9%",
19
+ "accent-foreground": "240 5.9% 10%",
20
+ "destructive": "0 84.2% 60.2%",
21
+ "destructive-foreground": "0 0% 98%",
22
+ "border": "240 5.9% 90%",
23
+ "input": "240 5.9% 90%",
24
+ "ring": "240 10% 3.9%",
25
+ "chart-1": "12 76% 61%",
26
+ "chart-2": "173 58% 39%",
27
+ "chart-3": "197 37% 24%",
28
+ "chart-4": "43 74% 66%",
29
+ "chart-5": "27 87% 67%"
30
+ },
31
+ "dark": {
32
+ "background": "240 10% 3.9%",
33
+ "foreground": "0 0% 98%",
34
+ "card": "240 10% 3.9%",
35
+ "card-foreground": "0 0% 98%",
36
+ "popover": "240 10% 3.9%",
37
+ "popover-foreground": "0 0% 98%",
38
+ "primary": "0 0% 98%",
39
+ "primary-foreground": "240 5.9% 10%",
40
+ "secondary": "240 3.7% 15.9%",
41
+ "secondary-foreground": "0 0% 98%",
42
+ "muted": "240 3.7% 15.9%",
43
+ "muted-foreground": "240 5% 64.9%",
44
+ "accent": "240 3.7% 15.9%",
45
+ "accent-foreground": "0 0% 98%",
46
+ "destructive": "0 62.8% 30.6%",
47
+ "destructive-foreground": "0 0% 98%",
48
+ "border": "240 3.7% 15.9%",
49
+ "input": "240 3.7% 15.9%",
50
+ "ring": "240 4.9% 83.9%",
51
+ "chart-1": "220 70% 50%",
52
+ "chart-2": "160 60% 45%",
53
+ "chart-3": "30 80% 55%",
54
+ "chart-4": "280 65% 60%",
55
+ "chart-5": "340 75% 55%"
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ import b from'chalk';import {Command}from'commander';import x from'path';import y from'fs-extra';import Ce from'prompts';import R,{promises}from'fs';import {cyan,green,yellow,red}from'kleur/colors';import {exec}from'child_process';import {promisify}from'util';import rt from'ora';import {z as z$1}from'zod';import kt from'cli-table3';var Y=".bak";function ce(r){if(!y.existsSync(r))return null;let e=`${r}${Y}`;try{return y.renameSync(r,e),e}catch(t){return console.error(`Failed to create backup of ${r}: ${t}`),null}}function D(r){let e=`${r}${Y}`;if(!y.existsSync(e))return false;try{return y.renameSync(e,r),!0}catch(t){return console.error(`Warning: Could not restore backup file ${e}: ${t}`),false}}function M(r){let e=`${r}${Y}`;if(!y.existsSync(e))return false;try{return y.unlinkSync(e),!0}catch{return false}}var g=class{async fileExists(e){try{return await promises.access(e),!0}catch{return false}}async writeFile(e,t){await promises.mkdir(x.dirname(e),{recursive:true}),await promises.writeFile(e,t,"utf-8");}async readFile(e){return await promises.readFile(e,"utf-8")}async ensureDir(e){await promises.mkdir(e,{recursive:true});}};function pe(){return R.existsSync("composer.json")&&R.existsSync("artisan")}function me(){try{return JSON.parse(R.readFileSync("package.json","utf8"))}catch{return null}}function de(r){let e={...r.dependencies,...r.devDependencies};if(e["@tailwindcss/vite"]||e["@tailwindcss/postcss"])return true;if(e.tailwindcss){let o=String(e.tailwindcss).match(/(\d+)/);return o?Number(o[1])>=4:false}return false}function Ge(){try{let r=JSON.parse(R.readFileSync("package.json","utf8")),e=r.dependencies&&Object.keys(r.dependencies).some(o=>o.toLowerCase().includes("alpine")),t=r.devDependencies&&Object.keys(r.devDependencies).some(o=>o.toLowerCase().includes("alpine"));return !!(e||t)}catch{return false}}function Be(){let r="resources/views/layouts";if(!R.existsSync(r))return false;try{let e=R.readdirSync(r,{recursive:!0});for(let t of e)if(t.endsWith(".blade.php")&&R.readFileSync(x.join(r,t),"utf8").toLowerCase().includes("alpine"))return !0}catch{return false}return false}function fe(){return Ge()||Be()}function A(){return R.existsSync("pnpm-lock.yaml")||R.existsSync("pnpm-lock.yml")?"pnpm":R.existsSync("yarn.lock")?"yarn":R.existsSync("package-lock.json")?"npm":R.existsSync("bun.lock")?"bun":"npm"}var He=["resources/css/app.css","resources/css/app.scss","resources/css/main.css","resources/css/style.css","resources/css/styles.css"];function ue(){for(let r of He)if(R.existsSync(r))return {path:r,content:R.readFileSync(r,"utf8")};return null}function X(r){return /@import\s+["']tailwindcss["']/.test(r)}function ge(r){let e=R.readFileSync(r,"utf8");e.includes('@import "./velar.css"')||(X(e)?e=e.replace(/@import\s+["']tailwindcss["'];?/,t=>`${t}
2
+ @import "./velar.css";`):e+=`
3
+ @import "./velar.css";
4
+ `,R.writeFileSync(r,e,"utf8"));}var qe=["resources/js/app.js","resources/js/main.js","resources/js/index.js"];function he(){for(let r of qe)if(R.existsSync(r))return {path:r,content:R.readFileSync(r,"utf8")};return null}function ye(r,e,t){let o=R.readFileSync(r,"utf8"),n=`import ${e} from '${t}'`;if(o.includes(n)||o.includes(`import ${e} from "${t}"`))return;let i=o.split(`
5
+ `),a=-1;for(let c=0;c<i.length;c++)i[c]?.startsWith("import ")&&(a=c);i.splice(a+1,0,n),o=i.join(`
6
+ `);let l=`Alpine.data('${e}', ${e});`;o.includes("document.addEventListener('alpine:init'")?o.includes(l)||(o=o.replace(/document\.addEventListener\('alpine:init',\s*\(\)\s*=>\s*\{/,c=>`${c}
7
+ ${l}`)):o+=`
8
+
9
+ document.addEventListener('alpine:init', () => {
10
+ ${l}
11
+ });
12
+ `,R.writeFileSync(r,o,"utf8");}function We(r){let e=r;for(let t=0;t<4;t+=1){let o=x.join(e,"colors");if(R.existsSync(o))return o;let n=x.join(e,"src/colors");if(R.existsSync(n))return n;let i=x.dirname(e);if(i===e)break;e=i;}return x.join(r,"colors")}var ze=process.argv[1]?x.dirname(x.resolve(process.argv[1])):process.cwd(),Q=We(ze);function ve(){return R.existsSync(Q)?R.readdirSync(Q).filter(e=>e.endsWith(".json")).map(e=>{let t=x.join(Q,e),o=R.readFileSync(t,"utf-8");return JSON.parse(o)}).filter(e=>!!e?.name).sort((e,t)=>e.name.localeCompare(t.name)):[]}function U(){return ve()}function Ke(r){return ve().find(e=>e.name===r)}function we(r){return Object.entries(r).map(([e,t])=>` --${e}: ${t};`)}function be(r,e){let t=Ke(r);if(!t)throw new Error(`Theme "${r}" not found in colors registry.`);let o=we(t.cssVars.light),n=we(t.cssVars.dark),i=[":root {",...o,"}","",".dark {",...n,"}",""].join(`
13
+ `);R.writeFileSync(e,i,{encoding:"utf-8",flag:"wx"});}function xe(r){R.writeFileSync("velar.json",JSON.stringify(r,null,2)+`
14
+ `,"utf8");}function Se(){if(!R.existsSync("velar.json"))throw new Error("Velar configuration not found.");return JSON.parse(R.readFileSync("velar.json","utf8"))}var m={error:red,warn:yellow,info:cyan,success:green};var s={error(...r){console.log(m.error(r.join(" ")));},warn(...r){console.log(m.warn(r.join(" ")));},info(...r){console.log(m.info(r.join(" ")));},success(...r){console.log(m.success(r.join(" ")));},log(...r){console.log(r.join(" "));},break(){console.log("");}};var N={version:"1.0.0"};var J=class{constructor(e){this.fileSystem=e;}validateEnvironment(){if(!pe())throw new Error("No Laravel project detected");let e=me();if(!e||!de(e))throw new Error("Tailwind CSS v4 was not detected");let t=fe(),o=A(),n=ue(),i=he(),a=n?X(n.content):false;return {isLaravel:true,hasTailwindV4:true,hasAlpine:t,detectedPackageManager:o,cssFile:n,jsFile:i,canInjectCss:a}}displayEnvironmentInfo(e){e.hasAlpine?s.success("Alpine.js detected - components will be fully interactive"):(s.warn("Alpine.js not detected"),s.log(`Install Alpine.js: ${e.detectedPackageManager} install alpinejs`)),e.cssFile?e.canInjectCss||(s.warn("Tailwind import not found in CSS"),s.log("Velar styles will not be auto-imported")):(s.warn("No main CSS file found"),s.log("Styles will be created but not auto-imported")),e.jsFile||(s.warn("No main JS file found"),s.log("Component scripts will not be auto-imported"));}async createComponentsDirectory(e="resources/views/components/ui"){await this.fileSystem.ensureDir(e);}async createThemeFile(e,t="resources/css/velar.css"){let o=t.split("/").slice(0,-1).join("/");if(await this.fileSystem.ensureDir(o),R.existsSync(t))s.info("velar.css already exists");else try{be(e,t),s.success("Velar theme created"),s.info(t);}catch(n){throw new Error(`Failed to create theme file: ${n.message}`)}}async injectStylesImport(e){ge(e),s.success("Velar styles imported"),s.info(e);}async generateConfig(e,t){let o={version:N.version,theme:e.theme,packageManager:e.packageManager,css:{entry:t.cssFile?.path??"",velar:"resources/css/velar.css"},js:{entry:t.jsFile?.path??""},components:{path:"resources/views/components/ui"}};xe(o),s.success("velar.json config generated");}displaySummary(e,t,o){console.log(`
15
+ ---`),s.success("Laravel project detected"),s.success("Tailwind CSS v4 detected"),s.success(`Theme selected: ${e.theme}`),s.success(`Package manager: ${e.packageManager}`),s.success("UI components directory ready"),t.jsFile&&s.success("Main JS file detected"),s.success(o?"Styles import complete":"Styles import pending"),s.success("velar.json created"),console.log(`
16
+ Next steps:`),console.log(" velar add button"),console.log(`
17
+ \u{1F4A1} Want to customize your Tailwind palette? Try https://tweakcn.com/ \u2014 a visual generator for Tailwind-compatible color scales.`);}};var h={start(r){return rt(r).start()},async withTask(r,e,t,o){let n=this.start(r);try{let i=await e();return t?n.succeed(t):n.stop(),i}catch(i){throw n.fail(o||"Operation failed"),i}}};var st=promisify(exec);async function it(r){try{let e=x.resolve(r,"composer.json"),t=x.resolve(r,"package.json");if(!y.existsSync(e))return null;let o=await y.readJson(e);if(!(o.require?.["laravel/framework"]||o.require?.["illuminate/foundation"]))return null;let i=process.cwd();process.chdir(r);let a=A();console.log(`Detected package manager: ${a}`),process.chdir(i);let l={name:o.name||x.basename(r),framework:{name:"laravel",label:"Laravel",version:o.require?.["laravel/framework"]||"unknown"},hasAlpine:!1,hasVite:!1,packageManager:a,paths:{views:"resources/views",assets:"resources/js",public:"public",config:"config"}};if(y.existsSync(t)){let u=await y.readJson(t);l.hasAlpine=!!(u.dependencies?.alpinejs||u.devDependencies?.alpinejs),l.hasVite=!!u.devDependencies?.vite;}let c=x.resolve(r,"resources/views"),d=x.resolve(r,"resources/js");return y.existsSync(c)&&(l.paths.views="resources/views"),y.existsSync(d)&&(l.paths.assets="resources/js"),l}catch{return null}}async function ke(r){let e={};if(!y.existsSync(r.cwd))return e.MISSING_DIR=true,{errors:e,projectInfo:null};let t=h.start("Checking project environment..."),o=x.resolve(r.cwd,"velar.json");if(y.existsSync(o)&&!r.force){t.fail(),s.break();let{action:l}=await Ce({type:"select",name:"action",message:`A ${m.info("velar.json")} file already exists. What would you like to do?`,choices:[{title:"Re-initialize Velar configuration",value:"reinit"},{title:"Keep existing configuration",value:"keep"},{title:"Exit",value:"exit"}],initial:0});l==="exit"&&(s.log("Operation cancelled."),process.exit(0)),l==="keep"&&(s.log("Keeping existing configuration."),process.exit(0)),s.log("Re-initializing Velar configuration...");}let n=await it(r.cwd);(!n||n.framework.name!=="laravel")&&(e.UNSUPPORTED_PROJECT=true,t.fail(),s.break(),s.error(`We could not detect a supported Laravel project at ${m.info(r.cwd)}.
18
+ Velar is designed to work with Laravel projects.`),s.break(),process.exit(1)),t.succeed(`Found ${m.info(n.framework.label)} project`);let i=h.start("Checking Alpine.js...");if(n.hasAlpine)i.succeed("Alpine.js found");else {i.fail(),s.break(),s.warn("Alpine.js is required but not found in your project.");let{installAlpine:l}=await Ce({type:"confirm",name:"installAlpine",message:"Would you like to install Alpine.js now?",initial:true});if(l){let c=n.packageManager,d=h.start(`Installing Alpine.js with ${c}...`);try{await st(`${c} install alpinejs`,{cwd:r.cwd}),d.succeed("Alpine.js installed successfully"),n.hasAlpine=!0;}catch(u){d.fail(`Failed to install Alpine.js: ${u.message}`),s.error(`Please install Alpine.js manually: ${m.info(`${c} install alpinejs`)}`),s.break(),process.exit(1);}}else {let c=n.packageManager;s.error(`Alpine.js is required. Install it with: ${m.info(`${c} install alpinejs`)}`),s.break(),process.exit(1);}}let a=h.start("Checking build tools...");return n.hasVite?a.succeed("Vite found"):(s.warn("Vite not found. Using Vite is recommended for better development experience."),a.warn("Vite not found (but optional)")),Object.keys(e).length>0&&(s.break(),process.exit(1)),{errors:e,projectInfo:n}}var Ee=z$1.object({baseColor:z$1.string().optional(),yes:z$1.boolean(),defaults:z$1.boolean(),force:z$1.boolean(),cwd:z$1.string(),silent:z$1.boolean()});async function at(){let r=U();r.length===0&&(s.error("No base colors available."),process.exit(1));let{theme:e}=await Ce({type:"select",name:"theme",message:"Choose a base color theme",choices:r.map(t=>({title:t.label,value:t.name}))},{onCancel:()=>{s.error("Theme selection aborted"),process.exit(1);}});return e}async function ct(){let{shouldImport:r}=await Ce({type:"confirm",name:"shouldImport",message:"Import Velar styles into your main CSS file?",initial:true},{onCancel:()=>false});return !!r}function lt(r){if(!r.baseColor)return;let t=U().find(o=>o.name===r.baseColor);if(t)return t.name;s.warn(`Unknown base color "${r.baseColor}".`);}async function Ie(r,e){e||(e=(await ke(r)).projectInfo),process.chdir(r.cwd);let t=new g,o=new J(t);try{let n=o.validateEnvironment();o.displayEnvironmentInfo(n);let i=e.packageManager,a=U(),l=a.find(u=>u.name==="neutral")?.name??a[0]?.name,c=lt(r);c||(c=r.defaults&&l?l:await at()),c||(s.error("No base color available."),process.exit(1)),await o.createComponentsDirectory(),await o.createThemeFile(c);let d=!1;n.cssFile&&n.canInjectCss&&(r.defaults||await ct())&&(await o.injectStylesImport(n.cssFile.path),d=!0),await o.generateConfig({packageManager:i,theme:c,importStyles:d},n),o.displaySummary({packageManager:i,theme:c,importStyles:d},n,d);}catch(n){s.error(n.message),n instanceof Error&&(n.message.includes("Laravel project")?s.log("Run velar init at the root of a Laravel project"):n.message.includes("Tailwind")&&s.log(`Velar requires ${m.info("Tailwind CSS v4+")}`)),process.exit(1);}}process.on("exit",r=>{let e=x.resolve(process.cwd(),"velar.json");return r===0?M(e):D(e)});var Fe=new Command().name("init").description("initialize your project and install dependencies").option("-b, --base-color <base-color>","the base color to use. (neutral, gray, zinc, stone, slate)",void 0).option("-y, --yes","skip confirmation prompt.",true).option("-d, --defaults","use default configuration.",false).option("-f, --force","force overwrite of existing configuration.",false).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).option("-s, --silent","mute output.",false).action(async r=>{let e=Ee.parse({baseColor:r.baseColor,yes:!!r.yes,defaults:!!r.defaults,force:!!r.force,cwd:x.resolve(r.cwd),silent:!!r.silent});await Ie(e);});var te=class extends Error{constructor(t,o,n){super(t);this.code=o;this.context=n;this.name="VelarError";}},I=class{handle(e,t){e instanceof te?(console.error(`[${e.code}] ${e.message}`),e.context&&console.error("Context:",e.context)):console.error(`Unexpected error in ${t}: ${e.message}`);}};var mt={UNKNOWN_ERROR:"UNKNOWN_ERROR"},G=class extends Error{code;statusCode;context;suggestion;timestamp;cause;constructor(e,t={}){super(e),this.name="RegistryError",this.code=t.code||mt.UNKNOWN_ERROR,this.statusCode=t.statusCode,this.cause=t.cause,this.context=t.context,this.suggestion=t.suggestion,this.timestamp=new Date,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor);}toJSON(){return {name:this.name,message:this.message,code:this.code,statusCode:this.statusCode,context:this.context,suggestion:this.suggestion,timestamp:this.timestamp,stack:this.stack}}};function re(r){if(s.break(),s.error("Something went wrong. Please check the error below for more details."),s.error("If the problem persists, please open an issue on GitHub."),s.error(""),typeof r=="string"&&(s.error(r),s.break(),process.exit(1)),r instanceof G&&(r.message&&(s.error(r.cause?"Error:":"Message:"),s.error(r.message)),r.cause&&(s.error(`
19
+ Message:`),s.error(r.cause)),r.suggestion&&(s.error(`
20
+ Suggestion:`),s.error(r.suggestion)),s.break(),process.exit(1)),r instanceof z$1.ZodError){s.error("Validation failed:");for(let[e,t]of Object.entries(r.flatten().fieldErrors))s.error(`- ${m.info(e)}: ${t}`);s.break(),process.exit(1);}r instanceof Error&&(s.error(r.message),s.break(),process.exit(1)),s.break(),process.exit(1);}var B=class{config;async load(){try{return this.config=Se(),this.config||(s.error(""),re(new Error("Configuration not found")),process.exit(1)),this.config}catch{s.error(""),re(new Error("Something went wrong. Please try again.")),process.exit(1);}}getPackageManager(){if(!this.config)throw new Error("Configuration not loaded");return this.config.packageManager||"npm"}validate(){return !!this.config}getComponentsPath(){if(!this.config)throw new Error("Configuration not loaded");return this.config.components.path}getThemePath(){if(!this.config)throw new Error("Configuration not loaded");return this.config.css.velar}getJsEntryPath(){if(!this.config)throw new Error("Configuration not loaded");return this.config.js?.entry??""}getTheme(){if(!this.config)throw new Error("Configuration not loaded");return this.config.theme}};var H=promisify(exec);function gt(r){return r.startsWith("@")?r:r.replace("@",":")}var q=class{fileSystem;constructor(e){this.fileSystem=e??new g;}async installDependencies(e,t){let o=[],n=[];e.npm&&e.npm.length>0&&o.push(this.installNpmDependencies(e.npm,t)),e.composer&&e.composer.length>0&&n.push(this.installComposerDependencies(e.composer)),await Promise.allSettled([...o,...n]);}async installNpmDependencies(e,t){if(!this.fileSystem.fileExists("package.json")){s.warn("No package.json found, skipping npm dependencies");return}let o=await this.filterMissingNpmDependencies(e);if(o.length===0){s.info("All npm dependencies already installed");return}let n=this.getNpmInstallCommand(t,o);try{s.info(`Installing npm dependencies: ${o.join(", ")}`);let{stdout:i,stderr:a}=await H(n,{cwd:process.cwd(),timeout:12e4});i&&process.env.NODE_ENV!=="test"&&console.log(i),a&&!a.includes("WARN")&&s.warn(`npm install warnings: ${a}`),s.success(`Installed ${o.length} npm dependencies`);}catch(i){throw s.error(`Failed to install npm dependencies: ${i.message}`),i}}async installComposerDependencies(e){if(!this.fileSystem.fileExists("composer.json")){s.warn("No composer.json found, skipping composer dependencies");return}let t=e.map(gt),o=await this.filterMissingComposerDependencies(t);if(o.length===0){s.info("All composer dependencies already installed");return}try{s.info(`Installing composer dependencies: ${o.join(", ")}`);let{stdout:n,stderr:i}=await H(`composer require ${o.join(" ")}`,{cwd:process.cwd(),timeout:3e5});n&&process.env.NODE_ENV!=="test"&&console.log(n),i&&s.warn(`composer require warnings: ${i}`),s.success(`Installed ${o.length} composer dependencies`);}catch(n){throw s.error(`Failed to install composer dependencies: ${n.message}`),n}}getNpmInstallCommand(e,t){switch(e){case "pnpm":return `pnpm add ${t.join(" ")}`;case "yarn":return `yarn add ${t.join(" ")}`;case "bun":return `bun add ${t.join(" ")}`;default:return `npm install ${t.join(" ")}`}}async filterMissingNpmDependencies(e){try{let{stdout:t}=await H("npm list --json --depth=0",{cwd:process.cwd(),timeout:3e4}),o=JSON.parse(t),n=Object.keys({...o.dependencies,...o.devDependencies});return e.filter(i=>{let a=i.split("@")[0];return !n.includes(a)})}catch{return e}}async filterMissingComposerDependencies(e){try{let{stdout:t}=await H("composer show --installed --format=json",{cwd:process.cwd(),timeout:3e4}),n=JSON.parse(t).installed.map(i=>i.name);return e.filter(i=>{let a=i.split(":")[0];return !n.includes(a)})}catch{return e}}};var z=class{constructor(e,t,o){this.registryService=e;this.configManager=o;if(this.fileSystem=t??new g,this.dependencyService=new q(this.fileSystem),!this.configManager)throw new Error("ConfigManager is required")}fileSystem;dependencyService;async addComponents(e){let t={added:[],skipped:[],failed:[]};for(let o of e)try{let n=await this.addComponent(o);t.added.push(...n.added),t.skipped.push(...n.skipped),t.failed.push(...n.failed);}catch(n){t.failed.push({name:o,error:n.message});}return t}async addComponent(e){let t={added:[],skipped:[],failed:[]},o=await this.registryService.fetchComponent(e),n=await this.registryService.resolveDependencies(o);if(o.dependencies){let l=this.configManager.getPackageManager();try{await this.dependencyService.installDependencies(o.dependencies,l);}catch(c){s.warn(`Failed to install dependencies for ${e}: ${c.message}`);}}let i=this.configManager.getComponentsPath(),a=[];for(let l of n)for(let c of l.files){let d=this.getDestinationPath(l,c,i),u=await this.fileSystem.fileExists(d);if(u){let ae=await this.handleFileConflict(c.path);if(ae==="skip"){t.skipped.push(`${l.name}/${c.path}`);continue}else ae==="cancel"&&(s.error("Cancelled."),process.exit(0));}let _e=await this.registryService.fetchFile(l.name,c.path);a.push({componentName:l.name,filePath:c.path,fileType:c.type,destPath:d,content:_e,existedBefore:u});}if(a.length>0)try{await this.applyFileBatch(a),a.forEach(c=>t.added.push(`${c.componentName}/${c.filePath}`));let l=new Set(a.filter(c=>c.fileType==="js").map(c=>c.componentName));for(let c of Array.from(l))await this.autoImportJs(c);}catch(l){a.forEach(c=>t.failed.push({name:`${c.componentName}/${c.filePath}`,error:l.message}));}return t}async autoImportJs(e){try{let t=this.configManager?.getJsEntryPath();if(!t||!await this.fileSystem.fileExists(t))return;let o=`./ui/${e}`;ye(t,e,o),s.success(`Auto-imported ${e} into ${t}`);}catch(t){s.warn(`Failed to auto-import JS for ${e}: ${t.message}`);}}getDestinationPath(e,t,o){switch(t.type){case "blade":return x.join(o,`${e.name}.blade.php`);case "js":return x.join("resources/js/ui",`${e.name}.js`);case "css":return x.join("resources/css/components",`${e.name}.css`);default:return x.join(o,t.path)}}async handleFileConflict(e){let{action:t}=await Ce({type:"select",name:"action",message:`File "${e}" already exists. What do you want to do?`,choices:[{title:"Skip",value:"skip"},{title:"Overwrite",value:"overwrite"},{title:"Cancel",value:"cancel"}],initial:0},{onCancel:()=>{s.error("Cancelled."),process.exit(0);}});return t}async applyFileBatch(e){let t=[],o=[];try{for(let n of e){let i=`${n.destPath}.velar-tmp`;await this.fileSystem.writeFile(i,n.content),t.push(i);}for(let n of e){if(!n.existedBefore)continue;if(!ce(n.destPath))throw new Error(`Failed to create backup for ${n.destPath}`);o.push(n.destPath);}for(let n of e){let i=`${n.destPath}.velar-tmp`;await y.move(i,n.destPath,{overwrite:!0});}o.forEach(n=>M(n));}catch(n){for(let i of e)await this.fileSystem.fileExists(i.destPath)&&await y.remove(i.destPath),i.existedBefore&&D(i.destPath);for(let i of t)await this.fileSystem.fileExists(i)&&await y.remove(i);throw n}}};var K=class{constructor(e,t,o){this.registryService=e;this.configManager=t;this.componentService=o??new z(e,new g,t);}componentService;validateInitialization(){if(!this.configManager.validate())throw new Error("Velar is not initialized")}validateComponents(e,t){for(let o of e)if(!t.components.find(i=>i.name===o))throw new Error(`Component "${o}" not found`)}async getAvailableComponents(){return await this.registryService.fetchRegistry()}async addComponents(e){return await this.componentService.addComponents(e)}displayResults(e){e.added.forEach(t=>s.success(`Added ${t}`)),e.skipped.forEach(t=>s.warn(`Skipped ${t}`)),e.failed.forEach(({name:t,error:o})=>s.error(`Failed to add ${t}: ${o}`));}displayNextSteps(e){if(e.added.length===0)return;console.log(`
21
+ \u{1F389} Happy coding! Enjoy building beautiful components!`);let t=e.added.filter(n=>n.endsWith(".js")),o=this.configManager.validate()&&this.configManager.getJsEntryPath();t.length>0&&!o&&(console.log(" Import JS files in your app.js:"),t.forEach(n=>{let i=n.split("/")[1];i&&console.log(` import './ui/${i}'`);}));}};var T=()=>"https://api.github.com/repos/velar-ui/registry/contents";var Z=class extends Error{constructor(t,o){super(t);this.cause=o;this.name="RegistryError";}},p=class extends Z{constructor(e,t){super(e,t),this.name="NetworkError";}},C=class extends Z{constructor(e,t){super(`Component "${e}" not found`,t),this.name="ComponentNotFoundError";}};var w={maxRetries:3,initialDelay:1e3,backoffFactor:2,maxDelay:1e4,retryableStatusCodes:[408,429,500,502,503,504],timeout:3e4,headers:{}};function ne(r){return new Promise(e=>setTimeout(e,r))}function se(r,e,t,o){let n=e*Math.pow(t,r);return Math.min(n,o)}function yt(r,e){return e.includes(r)}async function wt(r,e){let{timeout:t=w.timeout,headers:o={}}=e,n=new AbortController,i=setTimeout(()=>n.abort(),t);try{return await fetch(r,{signal:n.signal,headers:{"User-Agent":"Velar-CLI",...o}})}catch(a){throw a instanceof Error&&a.name==="AbortError"?new p(`Request timeout after ${t}ms for ${r}`,a):a}finally{clearTimeout(i);}}var j=class{async fetch(e,t={}){let o={maxRetries:t.maxRetries??w.maxRetries,initialDelay:t.initialDelay??w.initialDelay,backoffFactor:t.backoffFactor??w.backoffFactor,maxDelay:t.maxDelay??w.maxDelay,retryableStatusCodes:t.retryableStatusCodes??w.retryableStatusCodes,timeout:t.timeout??w.timeout,headers:t.headers??w.headers},n=null;for(let i=0;i<=o.maxRetries;i++)try{let a=await wt(e,{...t,timeout:o.timeout,headers:o.headers});if(a.ok||!yt(a.status,o.retryableStatusCodes))return a;if(console.log("Attempt: ",i),i===o.maxRetries)throw new p(`Request failed after ${o.maxRetries+1} attempts: ${a.status} ${a.statusText}`);let l=se(i,o.initialDelay,o.backoffFactor,o.maxDelay);await ne(l);}catch(a){if(n=a,a instanceof p&&a.message.includes("timeout")){if(i===o.maxRetries)throw a;let c=se(i,o.initialDelay,o.backoffFactor,o.maxDelay);await ne(c);continue}if(i===o.maxRetries)throw n instanceof p?n:new p(`Request failed after ${o.maxRetries+1} attempts: ${n.message}`,n);let l=se(i,o.initialDelay,o.backoffFactor,o.maxDelay);await ne(l);}throw new p(`Request failed after ${o.maxRetries+1} attempts: ${n?.message??"Unknown error"}`,n??void 0)}async fetchJson(e,t){let o=await this.fetch(e,t);if(!o.ok)throw new p(`Failed to fetch JSON from ${e}: ${o.status} ${o.statusText}`);try{return await o.json()}catch(n){throw new p(`Failed to parse JSON from ${e}: ${n.message}`,n)}}async fetchText(e,t){let o=await this.fetch(e,t);if(!o.ok)throw new p(`Failed to fetch text from ${e}: ${o.status} ${o.statusText}`);try{return await o.text()}catch(n){throw new p(`Failed to read text from ${e}: ${n.message}`,n)}}};var v=new j;async function $e(r="main"){try{let e=`https://raw.githubusercontent.com/velar-ui/registry/${r}/registry.json`;try{return await v.fetchJson(e)}catch{}let t=await v.fetchJson(`${T()}/components`),o=[];for(let n of t)if(n.type==="dir")try{let i=await v.fetchJson(`${T()}/components/${n.name}/meta.json`);o.push({...i,name:n.name,path:n.path});}catch{o.push({name:n.name,path:n.path,files:[]});}return {components:o}}catch(e){throw e instanceof p?e:new p(`Failed to fetch remote registry: ${e.message}`,e)}}async function Pe(r){try{let e=`${T()}/components/${r}/meta.json`,t=await v.fetch(e);if(t.status===404)throw new C(r);if(!t.ok)throw new p(`Component meta not found: ${t.status} ${t.statusText}`);return await v.fetchJson(e)}catch(e){throw e instanceof C||e instanceof p?e:new p(`Failed to fetch component meta for "${r}": ${e.message}`,e)}}async function Oe(r,e){try{let t=`${T()}/components/${r}/${e}`,o=await v.fetch(t);if(o.status===404)throw new C(r);if(!o.ok)throw new p(`File not found: ${o.status} ${o.statusText}`);let n=await v.fetchJson(t);if(!n.download_url)throw new p("File has no download URL");return await v.fetchText(n.download_url)}catch(t){throw t instanceof C||t instanceof p?t:new p(`Failed to fetch file "${e}" for component "${r}": ${t.message}`,t)}}var F=class{httpService;constructor(e){this.httpService=e??new j;}async fetchRegistry(){return await h.withTask("Fetching registry...",()=>$e(),void 0,"Failed to fetch registry")}async fetchComponent(e){let t=await h.withTask(`Fetching component "${e}" metadata...`,()=>Pe(e),void 0,`Failed to fetch component "${e}"`);return await this.parseComponentMeta(t)}async fetchFile(e,t){let o=e.split("/").pop()||e;return await h.withTask(`Downloading ${t}...`,()=>Oe(o,t),void 0,`Failed to fetch file "${t}"`)}async resolveDependencies(e){let t=new Set,o=[];return await(async i=>{t.has(i.name)||(t.add(i.name),o.push(i));})(e),o}async parseComponentMeta(e){if(!e.download_url)throw new Error("GitHub file has no download URL");try{let t=await this.httpService.fetchText(e.download_url);return JSON.parse(t)}catch(t){throw new Error(`Failed to parse component meta: ${t.message}`)}}};async function bt(r,e){if(r.all)return [...e];if(r.components?.length)return r.components;s.info("Use arrow keys and space to select, then press enter.");let{components:t}=await Ce({type:"multiselect",name:"components",message:"Which components would you like to add?",hint:"Space to select. A to toggle all. Enter to submit.",instructions:false,choices:e.map(n=>({title:n,value:n,selected:r.all?true:r.components?.includes(n)}))});t?.length||(s.warn("No components selected. Exiting."),s.info(""),process.exit(1));let o=z$1.array(z$1.string()).safeParse(t);return o.success||(s.error("Something went wrong. Please try again."),process.exit(1)),o.data}async function Te(r){let e=new B;await e.load();let t=new F,o=new K(t,e);try{o.validateInitialization();}catch{s.error("Velar is not initialized"),s.log("Run velar init first"),process.exit(1);}let n=await o.getAvailableComponents(),i=n.components.map(c=>c.name).sort((c,d)=>c.localeCompare(d)),a=await bt(r,i);try{o.validateComponents(a,n);}catch(c){s.error(c.message),s.log("Run velar list to see available components"),process.exit(1);}let l=await o.addComponents(a);o.displayResults(l),o.displayNextSteps(l);}var Ct=z$1.object({components:z$1.array(z$1.string()).optional(),yes:z$1.boolean(),overwrite:z$1.boolean(),cwd:z$1.string(),all:z$1.boolean(),path:z$1.string().optional(),silent:z$1.boolean(),srcDir:z$1.boolean().optional(),cssVariables:z$1.boolean().optional()}),De=new Command().name("add").argument("[components...]","Names of components to add").option("-y, --yes","skip confirmation prompt.",false).option("-o, --overwrite","overwrite existing files.",false).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).option("-a, --all","add all available components",false).option("-p, --path <path>","the path to add the component to.").option("-s, --silent","mute output.",false).option("--src-dir","use the src directory when creating a new project.",false).option("--no-src-dir","do not use the src directory when creating a new project.").option("--css-variables","use CSS variables for theming.",true).option("--no-css-variables","do not use CSS variables for theming.").description("Add one or more UI components to your Laravel project").action(async(r,e)=>{let t=new I;try{let o={components:r,cwd:x.resolve(e.cwd),...e,cssVariables:e.cssVariables??!0},n=Ct.parse(o);await Te(n);}catch(o){t.handle(o,"add command"),process.exit(1);}});function Rt(r,e){if(!e)return [...r];let t=e.toLowerCase();return r.filter(o=>{let n=o.name.toLowerCase().includes(t),i=o.description?o.description.toLowerCase().includes(t):false,a=o.categories?o.categories.some(l=>l.toLowerCase().includes(t)):false;return n||i||a})}function Et(r,e,t){let o=Math.max(0,e??0);return t===void 0?r.slice(o):r.slice(o,o+Math.max(0,t))}async function Me(r){let o=[...(await new F().fetchRegistry()).components].sort((l,c)=>l.name.localeCompare(c.name)),n=Rt(o,r.query),i=Et(n,r.offset,r.limit);if(r.json){console.log(JSON.stringify({total:n.length,count:i.length,offset:r.offset??0,limit:r.limit??null,components:i},null,2));return}if(i.length===0){s.warn("No components found.");return}console.log(b.bold(`
22
+ Available components:`)),console.log("");let a=new kt({head:[b.bold("Component"),b.bold("Description"),b.bold("Categories")],colWidths:[24,50,24],wordWrap:true,style:{head:[],border:[]}});for(let l of i)a.push([b.cyan(l.name),b.white(l.description||"No description"),b.gray(l.categories?.join(", ")||"-")]);console.log(a.toString()),console.log(""),s.info(`Run ${b.green("velar add <component>")} to add one.`);}var Ft=z$1.object({cwd:z$1.string(),query:z$1.string().optional(),limit:z$1.number().optional(),offset:z$1.number().optional(),json:z$1.boolean()}),Ve=new Command().name("list").alias("search").description("List or search components from the registry").option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).option("-q, --query <query>","query string").option("-l, --limit <number>","maximum number of items to display",void 0).option("-o, --offset <number>","number of items to skip",void 0).option("--json","output JSON",false).action(async r=>{let e=new I;try{let t=Ft.parse({cwd:x.resolve(r.cwd),query:r.query,limit:r.limit?Number.parseInt(r.limit,10):void 0,offset:r.offset?Number.parseInt(r.offset,10):void 0,json:!!r.json});process.chdir(t.cwd),await Me(t);}catch(t){e.handle(t,"list command"),process.exit(1);}});function Pt(){console.log(""),console.log(b.bold.cyan(` \u25BC VELAR CLI v${N.version}`)),console.log(b.gray(" Tailwind CSS v4+ components for Laravel")),console.log("");}var ie=new Command;ie.name("velar").description("Velar CLI: Copy UI components into your Laravel project").version(N.version,"-v, --version","display the version number").hook("preAction",()=>{Pt();});ie.addCommand(De).addCommand(Fe).addCommand(Ve);ie.parse(process.argv);//# sourceMappingURL=index.js.map
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/file-helper.ts","../src/services/filesystem-service.ts","../src/utils/laravel.ts","../src/utils/tailwind.ts","../src/utils/requirements.ts","../src/utils/package-manager.ts","../src/utils/css.ts","../src/utils/js.ts","../src/utils/theme.ts","../src/utils/config.ts","../src/utils/highlighter.ts","../src/utils/logger.ts","../package.json","../src/services/init-service.ts","../src/utils/spinner.ts","../src/utils/preflight-init.ts","../src/utils/init-project.ts","../src/commands/init.ts","../src/errors/ErrorHandler.ts","../src/utils/errors.ts","../src/utils/handle-error.ts","../src/config/config-manager.ts","../src/services/dependency-service.ts","../src/services/component-service.ts","../src/services/add-service.ts","../src/utils/environment.ts","../src/errors/errors.ts","../src/services/http-service.ts","../src/utils/remote-registry.ts","../src/services/registry-service.ts","../src/utils/add-components.ts","../src/commands/add.ts","../src/utils/list-components.ts","../src/commands/list.ts","../src/index.ts"],"names":["FILE_BACKUP_SUFFIX","createFileBackup","filePath","fsExtra","backupPath","error","restoreFileBackup","deleteFileBackup","FilesystemService","fs","content","path","dirPath","isLaravelProject","readPackageJson","detectTailwindV4","pkg","deps","match","hasAlpineInPackageJson","hasInDeps","dep","hasInDevDeps","hasAlpineInLayouts","layoutDir","files","file","hasAlpineJs","detectPackageManager","CSS_CANDIDATES","findMainCss","rel","hasTailwindImport","css","injectVelarImport","cssPath","JS_CANDIDATES","findMainJs","injectComponentJs","jsPath","componentName","componentImportPath","importStatement","lines","lastImportIndex","i","alpineDataRegistration","findColorsDir","startDir","current","depth","distPath","srcPath","parent","entryDir","COLORS_DIR","loadBaseColors","raw","color","a","b","getBaseColors","getBaseColor","name","renderCssVars","vars","key","value","copyTheme","theme","target","baseColor","lightVars","darkVars","writeVelarConfig","config","readVelarConfig","highlighter","red","yellow","cyan","green","logger","args","package_default","InitService","fileSystem","hasAlpine","detectedPm","js","canInject","validation","targetPath","options","stylesImported","spinner","message","ora","task","successMessage","failMessage","s","result","execAsync","promisify","exec","getProjectInfo","cwd","composerPath","packagePath","composer","originalDir","pkgManager","projectInfo","viewsPath","assetsPath","preFlightInit","errors","projectSpinner","velarConfigPath","action","prompts","alpineSpinner","installAlpine","installSpinner","viteSpinner","initOptionsSchema","z","promptTheme","baseColors","promptStyleImport","shouldImport","resolveThemeFromOptions","matched","initProject","initService","packageManager","defaultTheme","code","init","Command","opts","VelarError","context","ErrorHandler","RegistryErrorCode","RegistryError","handleError","ConfigManager","convertNpmToComposerFormat","DependencyService","dependencies","npmPromises","composerPromises","missingDeps","command","stdout","stderr","convertedDeps","installed","installedDeps","ComponentService","registryService","configManager","componentNames","componentResult","component","componentsToAdd","componentsPath","plannedFiles","comp","dest","existedBefore","jsComponents","jsComponent","jsEntry","importPath","tempFiles","backupTargets","tempPath","tempFile","AddService","componentService","registry","c","jsFiles","hasJsEntry","fileName","getGitHubRegistryUrl","cause","NetworkError","ComponentNotFoundError","DEFAULT_RETRY_OPTIONS","sleep","ms","resolve","calculateDelay","attempt","initialDelay","backoffFactor","maxDelay","delay","isRetryableStatus","status","retryableStatusCodes","fetchWithTimeout","url","timeout","headers","controller","timeoutId","HttpService","retryOptions","lastError","response","httpService","fetchGitHubRegistry","branch","registryUrl","components","meta","fetchComponent","metaUrl","fetchComponentFile","fileUrl","RegistryService","componentUrl","visited","resolved","promptForRegistryComponents","availableComponents","addComponents","addService","available","err","addOptionsSchema","add","errorHandler","rawOptions","filterComponents","query","normalized","nameMatch","descriptionMatch","categoryMatch","category","sliceComponents","offset","limit","start","listComponents","sorted","filtered","sliced","chalk","table","Table","listOptionsSchema","list","displayIntro","program"],"mappings":"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","file":"index.js","sourcesContent":["import fsExtra from 'fs-extra'\n\nexport const FILE_BACKUP_SUFFIX = '.bak'\n\nexport function createFileBackup(filePath: string): string | null {\n if (!fsExtra.existsSync(filePath)) {\n return null\n }\n\n const backupPath = `${filePath}${FILE_BACKUP_SUFFIX}`\n try {\n fsExtra.renameSync(filePath, backupPath)\n return backupPath\n } catch (error) {\n console.error(`Failed to create backup of ${filePath}: ${error}`)\n return null\n }\n}\n\nexport function restoreFileBackup(filePath: string): boolean {\n const backupPath = `${filePath}${FILE_BACKUP_SUFFIX}`\n\n if (!fsExtra.existsSync(backupPath)) {\n return false\n }\n\n try {\n fsExtra.renameSync(backupPath, filePath)\n return true\n } catch (error) {\n console.error(\n `Warning: Could not restore backup file ${backupPath}: ${error}`,\n )\n return false\n }\n}\n\nexport function deleteFileBackup(filePath: string): boolean {\n const backupPath = `${filePath}${FILE_BACKUP_SUFFIX}`\n\n if (!fsExtra.existsSync(backupPath)) {\n return false\n }\n\n try {\n fsExtra.unlinkSync(backupPath)\n return true\n } catch {\n // Best effort - don't log as this is just cleanup\n return false\n }\n}\n","import { promises as fs } from 'fs'\nimport path from 'path'\nimport type { IFileSystemService } from '../types/interfaces'\n\n/**\n * Service for file system operations\n */\nexport class FilesystemService implements IFileSystemService {\n /**\n * Check if a file exists\n * @param filePath - Path to check\n * @returns Promise resolving to true if file exists\n */\n async fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Write content to a file, creating directories if necessary\n * @param filePath - Path to write to\n * @param content - Content to write\n * @returns Promise that resolves when file is written\n * @throws Error if write fails\n */\n async writeFile(filePath: string, content: string): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true })\n await fs.writeFile(filePath, content, 'utf-8')\n }\n\n /**\n * Read content from a file\n * @param filePath - Path to read from\n * @returns Promise resolving to file content\n * @throws Error if file doesn't exist or read fails\n */\n async readFile(filePath: string): Promise<string> {\n return await fs.readFile(filePath, 'utf-8')\n }\n\n /**\n * Ensure a directory exists, creating it if necessary\n * @param dirPath - Directory path\n * @returns Promise that resolves when directory is ensured\n * @throws Error if directory creation fails\n */\n async ensureDir(dirPath: string): Promise<void> {\n await fs.mkdir(dirPath, { recursive: true })\n }\n}\n","import fs from 'fs'\n\n/**\n * Check if the current directory is a Laravel project\n * @returns True if Laravel project is detected\n */\nexport function isLaravelProject(): boolean {\n return fs.existsSync('composer.json') && fs.existsSync('artisan')\n}\n","import fs from 'fs'\n\n/**\n * Package.json structure\n */\ninterface PackageJson {\n dependencies?: Readonly<Record<string, string>>\n devDependencies?: Readonly<Record<string, string>>\n}\n\n/**\n * Read package.json file\n * @returns Package.json object or null if file doesn't exist or is invalid\n */\nexport function readPackageJson(): PackageJson | null {\n try {\n return JSON.parse(fs.readFileSync('package.json', 'utf8')) as PackageJson\n } catch {\n return null\n }\n}\n\n/**\n * Detect if Tailwind CSS v4 is installed\n * @param pkg - Package.json object\n * @returns True if Tailwind v4 is detected\n */\nexport function detectTailwindV4(pkg: PackageJson): boolean {\n const deps = { ...pkg.dependencies, ...pkg.devDependencies }\n if (deps['@tailwindcss/vite'] || deps['@tailwindcss/postcss']) {\n return true\n }\n if (deps['tailwindcss']) {\n const version = String(deps['tailwindcss'])\n const match = version.match(/(\\d+)/)\n return match ? Number(match[1]) >= 4 : false\n }\n return false\n}\n","import fs from 'fs'\nimport path from 'path'\n\n/**\n * Check if Alpine.js is listed in package.json dependencies\n * @returns True if Alpine.js is found in dependencies\n */\nexport function hasAlpineInPackageJson(): boolean {\n try {\n const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')) as {\n dependencies?: Readonly<Record<string, string>>\n devDependencies?: Readonly<Record<string, string>>\n }\n const hasInDeps =\n pkg.dependencies &&\n Object.keys(pkg.dependencies).some((dep) =>\n dep.toLowerCase().includes('alpine'),\n )\n const hasInDevDeps =\n pkg.devDependencies &&\n Object.keys(pkg.devDependencies).some((dep) =>\n dep.toLowerCase().includes('alpine'),\n )\n return Boolean(hasInDeps || hasInDevDeps)\n } catch {\n return false\n }\n}\n\n/**\n * Check if Alpine.js is referenced in layout files\n * @returns True if Alpine.js is found in layout files\n */\nexport function hasAlpineInLayouts(): boolean {\n const layoutDir = 'resources/views/layouts'\n if (!fs.existsSync(layoutDir)) return false\n\n try {\n const files = fs.readdirSync(layoutDir, { recursive: true }) as string[]\n for (const file of files) {\n if (file.endsWith('.blade.php')) {\n const content = fs.readFileSync(path.join(layoutDir, file), 'utf8')\n if (content.toLowerCase().includes('alpine')) {\n return true\n }\n }\n }\n } catch {\n return false\n }\n return false\n}\n\n/**\n * Check if Alpine.js is available in the project\n * @returns True if Alpine.js is detected\n */\nexport function hasAlpineJs(): boolean {\n return hasAlpineInPackageJson() || hasAlpineInLayouts()\n}\n","import fs from 'fs'\nimport type { PackageManager } from '../types'\n\n/**\n * Detect the package manager used in the project\n * @returns Detected package manager name (defaults to \"npm\")\n */\nexport function detectPackageManager(): PackageManager {\n // Check lock files\n if (fs.existsSync('pnpm-lock.yaml') || fs.existsSync('pnpm-lock.yml')) {\n return 'pnpm'\n }\n if (fs.existsSync('yarn.lock')) {\n return 'yarn'\n }\n if (fs.existsSync('package-lock.json')) {\n return 'npm'\n }\n if (fs.existsSync('bun.lock')) {\n return 'bun'\n }\n\n // Default to npm\n return 'npm'\n}\n","import fs from 'fs'\nimport type { FileInfo } from '@/src/types'\n\n/**\n * Common CSS file paths to check for main stylesheet\n */\nexport const CSS_CANDIDATES = [\n 'resources/css/app.css',\n 'resources/css/app.scss',\n 'resources/css/main.css',\n 'resources/css/style.css',\n 'resources/css/styles.css',\n] as const\n\n/**\n * Find the main CSS file in the project\n * @returns CSS file info if found, null otherwise\n */\nexport function findMainCss(): FileInfo | null {\n for (const rel of CSS_CANDIDATES) {\n if (fs.existsSync(rel)) {\n return {\n path: rel,\n content: fs.readFileSync(rel, 'utf8'),\n }\n }\n }\n return null\n}\n\n/**\n * Check if CSS content has Tailwind import\n * @param css - CSS content to check\n * @returns True if Tailwind import is found\n */\nexport function hasTailwindImport(css: string): boolean {\n return /@import\\s+[\"']tailwindcss[\"']/.test(css)\n}\n\n/**\n * Inject Velar CSS import into main CSS file\n * @param cssPath - Path to the CSS file\n * @throws Error if file read/write fails\n */\nexport function injectVelarImport(cssPath: string): void {\n let content = fs.readFileSync(cssPath, 'utf8')\n if (content.includes('@import \"./velar.css\"')) {\n return\n }\n if (hasTailwindImport(content)) {\n content = content.replace(\n /@import\\s+[\"']tailwindcss[\"'];?/,\n (match) => `${match}\\n@import \"./velar.css\";`,\n )\n } else {\n content += '\\n@import \"./velar.css\";\\n'\n }\n fs.writeFileSync(cssPath, content, 'utf8')\n}\n","import fs from 'fs'\nimport type { FileInfo } from '@/src/types'\n\n/**\n * Common JS file paths to check for main script\n */\nexport const JS_CANDIDATES = [\n 'resources/js/app.js',\n 'resources/js/main.js',\n 'resources/js/index.js',\n] as const\n\n/**\n * Find the main JS file in the project\n * @returns JS file info if found, null otherwise\n */\nexport function findMainJs(): FileInfo | null {\n for (const rel of JS_CANDIDATES) {\n if (fs.existsSync(rel)) {\n return {\n path: rel,\n content: fs.readFileSync(rel, 'utf8'),\n }\n }\n }\n return null\n}\n\n/**\n * Inject component JS import and Alpine initialization into main JS file\n * @param jsPath - Path to the JS file\n * @param componentName - Name of the component\n * @param componentImportPath - Path to import the component from\n * @throws Error if file read/write fails\n */\nexport function injectComponentJs(\n jsPath: string,\n componentName: string,\n componentImportPath: string,\n): void {\n let content = fs.readFileSync(jsPath, 'utf8')\n\n // Avoid duplicate imports\n const importStatement = `import ${componentName} from '${componentImportPath}'`\n if (\n content.includes(importStatement) ||\n content.includes(`import ${componentName} from \"${componentImportPath}\"`)\n ) {\n return\n }\n\n // Add import at the top (after other imports if possible)\n const lines = content.split('\\n')\n let lastImportIndex = -1\n for (let i = 0; i < lines.length; i++) {\n if (lines[i]?.startsWith('import ')) {\n lastImportIndex = i\n }\n }\n\n lines.splice(lastImportIndex + 1, 0, importStatement)\n content = lines.join('\\n')\n\n // Handle Alpine.data registration\n const alpineDataRegistration = `Alpine.data('${componentName}', ${componentName});`\n\n if (content.includes(\"document.addEventListener('alpine:init'\")) {\n // Inject into existing listener\n if (!content.includes(alpineDataRegistration)) {\n content = content.replace(\n /document\\.addEventListener\\('alpine:init',\\s*\\(\\)\\s*=>\\s*\\{/,\n (match) => `${match}\\n ${alpineDataRegistration}`,\n )\n }\n } else {\n // Create new listener at the end\n content += `\\n\\ndocument.addEventListener('alpine:init', () => {\\n ${alpineDataRegistration}\\n});\\n`\n }\n\n fs.writeFileSync(jsPath, content, 'utf8')\n}\n","import fs from 'fs'\nimport path from 'path'\nimport type { VelarTheme } from '@/src/types'\n\ntype BaseColor = {\n name: VelarTheme\n label: string\n cssVars: {\n light: Record<string, string>\n dark: Record<string, string>\n }\n}\n\nfunction findColorsDir(startDir: string): string {\n let current = startDir\n for (let depth = 0; depth < 4; depth += 1) {\n const distPath = path.join(current, 'colors')\n if (fs.existsSync(distPath)) {\n return distPath\n }\n\n const srcPath = path.join(current, 'src/colors')\n if (fs.existsSync(srcPath)) {\n return srcPath\n }\n\n const parent = path.dirname(current)\n if (parent === current) {\n break\n }\n current = parent\n }\n\n return path.join(startDir, 'colors')\n}\n\nconst entryDir = process.argv[1]\n ? path.dirname(path.resolve(process.argv[1]))\n : process.cwd()\nconst COLORS_DIR = findColorsDir(entryDir)\n\nfunction loadBaseColors(): BaseColor[] {\n if (!fs.existsSync(COLORS_DIR)) {\n return []\n }\n\n const files = fs\n .readdirSync(COLORS_DIR)\n .filter((file) => file.endsWith('.json'))\n\n return files\n .map((file) => {\n const filePath = path.join(COLORS_DIR, file)\n const raw = fs.readFileSync(filePath, 'utf-8')\n return JSON.parse(raw) as BaseColor\n })\n .filter((color) => !!color?.name)\n .sort((a, b) => a.name.localeCompare(b.name))\n}\n\nexport function getBaseColors(): BaseColor[] {\n return loadBaseColors()\n}\n\nexport function getBaseColor(name: VelarTheme): BaseColor | undefined {\n return loadBaseColors().find((color) => color.name === name)\n}\n\nfunction renderCssVars(vars: Record<string, string>): string[] {\n return Object.entries(vars).map(([key, value]) => ` --${key}: ${value};`)\n}\n\n/**\n * Copy a theme CSS file to the target location\n * @param theme - Theme name to copy\n * @param target - Target file path\n * @throws Error if theme doesn't exist or copy fails\n */\nexport function copyTheme(theme: VelarTheme, target: string): void {\n const baseColor = getBaseColor(theme)\n if (!baseColor) {\n throw new Error(`Theme \"${theme}\" not found in colors registry.`)\n }\n\n const lightVars = renderCssVars(baseColor.cssVars.light)\n const darkVars = renderCssVars(baseColor.cssVars.dark)\n\n const content = [\n ':root {',\n ...lightVars,\n '}',\n '',\n '.dark {',\n ...darkVars,\n '}',\n '',\n ].join('\\n')\n\n fs.writeFileSync(target, content, { encoding: 'utf-8', flag: 'wx' })\n}\n","import fs from 'fs'\nimport type { VelarConfig } from '../types'\n\n/**\n * Write Velar configuration to velar.json file\n * @param config - Configuration object to write\n * @throws Error if file write fails\n */\nexport function writeVelarConfig(config: VelarConfig): void {\n fs.writeFileSync('velar.json', JSON.stringify(config, null, 2) + '\\n', 'utf8')\n}\n\n/**\n * Read Velar configuration from velar.json file\n * @returns Configuration object\n * @throws Error if file doesn't exist or is invalid\n */\nexport function readVelarConfig(): VelarConfig {\n if (!fs.existsSync('velar.json')) {\n throw new Error('Velar configuration not found.')\n }\n return JSON.parse(fs.readFileSync('velar.json', 'utf8')) as VelarConfig\n}\n","import { cyan, green, red, yellow } from 'kleur/colors'\n\nexport const highlighter = {\n error: red,\n warn: yellow,\n info: cyan,\n success: green,\n}\n","import { highlighter } from '@/src/utils/highlighter'\n\nexport const logger = {\n error(...args: unknown[]) {\n console.log(highlighter.error(args.join(' ')))\n },\n warn(...args: unknown[]) {\n console.log(highlighter.warn(args.join(' ')))\n },\n info(...args: unknown[]) {\n console.log(highlighter.info(args.join(' ')))\n },\n success(...args: unknown[]) {\n console.log(highlighter.success(args.join(' ')))\n },\n log(...args: unknown[]) {\n console.log(args.join(' '))\n },\n break() {\n console.log('')\n },\n}\n","{\n \"name\": \"velyx\",\n \"version\": \"1.0.0\",\n \"description\": \"CLI to add composable UI components to Laravel projects\",\n \"author\": \"\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=20\"\n },\n \"bin\": {\n \"velyx\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"keywords\": [\n \"laravel\",\n \"cli\",\n \"ui\",\n \"blade\",\n \"tailwind\",\n \"alpine\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/velyx-labs/cli.git\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"packageManager\": \"pnpm@10.28.1+sha512.7d7dbbca9e99447b7c3bf7a73286afaaf6be99251eb9498baefa7d406892f67b879adb3a1d7e687fc4ccc1a388c7175fbaae567a26ab44d1067b54fcb0d6a316\",\n \"pnpm\": {\n \"overrides\": {\n \"cli-spinners\": \"2.9.2\"\n }\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"check:ci\": \"pnpm run lint && pnpm run typecheck\",\n \"clean\": \"rimraf dist\",\n \"dev\": \"tsup --watch\",\n \"check\": \"pnpm run format:write && eslint --fix\",\n \"format:check\": \"prettier --check \\\"**/*.{ts,tsx,mdx}\\\" --cache\",\n \"format:write\": \"prettier --write \\\"**/*.{ts,tsx,mdx}\\\" --cache\",\n \"lint\": \"eslint\",\n \"prepublishOnly\": \"pnpm run build\",\n \"pub:beta\": \"pnpm build && pnpm publish --no-git-checks --access public --tag beta\",\n \"pub:next\": \"pnpm build && pnpm publish --no-git-checks --access public --tag next\",\n \"pub:release\": \"pnpm build && pnpm publish --access public\",\n \"release\": \"changeset version\",\n \"start\": \"node dist/index.js\",\n \"test\": \"vitest run\",\n \"test:coverage\": \"vitest run --coverage\",\n \"test:watch\": \"vitest\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^0.11.0\",\n \"chalk\": \"^5.6.2\",\n \"changeset\": \"^0.2.6\",\n \"cli-table3\": \"^0.6.5\",\n \"commander\": \"^14.0.2\",\n \"fs-extra\": \"^11.3.3\",\n \"kleur\": \"^4.1.5\",\n \"log-symbols\": \"^7.0.1\",\n \"ora\": \"^9.1.0\",\n \"prompts\": \"^2.4.2\",\n \"vite-tsconfig-paths\": \"^6.0.5\",\n \"zod\": \"^3.24.1\",\n \"zod-to-json-schema\": \"^3.24.6\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.39.2\",\n \"@eslint/json\": \"^0.14.0\",\n \"@eslint/markdown\": \"^7.5.1\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/node\": \"^25.0.9\",\n \"@types/prompts\": \"^2.4.9\",\n \"@vitest/coverage-v8\": \"^4.0.18\",\n \"eslint\": \"^9.39.2\",\n \"globals\": \"^17.0.0\",\n \"jiti\": \"^2.6.1\",\n \"prettier\": \"3.8.0\",\n \"rimraf\": \"^6.0.1\",\n \"tsc-alias\": \"^1.8.16\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.53.0\",\n \"vitest\": \"^4.0.18\"\n }\n}\n","import type {\n VelarConfig,\n PackageManager,\n VelarTheme,\n FileInfo,\n} from '@/src/types'\nimport type { IFileSystemService } from '../types/interfaces'\nimport { isLaravelProject } from '../utils/laravel'\nimport { readPackageJson, detectTailwindV4 } from '../utils/tailwind'\nimport { hasAlpineJs } from '../utils/requirements'\nimport { detectPackageManager } from '../utils/package-manager'\nimport { findMainCss, hasTailwindImport, injectVelarImport } from '../utils/css'\nimport { findMainJs } from '../utils/js'\nimport { copyTheme } from '../utils/theme'\nimport { writeVelarConfig } from '../utils/config'\nimport fs from 'fs'\nimport { logger } from '../utils/logger'\nimport packageJson from '../../package.json'\n\n/**\n * Environment validation result\n */\nexport interface EnvironmentValidation {\n /** Whether Laravel project is detected */\n isLaravel: boolean\n /** Whether Tailwind v4 is detected */\n hasTailwindV4: boolean\n /** Whether Alpine.js is detected */\n hasAlpine: boolean\n /** Detected package manager */\n detectedPackageManager: PackageManager\n /** Main CSS file info if found */\n cssFile: FileInfo | null\n /** Main JS file info if found */\n jsFile: FileInfo | null\n /** Whether CSS can be injected */\n canInjectCss: boolean\n}\n\n/**\n * Initialization options\n */\nexport interface InitOptions {\n /** Selected package manager */\n packageManager: PackageManager\n /** Selected theme */\n theme: VelarTheme\n /** Whether to import styles */\n importStyles: boolean\n}\n\n/**\n * Service for handling Velar initialization\n */\nexport class InitService {\n /**\n * Create a new InitService instance\n * @param fileSystem - File system service\n */\n constructor(private readonly fileSystem: IFileSystemService) {}\n\n /**\n * Validate the project environment\n * @returns Environment validation result\n * @throws Error if critical requirements are not met\n */\n validateEnvironment(): EnvironmentValidation {\n // Validate Laravel project\n if (!isLaravelProject()) {\n throw new Error('No Laravel project detected')\n }\n\n // Check Tailwind v4\n const pkg = readPackageJson()\n if (!pkg || !detectTailwindV4(pkg)) {\n throw new Error('Tailwind CSS v4 was not detected')\n }\n\n // Check interactivity frameworks\n const hasAlpine = hasAlpineJs()\n const detectedPm = detectPackageManager()\n\n // Find CSS and JS files\n const css = findMainCss()\n const js = findMainJs()\n const canInject = css ? hasTailwindImport(css.content) : false\n\n return {\n isLaravel: true,\n hasTailwindV4: true,\n hasAlpine,\n detectedPackageManager: detectedPm,\n cssFile: css,\n jsFile: js,\n canInjectCss: canInject,\n }\n }\n\n /**\n * Display environment information and warnings\n * @param validation - Environment validation result\n */\n displayEnvironmentInfo(validation: EnvironmentValidation): void {\n // Display interactivity framework status\n if (!validation.hasAlpine) {\n logger.warn('Alpine.js not detected')\n logger.log(\n `Install Alpine.js: ${validation.detectedPackageManager} install alpinejs`,\n )\n } else {\n logger.success(\n 'Alpine.js detected - components will be fully interactive',\n )\n }\n\n // Display CSS file status\n if (!validation.cssFile) {\n logger.warn('No main CSS file found')\n logger.log('Styles will be created but not auto-imported')\n } else if (!validation.canInjectCss) {\n logger.warn('Tailwind import not found in CSS')\n logger.log('Velar styles will not be auto-imported')\n }\n\n // Display JS file status\n if (!validation.jsFile) {\n logger.warn('No main JS file found')\n logger.log('Component scripts will not be auto-imported')\n }\n }\n\n /**\n * Create the UI components directory\n * @param path - Directory path (default: \"resources/views/components/ui\")\n * @returns Promise that resolves when directory is created\n */\n async createComponentsDirectory(\n path = 'resources/views/components/ui',\n ): Promise<void> {\n await this.fileSystem.ensureDir(path)\n }\n\n /**\n * Create the Velar theme CSS file\n * @param theme - Theme to use\n * @param targetPath - Target CSS file path (default: \"resources/css/velar.css\")\n * @returns Promise that resolves when theme is created\n * @throws Error if theme creation fails\n */\n async createThemeFile(\n theme: VelarTheme,\n targetPath = 'resources/css/velar.css',\n ): Promise<void> {\n // Ensure directory exists\n const dirPath = targetPath.split('/').slice(0, -1).join('/')\n await this.fileSystem.ensureDir(dirPath)\n\n // Create theme file if it doesn't exist\n if (!fs.existsSync(targetPath)) {\n try {\n copyTheme(theme, targetPath)\n logger.success('Velar theme created')\n logger.info(targetPath)\n } catch (error) {\n throw new Error(\n `Failed to create theme file: ${(error as Error).message}`,\n )\n }\n } else {\n logger.info('velar.css already exists')\n }\n }\n\n /**\n * Inject Velar styles import into main CSS file\n * @param cssPath - Path to main CSS file\n * @returns Promise that resolves when import is injected\n */\n async injectStylesImport(cssPath: string): Promise<void> {\n injectVelarImport(cssPath)\n logger.success('Velar styles imported')\n logger.info(cssPath)\n }\n\n /**\n * Generate and write Velar configuration file\n * @param options - Initialization options\n * @param validation - Environment validation result\n * @returns Promise that resolves when config is written\n */\n async generateConfig(\n options: InitOptions,\n validation: EnvironmentValidation,\n ): Promise<void> {\n const config: VelarConfig = {\n version: packageJson.version as string,\n theme: options.theme,\n packageManager: options.packageManager,\n css: {\n entry: validation.cssFile?.path ?? '',\n velar: 'resources/css/velar.css',\n },\n js: {\n entry: validation.jsFile?.path ?? '',\n },\n components: {\n path: 'resources/views/components/ui',\n },\n }\n\n writeVelarConfig(config)\n logger.success('velar.json config generated')\n }\n\n /**\n * Display initialization summary\n * @param options - Initialization options\n * @param validation - Environment validation result\n * @param stylesImported - Whether styles were imported\n */\n displaySummary(\n options: InitOptions,\n validation: EnvironmentValidation,\n stylesImported: boolean,\n ): void {\n console.log('\\n---')\n logger.success('Laravel project detected')\n logger.success('Tailwind CSS v4 detected')\n logger.success(`Theme selected: ${options.theme}`)\n logger.success(`Package manager: ${options.packageManager}`)\n logger.success('UI components directory ready')\n if (validation.jsFile) {\n logger.success('Main JS file detected')\n }\n logger.success(\n stylesImported ? 'Styles import complete' : 'Styles import pending',\n )\n logger.success('velar.json created')\n console.log('\\nNext steps:')\n console.log(' velar add button')\n console.log(\n '\\n💡 Want to customize your Tailwind palette? Try https://tweakcn.com/ — a visual generator for Tailwind-compatible color scales.',\n )\n }\n}\n","import ora, { type Ora } from 'ora'\n\n/**\n * Utility to manage loading spinners\n */\nexport const spinner = {\n /**\n * Starts a spinner with a message\n * @param message - Message to display\n * @returns Ora spinner instance\n */\n start(message: string): Ora {\n return ora(message).start()\n },\n\n /**\n * Executes an asynchronous task with a spinner\n * @param message - Message during loading\n * @param task - Asynchronous function to execute\n * @param successMessage - Optional success message\n * @param failMessage - Optional error message\n * @returns Task result\n */\n async withTask<T>(\n message: string,\n task: () => Promise<T>,\n successMessage?: string,\n failMessage?: string,\n ): Promise<T> {\n const s = this.start(message)\n try {\n const result = await task()\n if (successMessage) {\n s.succeed(successMessage)\n } else {\n s.stop()\n }\n return result\n } catch (error) {\n s.fail(failMessage || 'Operation failed')\n throw error\n }\n },\n}\n","import { exec } from 'child_process'\nimport path from 'path'\nimport fs from 'fs-extra'\nimport { promisify } from 'util'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\nimport { spinner } from '@/src/utils/spinner'\nimport prompts from 'prompts'\nimport { detectPackageManager } from '@/src/utils/package-manager'\nimport type { InitOptions } from '@/src/utils/init-project'\nimport type { PackageManager } from '@/src/types'\n\nconst execAsync = promisify(exec)\n\nexport interface ProjectInfo {\n name: string\n framework: {\n name: string\n label: string\n version?: string\n }\n hasAlpine: boolean\n hasVite: boolean\n packageManager: PackageManager\n paths: {\n views: string\n assets: string\n public: string\n config: string\n }\n}\n\nexport async function getProjectInfo(cwd: string): Promise<ProjectInfo | null> {\n try {\n const composerPath = path.resolve(cwd, 'composer.json')\n const packagePath = path.resolve(cwd, 'package.json')\n\n if (!fs.existsSync(composerPath)) {\n return null\n }\n\n const composer = await fs.readJson(composerPath)\n const isLaravel =\n composer.require?.['laravel/framework'] ||\n composer.require?.['illuminate/foundation']\n\n if (!isLaravel) {\n return null\n }\n\n // Détecter le package manager\n const originalDir = process.cwd()\n process.chdir(cwd)\n const pkgManager = detectPackageManager()\n console.log(`Detected package manager: ${pkgManager}`)\n process.chdir(originalDir)\n\n const projectInfo: ProjectInfo = {\n name: composer.name || path.basename(cwd),\n framework: {\n name: 'laravel',\n label: 'Laravel',\n version: composer.require?.['laravel/framework'] || 'unknown',\n },\n hasAlpine: false,\n hasVite: false,\n packageManager: pkgManager,\n paths: {\n views: 'resources/views',\n assets: 'resources/js',\n public: 'public',\n config: 'config',\n },\n }\n\n // Vérifier les dépendances frontend\n if (fs.existsSync(packagePath)) {\n const pkg = await fs.readJson(packagePath)\n projectInfo.hasAlpine = !!(\n pkg.dependencies?.alpinejs || pkg.devDependencies?.alpinejs\n )\n projectInfo.hasVite = !!pkg.devDependencies?.vite\n }\n\n // Vérifier la structure des dossiers\n const viewsPath = path.resolve(cwd, 'resources/views')\n const assetsPath = path.resolve(cwd, 'resources/js')\n\n if (fs.existsSync(viewsPath)) {\n projectInfo.paths.views = 'resources/views'\n }\n\n if (fs.existsSync(assetsPath)) {\n projectInfo.paths.assets = 'resources/js'\n }\n\n return projectInfo\n } catch {\n return null\n }\n}\n\nexport async function preFlightInit(options: InitOptions): Promise<{\n errors: Record<string, boolean>\n projectInfo: ProjectInfo | null\n}> {\n const errors: Record<string, boolean> = {}\n\n // Vérifier si le répertoire existe\n if (!fs.existsSync(options.cwd)) {\n errors['MISSING_DIR'] = true\n return { errors, projectInfo: null }\n }\n\n const projectSpinner = spinner.start('Checking project environment...')\n\n // Vérifier si velar.json existe déjà\n const velarConfigPath = path.resolve(options.cwd, 'velar.json')\n if (fs.existsSync(velarConfigPath) && !options.force) {\n projectSpinner.fail()\n logger.break()\n\n const { action } = await prompts({\n type: 'select',\n name: 'action',\n message: `A ${highlighter.info('velar.json')} file already exists. What would you like to do?`,\n choices: [\n {\n title: 'Re-initialize Velar configuration',\n value: 'reinit',\n },\n {\n title: 'Keep existing configuration',\n value: 'keep',\n },\n {\n title: 'Exit',\n value: 'exit',\n },\n ],\n initial: 0,\n })\n\n if (action === 'exit') {\n logger.log('Operation cancelled.')\n process.exit(0)\n }\n\n if (action === 'keep') {\n logger.log('Keeping existing configuration.')\n process.exit(0)\n }\n\n // Continue with re-initialization\n logger.log(`Re-initializing Velar configuration...`)\n }\n\n // Récupérer les infos du projet\n const projectInfo = await getProjectInfo(options.cwd)\n\n if (!projectInfo || projectInfo.framework.name !== 'laravel') {\n errors['UNSUPPORTED_PROJECT'] = true\n projectSpinner.fail()\n logger.break()\n logger.error(\n `We could not detect a supported Laravel project at ${highlighter.info(\n options.cwd,\n )}.\\nVelar is designed to work with Laravel projects.`,\n )\n logger.break()\n process.exit(1)\n }\n\n projectSpinner.succeed(\n `Found ${highlighter.info(projectInfo.framework.label)} project`,\n )\n\n // Vérifier Alpine.js\n const alpineSpinner = spinner.start('Checking Alpine.js...')\n\n if (!projectInfo.hasAlpine) {\n alpineSpinner.fail()\n logger.break()\n logger.warn(`Alpine.js is required but not found in your project.`)\n\n // Proposer d'installer Alpine.js directement\n const { installAlpine } = await prompts({\n type: 'confirm',\n name: 'installAlpine',\n message: 'Would you like to install Alpine.js now?',\n initial: true,\n })\n\n if (installAlpine) {\n // Installer Alpine.js avec le package manager détecté\n const pkgManager = projectInfo.packageManager\n const installSpinner = spinner.start(\n `Installing Alpine.js with ${pkgManager}...`,\n )\n\n try {\n await execAsync(`${pkgManager} install alpinejs`, {\n cwd: options.cwd,\n })\n installSpinner.succeed('Alpine.js installed successfully')\n projectInfo.hasAlpine = true\n } catch (error) {\n installSpinner.fail(\n `Failed to install Alpine.js: ${(error as Error).message}`,\n )\n logger.error(\n `Please install Alpine.js manually: ${highlighter.info(`${pkgManager} install alpinejs`)}`,\n )\n logger.break()\n process.exit(1)\n }\n } else {\n const pkgManager = projectInfo.packageManager\n logger.error(\n `Alpine.js is required. Install it with: ${highlighter.info(`${pkgManager} install alpinejs`)}`,\n )\n logger.break()\n process.exit(1)\n }\n } else {\n alpineSpinner.succeed('Alpine.js found')\n }\n\n // Vérifier Vite (recommandé pour Velar)\n const viteSpinner = spinner.start('Checking build tools...')\n\n if (!projectInfo.hasVite) {\n logger.warn(\n `Vite not found. Using Vite is recommended for better development experience.`,\n )\n viteSpinner.warn('Vite not found (but optional)')\n } else {\n viteSpinner.succeed('Vite found')\n }\n\n // Afficher les erreurs bloquantes\n if (Object.keys(errors).length > 0) {\n logger.break()\n process.exit(1)\n }\n\n return { errors, projectInfo }\n}\n","import prompts from 'prompts'\nimport { FilesystemService } from '@/src/services/filesystem-service'\nimport { InitService } from '@/src/services/init-service'\nimport { preFlightInit, type ProjectInfo } from '@/src/utils/preflight-init'\nimport { getBaseColors } from '@/src/utils/theme'\nimport { logger } from '@/src/utils/logger'\nimport { highlighter } from '@/src/utils/highlighter'\nimport type { VelarTheme } from '@/src/types'\nimport { z } from 'zod'\n\nexport const initOptionsSchema = z.object({\n baseColor: z.string().optional(),\n yes: z.boolean(),\n defaults: z.boolean(),\n force: z.boolean(),\n cwd: z.string(),\n silent: z.boolean(),\n})\n\nexport type InitOptions = z.infer<typeof initOptionsSchema>\n\nasync function promptTheme(): Promise<VelarTheme> {\n const baseColors = getBaseColors()\n if (baseColors.length === 0) {\n logger.error('No base colors available.')\n process.exit(1)\n }\n const { theme } = await prompts(\n {\n type: 'select',\n name: 'theme',\n message: 'Choose a base color theme',\n choices: baseColors.map((color) => ({\n title: color.label,\n value: color.name,\n })),\n },\n {\n onCancel: () => {\n logger.error('Theme selection aborted')\n process.exit(1)\n },\n },\n )\n\n return theme as VelarTheme\n}\n\nasync function promptStyleImport(): Promise<boolean> {\n const { shouldImport } = await prompts(\n {\n type: 'confirm',\n name: 'shouldImport',\n message: 'Import Velar styles into your main CSS file?',\n initial: true,\n },\n {\n onCancel: () => false,\n },\n )\n\n return Boolean(shouldImport)\n}\n\nfunction resolveThemeFromOptions(options: InitOptions): VelarTheme | undefined {\n if (!options.baseColor) {\n return undefined\n }\n\n const baseColors = getBaseColors()\n const matched = baseColors.find((color) => color.name === options.baseColor)\n if (matched) {\n return matched.name\n }\n\n logger.warn(`Unknown base color \"${options.baseColor}\".`)\n return undefined\n}\n\nexport async function initProject(\n options: InitOptions,\n projectInfo?: ProjectInfo | null,\n): Promise<void> {\n // Use provided projectInfo or run preflight checks\n if (!projectInfo) {\n const preflight = await preFlightInit(options)\n projectInfo = preflight.projectInfo\n }\n\n process.chdir(options.cwd)\n\n const fileSystem = new FilesystemService()\n const initService = new InitService(fileSystem)\n\n try {\n const validation = initService.validateEnvironment()\n initService.displayEnvironmentInfo(validation)\n\n // Use the package manager already detected in preflight checks\n const packageManager = projectInfo!.packageManager\n\n const baseColors = getBaseColors()\n const defaultTheme =\n baseColors.find((color) => color.name === 'neutral')?.name ??\n baseColors[0]?.name\n\n let theme = resolveThemeFromOptions(options)\n if (!theme) {\n theme =\n options.defaults && defaultTheme ? defaultTheme : await promptTheme()\n }\n\n if (!theme) {\n logger.error('No base color available.')\n process.exit(1)\n }\n\n await initService.createComponentsDirectory()\n await initService.createThemeFile(theme)\n\n let stylesImported = false\n if (validation.cssFile && validation.canInjectCss) {\n if (options.defaults || (await promptStyleImport())) {\n await initService.injectStylesImport(validation.cssFile.path)\n stylesImported = true\n }\n }\n\n await initService.generateConfig(\n {\n packageManager,\n theme,\n importStyles: stylesImported,\n },\n validation,\n )\n\n initService.displaySummary(\n {\n packageManager,\n theme,\n importStyles: stylesImported,\n },\n validation,\n stylesImported,\n )\n } catch (error) {\n logger.error((error as Error).message)\n if (error instanceof Error) {\n if (error.message.includes('Laravel project')) {\n logger.log('Run velar init at the root of a Laravel project')\n } else if (error.message.includes('Tailwind')) {\n logger.log(`Velar requires ${highlighter.info('Tailwind CSS v4+')}`)\n }\n }\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport path from 'path'\nimport { deleteFileBackup, restoreFileBackup } from '@/src/utils/file-helper'\nimport { initOptionsSchema, initProject } from '@/src/utils/init-project'\n\nprocess.on('exit', (code) => {\n const filePath = path.resolve(process.cwd(), 'velar.json')\n\n // Delete backup if successful.\n if (code === 0) {\n return deleteFileBackup(filePath)\n }\n\n // Restore backup if error.\n return restoreFileBackup(filePath)\n})\n\nexport const init = new Command()\n .name('init')\n .description('initialize your project and install dependencies')\n .option(\n '-b, --base-color <base-color>',\n 'the base color to use. (neutral, gray, zinc, stone, slate)',\n undefined,\n )\n .option('-y, --yes', 'skip confirmation prompt.', true)\n .option('-d, --defaults', 'use default configuration.', false)\n .option('-f, --force', 'force overwrite of existing configuration.', false)\n .option(\n '-c, --cwd <cwd>',\n 'the working directory. defaults to the current directory.',\n process.cwd(),\n )\n .option('-s, --silent', 'mute output.', false)\n .action(async (opts) => {\n const options = initOptionsSchema.parse({\n baseColor: opts.baseColor,\n yes: Boolean(opts.yes),\n defaults: Boolean(opts.defaults),\n force: Boolean(opts.force),\n cwd: path.resolve(opts.cwd),\n silent: Boolean(opts.silent),\n })\n\n await initProject(options)\n })\n","/**\n * Custom error class for Velar-specific errors with code and context\n */\nexport class VelarError extends Error {\n /**\n * Create a new VelarError\n * @param message - Error message\n * @param code - Error code for categorization\n * @param context - Additional context data\n */\n constructor(\n message: string,\n public readonly code: string,\n public readonly context?: Readonly<Record<string, unknown>>,\n ) {\n super(message)\n this.name = 'VelarError'\n }\n}\n\n/**\n * Handles and formats errors for display\n */\nexport class ErrorHandler {\n /**\n * Handle an error and display it appropriately\n * @param error - Error to handle\n * @param context - Context where the error occurred\n */\n handle(error: Error, context: string): void {\n if (error instanceof VelarError) {\n console.error(`[${error.code}] ${error.message}`)\n if (error.context) {\n console.error('Context:', error.context)\n }\n } else {\n console.error(`Unexpected error in ${context}: ${error.message}`)\n }\n\n // Don't exit here, let the caller handle it\n }\n}\n","import { z } from 'zod'\n\n// Error codes for programmatic error handling\nexport const RegistryErrorCode = {\n // Network errors\n NETWORK_ERROR: 'NETWORK_ERROR',\n NOT_FOUND: 'NOT_FOUND',\n UNAUTHORIZED: 'UNAUTHORIZED',\n FORBIDDEN: 'FORBIDDEN',\n FETCH_ERROR: 'FETCH_ERROR',\n\n // Configuration errors\n NOT_CONFIGURED: 'NOT_CONFIGURED',\n INVALID_CONFIG: 'INVALID_CONFIG',\n MISSING_ENV_VARS: 'MISSING_ENV_VARS',\n\n // File system errors\n LOCAL_FILE_ERROR: 'LOCAL_FILE_ERROR',\n\n // Parsing errors\n PARSE_ERROR: 'PARSE_ERROR',\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n\n // Generic errors\n UNKNOWN_ERROR: 'UNKNOWN_ERROR',\n} as const\n\nexport type RegistryErrorCode =\n (typeof RegistryErrorCode)[keyof typeof RegistryErrorCode]\n\nexport class RegistryError extends Error {\n public readonly code: RegistryErrorCode\n public readonly statusCode?: number\n public readonly context?: Record<string, unknown>\n public readonly suggestion?: string\n public readonly timestamp: Date\n public readonly cause?: unknown\n\n constructor(\n message: string,\n options: {\n code?: RegistryErrorCode\n statusCode?: number\n cause?: unknown\n context?: Record<string, unknown>\n suggestion?: string\n } = {},\n ) {\n super(message)\n this.name = 'RegistryError'\n this.code = options.code || RegistryErrorCode.UNKNOWN_ERROR\n this.statusCode = options.statusCode\n this.cause = options.cause\n this.context = options.context\n this.suggestion = options.suggestion\n this.timestamp = new Date()\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor)\n }\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n statusCode: this.statusCode,\n context: this.context,\n suggestion: this.suggestion,\n timestamp: this.timestamp,\n stack: this.stack,\n }\n }\n}\n\nexport class RegistryNotFoundError extends RegistryError {\n constructor(\n public readonly url: string,\n cause?: unknown,\n ) {\n const message = `The item at ${url} was not found. It may not exist at the registry.`\n\n super(message, {\n code: RegistryErrorCode.NOT_FOUND,\n statusCode: 404,\n cause,\n context: { url },\n suggestion:\n 'Check if the item name is correct and the registry URL is accessible.',\n })\n this.name = 'RegistryNotFoundError'\n }\n}\n\nexport class RegistryUnauthorizedError extends RegistryError {\n constructor(\n public readonly url: string,\n cause?: unknown,\n ) {\n const message = `You are not authorized to access the item at ${url}. If this is a remote registry, you may need to authenticate.`\n\n super(message, {\n code: RegistryErrorCode.UNAUTHORIZED,\n statusCode: 401,\n cause,\n context: { url },\n suggestion:\n 'Check your authentication credentials and environment variables.',\n })\n this.name = 'RegistryUnauthorizedError'\n }\n}\n\nexport class RegistryForbiddenError extends RegistryError {\n constructor(\n public readonly url: string,\n cause?: unknown,\n ) {\n const message = `You are not authorized to access the item at ${url}. If this is a remote registry, you may need to authenticate.`\n\n super(message, {\n code: RegistryErrorCode.FORBIDDEN,\n statusCode: 403,\n cause,\n context: { url },\n suggestion:\n 'Check your authentication credentials and environment variables.',\n })\n this.name = 'RegistryForbiddenError'\n }\n}\n\nexport class RegistryFetchError extends RegistryError {\n constructor(\n public readonly url: string,\n statusCode?: number,\n public readonly responseBody?: string,\n cause?: unknown,\n ) {\n // Use the error detail from the server if available\n const baseMessage = statusCode\n ? `Failed to fetch from registry (${statusCode}): ${url}`\n : `Failed to fetch from registry: ${url}`\n\n const message =\n typeof cause === 'string' && cause\n ? `${baseMessage} - ${cause}`\n : baseMessage\n\n let suggestion = 'Check your network connection and try again.'\n if (statusCode === 404) {\n suggestion =\n 'The requested resource was not found. Check the URL or item name.'\n } else if (statusCode === 500) {\n suggestion = 'The registry server encountered an error. Try again later.'\n } else if (statusCode && statusCode >= 400 && statusCode < 500) {\n suggestion = 'There was a client error. Check your request parameters.'\n }\n\n super(message, {\n code: RegistryErrorCode.FETCH_ERROR,\n statusCode,\n cause,\n context: { url, responseBody },\n suggestion,\n })\n this.name = 'RegistryFetchError'\n }\n}\n\nexport class RegistryNotConfiguredError extends RegistryError {\n constructor(public readonly registryName: string | null) {\n const message = registryName\n ? `Unknown registry \"${registryName}\". Make sure it is defined in components.json as follows:\n{\n \"registries\": {\n \"${registryName}\": \"[URL_TO_REGISTRY]\"\n }\n}`\n : `Unknown registry. Make sure it is defined in components.json under \"registries\".`\n\n super(message, {\n code: RegistryErrorCode.NOT_CONFIGURED,\n context: { registryName },\n suggestion:\n 'Add the registry configuration to your components.json file. Consult the registry documentation for the correct format.',\n })\n this.name = 'RegistryNotConfiguredError'\n }\n}\n\nexport class RegistryLocalFileError extends RegistryError {\n constructor(\n public readonly filePath: string,\n cause?: unknown,\n ) {\n super(`Failed to read local registry file: ${filePath}`, {\n code: RegistryErrorCode.LOCAL_FILE_ERROR,\n cause,\n context: { filePath },\n suggestion: 'Check if the file exists and you have read permissions.',\n })\n this.name = 'RegistryLocalFileError'\n }\n}\n\nexport class RegistryParseError extends RegistryError {\n public readonly parseError: unknown\n\n constructor(\n public readonly item: string,\n parseError: unknown,\n ) {\n let message = `Failed to parse registry item: ${item}`\n\n if (parseError instanceof z.ZodError) {\n message = `Failed to parse registry item: ${item}\\n${parseError.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n')}`\n }\n\n super(message, {\n code: RegistryErrorCode.PARSE_ERROR,\n cause: parseError,\n context: { item },\n suggestion:\n 'The registry item may be corrupted or have an invalid format. Please make sure it returns a valid JSON object. See https://ui.shadcn.com/schema/registry-item.json.',\n })\n\n this.parseError = parseError\n this.name = 'RegistryParseError'\n }\n}\n\nexport class RegistryMissingEnvironmentVariablesError extends RegistryError {\n constructor(\n public readonly registryName: string,\n public readonly missingVars: string[],\n ) {\n const message =\n `Registry \"${registryName}\" requires the following environment variables:\\n\\n` +\n missingVars.map((v) => ` • ${v}`).join('\\n')\n\n super(message, {\n code: RegistryErrorCode.MISSING_ENV_VARS,\n context: { registryName, missingVars },\n suggestion:\n 'Set the required environment variables to your .env or .env.local file.',\n })\n this.name = 'RegistryMissingEnvironmentVariablesError'\n }\n}\n\nexport class RegistryInvalidNamespaceError extends RegistryError {\n constructor(public readonly name: string) {\n const message = `Invalid registry namespace: \"${name}\". Registry names must start with @ (e.g., @shadcn, @v0).`\n\n super(message, {\n code: RegistryErrorCode.VALIDATION_ERROR,\n context: { name },\n suggestion:\n 'Use a valid registry name starting with @ or provide a direct URL to the registry.',\n })\n this.name = 'RegistryInvalidNamespaceError'\n }\n}\n\nexport class ConfigMissingError extends RegistryError {\n constructor(public readonly cwd: string) {\n const message = `No components.json found in ${cwd} or parent directories.`\n\n super(message, {\n code: RegistryErrorCode.NOT_CONFIGURED,\n context: { cwd },\n suggestion:\n \"Run 'npx shadcn@latest init' to create a components.json file, or check that you're in the correct directory.\",\n })\n this.name = 'ConfigMissingError'\n }\n}\n\nexport class ConfigParseError extends RegistryError {\n constructor(\n public readonly cwd: string,\n parseError: unknown,\n ) {\n let message = `Invalid components.json configuration in ${cwd}.`\n\n if (parseError instanceof z.ZodError) {\n message = `Invalid components.json configuration in ${cwd}:\\n${parseError.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n')}`\n }\n\n super(message, {\n code: RegistryErrorCode.INVALID_CONFIG,\n cause: parseError,\n context: { cwd },\n suggestion:\n \"Check your components.json file for syntax errors or invalid configuration. Run 'npx shadcn@latest init' to regenerate a valid configuration.\",\n })\n this.name = 'ConfigParseError'\n }\n}\n\nexport class RegistriesIndexParseError extends RegistryError {\n public readonly parseError: unknown\n\n constructor(parseError: unknown) {\n let message = 'Failed to parse registries index'\n\n if (parseError instanceof z.ZodError) {\n const invalidNamespaces = parseError.errors\n .filter((e) => e.path.length > 0)\n .map((e) => `\"${e.path[0]}\"`)\n .filter((v, i, arr) => arr.indexOf(v) === i) // remove duplicates\n\n if (invalidNamespaces.length > 0) {\n message = `Failed to parse registries index. Invalid registry namespace(s): ${invalidNamespaces.join(\n ', ',\n )}\\n${parseError.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n')}`\n } else {\n message = `Failed to parse registries index:\\n${parseError.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n')}`\n }\n }\n\n super(message, {\n code: RegistryErrorCode.PARSE_ERROR,\n cause: parseError,\n context: { parseError },\n suggestion:\n 'The registries index may be corrupted or have invalid registry namespace format. Registry names must start with @ (e.g., @shadcn, @example).',\n })\n\n this.parseError = parseError\n this.name = 'RegistriesIndexParseError'\n }\n}\n\nexport class InvalidConfigIconLibraryError extends RegistryError {\n constructor(\n public readonly iconLibrary: string,\n public readonly validOptions: string[],\n ) {\n const message = `Invalid icon library \"${iconLibrary}\". Valid options are: ${validOptions.join(\n ', ',\n )}`\n\n super(message, {\n code: RegistryErrorCode.INVALID_CONFIG,\n context: { iconLibrary, validOptions },\n suggestion: `Update the \"iconLibrary\" field in your components.json to one of: ${validOptions.join(\n ', ',\n )}`,\n })\n this.name = 'InvalidConfigIconLibraryError'\n }\n}\n\nexport const MISSING_DIR_OR_EMPTY_PROJECT = '1'\nexport const EXISTING_CONFIG = '2'\nexport const MISSING_CONFIG = '3'\nexport const FAILED_CONFIG_READ = '4'\nexport const TAILWIND_NOT_CONFIGURED = '5'\nexport const IMPORT_ALIAS_MISSING = '6'\nexport const UNSUPPORTED_FRAMEWORK = '7'\nexport const COMPONENT_URL_NOT_FOUND = '8'\nexport const COMPONENT_URL_UNAUTHORIZED = '9'\nexport const COMPONENT_URL_FORBIDDEN = '10'\nexport const COMPONENT_URL_BAD_REQUEST = '11'\nexport const COMPONENT_URL_INTERNAL_SERVER_ERROR = '12'\nexport const BUILD_MISSING_REGISTRY_FILE = '13'\nexport const INVALID_CONFIG_ICON_LIBRARY = '14'\n","import { RegistryError } from '@/src/utils/errors'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\nimport { z } from 'zod'\n\nexport function handleError(error: unknown): void {\n logger.break()\n logger.error(\n `Something went wrong. Please check the error below for more details.`,\n )\n logger.error(`If the problem persists, please open an issue on GitHub.`)\n logger.error('')\n if (typeof error === 'string') {\n logger.error(error)\n logger.break()\n process.exit(1)\n }\n\n if (error instanceof RegistryError) {\n if (error.message) {\n logger.error(error.cause ? 'Error:' : 'Message:')\n logger.error(error.message)\n }\n\n if (error.cause) {\n logger.error('\\nMessage:')\n logger.error(error.cause)\n }\n\n if (error.suggestion) {\n logger.error('\\nSuggestion:')\n logger.error(error.suggestion)\n }\n logger.break()\n process.exit(1)\n }\n\n if (error instanceof z.ZodError) {\n logger.error('Validation failed:')\n for (const [key, value] of Object.entries(error.flatten().fieldErrors)) {\n logger.error(`- ${highlighter.info(key)}: ${value}`)\n }\n logger.break()\n process.exit(1)\n }\n\n if (error instanceof Error) {\n logger.error(error.message)\n logger.break()\n process.exit(1)\n }\n\n logger.break()\n process.exit(1)\n}\n","import type { VelarConfig, PackageManager, VelarTheme } from '@/src/types'\nimport type { IConfigManager } from '@/src/types/interfaces'\nimport { readVelarConfig } from '@/src/utils/config'\nimport { logger } from '@/src/utils/logger'\nimport { handleError } from '@/src/utils/handle-error'\n\n/**\n * Manages Velar configuration loading and access\n */\nexport class ConfigManager implements IConfigManager {\n private config?: VelarConfig\n\n /**\n * Load configuration from file\n * @returns Promise resolving to configuration\n * @throws Error if configuration not found or invalid\n */\n async load(): Promise<VelarConfig> {\n try {\n this.config = readVelarConfig()\n if (!this.config) {\n logger.error('')\n handleError(new Error('Configuration not found'))\n process.exit(1)\n }\n return this.config\n } catch {\n logger.error('')\n handleError(new Error('Something went wrong. Please try again.'))\n process.exit(1)\n }\n }\n\n /**\n * Get the package manager from config\n * @returns Package manager name\n * @throws Error if config not loaded\n */\n getPackageManager(): PackageManager {\n if (!this.config) {\n throw new Error('Configuration not loaded')\n }\n return (this.config.packageManager || 'npm') as PackageManager\n }\n\n /**\n * Validate that configuration is loaded\n * @returns True if configuration is valid\n */\n validate(): boolean {\n return !!this.config\n }\n\n /**\n * Get the components path from config\n * @returns Components directory path\n * @throws Error if config not loaded\n */\n getComponentsPath(): string {\n if (!this.config) {\n throw new Error('Configuration not loaded')\n }\n return this.config.components.path\n }\n\n /**\n * Get the theme CSS path from config\n * @returns Theme CSS file path\n * @throws Error if config not loaded\n */\n getThemePath(): string {\n if (!this.config) {\n throw new Error('Configuration not loaded')\n }\n return this.config.css.velar\n }\n\n /**\n * Get the JS entry path from config\n * @returns JS entry file path\n * @throws Error if config not loaded\n */\n getJsEntryPath(): string {\n if (!this.config) {\n throw new Error('Configuration not loaded')\n }\n return this.config.js?.entry ?? ''\n }\n\n /**\n * Get the selected theme from config\n * @returns Theme name\n * @throws Error if config not loaded\n */\n getTheme(): VelarTheme {\n if (!this.config) {\n throw new Error('Configuration not loaded')\n }\n return this.config.theme as VelarTheme\n }\n}\n","import { exec } from 'child_process'\nimport { promisify } from 'util'\nimport type { PackageManager, VelarDependency } from '@/src/types'\nimport type { IDependencyService } from '@/src/types/interfaces'\nimport { logger } from '@/src/utils/logger'\nimport { FilesystemService } from './filesystem-service'\n\nconst execAsync = promisify(exec)\n\n/**\n * Convert npm-style dependency string to Composer format\n * @param dep - Dependency string in npm format (e.g., \"vendor/package@1.0.0\")\n * @returns Dependency string in Composer format (e.g., \"vendor/package:1.0.0\")\n */\nfunction convertNpmToComposerFormat(dep: string): string {\n // Replace @ with : for version constraint\n // But only if it's not a scoped package (starting with @)\n if (dep.startsWith('@')) {\n // Scoped npm package like @alpinejs/alpinejs - return as-is for npm\n return dep\n }\n // Replace @ with : for Composer packages\n return dep.replace('@', ':')\n}\n\n/**\n * Service for managing dependency installation\n */\nexport class DependencyService implements IDependencyService {\n private readonly fileSystem: FilesystemService\n\n constructor(fileSystem?: FilesystemService) {\n this.fileSystem = fileSystem ?? new FilesystemService()\n }\n\n /**\n * Install component dependencies using appropriate package managers\n * @param dependencies - Dependencies to install\n * @param packageManager - Package manager to use for npm dependencies\n * @returns Promise that resolves when installation is complete\n */\n async installDependencies(\n dependencies: VelarDependency,\n packageManager: PackageManager,\n ): Promise<void> {\n const npmPromises = []\n const composerPromises = []\n\n // Install npm dependencies\n if (dependencies.npm && dependencies.npm.length > 0) {\n npmPromises.push(\n this.installNpmDependencies(dependencies.npm, packageManager),\n )\n }\n\n // Install composer dependencies\n if (dependencies.composer && dependencies.composer.length > 0) {\n composerPromises.push(\n this.installComposerDependencies(dependencies.composer),\n )\n }\n\n // Execute installations in parallel\n await Promise.allSettled([...npmPromises, ...composerPromises])\n }\n\n /**\n * Install npm/yarn/pnpm/bun dependencies\n * @param dependencies - Array of dependency strings (e.g., \"alpinejs@^3.14.0\")\n * @param packageManager - Package manager to use\n * @returns Promise that resolves when installation is complete\n */\n async installNpmDependencies(\n dependencies: readonly string[],\n packageManager: PackageManager,\n ): Promise<void> {\n if (!this.fileSystem.fileExists('package.json')) {\n logger.warn('No package.json found, skipping npm dependencies')\n return\n }\n\n const missingDeps = await this.filterMissingNpmDependencies(dependencies)\n\n if (missingDeps.length === 0) {\n logger.info('All npm dependencies already installed')\n return\n }\n\n const command = this.getNpmInstallCommand(packageManager, missingDeps)\n\n try {\n logger.info(`Installing npm dependencies: ${missingDeps.join(', ')}`)\n\n const { stdout, stderr } = await execAsync(command, {\n cwd: process.cwd(),\n timeout: 120000, // 2 minutes timeout\n })\n\n if (stdout && process.env.NODE_ENV !== 'test') {\n console.log(stdout)\n }\n\n if (stderr && !stderr.includes('WARN')) {\n logger.warn(`npm install warnings: ${stderr}`)\n }\n\n logger.success(`Installed ${missingDeps.length} npm dependencies`)\n } catch (error) {\n logger.error(\n `Failed to install npm dependencies: ${(error as Error).message}`,\n )\n throw error\n }\n }\n\n /**\n * Install composer dependencies\n * @param dependencies - Array of dependency strings (e.g., \"livewire/livewire:^3.0\" or \"livewire/livewire@^3.0\")\n * @returns Promise that resolves when installation is complete\n */\n async installComposerDependencies(\n dependencies: readonly string[],\n ): Promise<void> {\n if (!this.fileSystem.fileExists('composer.json')) {\n logger.warn('No composer.json found, skipping composer dependencies')\n return\n }\n\n // Convert npm format (@) to Composer format (:) if needed\n const convertedDeps = dependencies.map(convertNpmToComposerFormat)\n\n const missingDeps =\n await this.filterMissingComposerDependencies(convertedDeps)\n\n if (missingDeps.length === 0) {\n logger.info('All composer dependencies already installed')\n return\n }\n\n try {\n logger.info(`Installing composer dependencies: ${missingDeps.join(', ')}`)\n\n const { stdout, stderr } = await execAsync(\n `composer require ${missingDeps.join(' ')}`,\n {\n cwd: process.cwd(),\n timeout: 300000, // 5 minutes timeout for composer\n },\n )\n\n if (stdout && process.env.NODE_ENV !== 'test') {\n console.log(stdout)\n }\n\n if (stderr) {\n logger.warn(`composer require warnings: ${stderr}`)\n }\n\n logger.success(`Installed ${missingDeps.length} composer dependencies`)\n } catch (error) {\n logger.error(\n `Failed to install composer dependencies: ${(error as Error).message}`,\n )\n throw error\n }\n }\n\n /**\n * Get the appropriate npm install command based on package manager\n * @param packageManager - Package manager to use\n * @param dependencies - Dependencies array\n * @returns Command string\n */\n private getNpmInstallCommand(\n packageManager: PackageManager,\n dependencies: readonly string[],\n ): string {\n switch (packageManager) {\n case 'pnpm':\n return `pnpm add ${dependencies.join(' ')}`\n case 'yarn':\n return `yarn add ${dependencies.join(' ')}`\n case 'bun':\n return `bun add ${dependencies.join(' ')}`\n case 'npm':\n default:\n return `npm install ${dependencies.join(' ')}`\n }\n }\n\n /**\n * Filter out npm dependencies that are already installed\n * @param dependencies - Dependencies to check\n * @returns Array of missing dependencies\n */\n private async filterMissingNpmDependencies(\n dependencies: readonly string[],\n ): Promise<string[]> {\n try {\n const { stdout } = await execAsync('npm list --json --depth=0', {\n cwd: process.cwd(),\n timeout: 30000,\n })\n\n const installed = JSON.parse(stdout) as Record<string, any>\n const installedDeps = Object.keys({\n ...installed.dependencies,\n ...installed.devDependencies,\n })\n\n return dependencies.filter((dep) => {\n const name = dep.split('@')[0]\n return !installedDeps.includes(name)\n })\n } catch {\n // If we can't check, assume all need to be installed\n return dependencies as string[]\n }\n }\n\n /**\n * Filter out composer dependencies that are already installed\n * @param dependencies - Dependencies to check\n * @returns Array of missing dependencies\n */\n private async filterMissingComposerDependencies(\n dependencies: readonly string[],\n ): Promise<string[]> {\n try {\n const { stdout } = await execAsync(\n 'composer show --installed --format=json',\n {\n cwd: process.cwd(),\n timeout: 30000,\n },\n )\n\n const installed = JSON.parse(stdout) as {\n installed: Array<{ name: string }>\n }\n const installedDeps = installed.installed.map((pkg) => pkg.name)\n\n return dependencies.filter((dep) => {\n const name = dep.split(':')[0]\n return !installedDeps.includes(name)\n })\n } catch {\n // If we can't check, assume all need to be installed\n return dependencies as string[]\n }\n }\n}\n","import prompts from 'prompts'\nimport path from 'path'\nimport fsExtra from 'fs-extra'\nimport type {\n AddResult,\n FailedComponent,\n VelarComponentFile,\n VelarComponentMeta,\n} from '@/src/types'\nimport type {\n IConfigManager,\n IFileSystemService,\n IRegistryService,\n} from '@/src/types/interfaces'\nimport { FilesystemService } from '@/src/services/filesystem-service'\nimport { DependencyService } from '@/src/services/dependency-service'\nimport { injectComponentJs } from '@/src/utils/js'\nimport { logger } from '@/src/utils/logger'\nimport {\n createFileBackup,\n deleteFileBackup,\n restoreFileBackup,\n} from '@/src/utils/file-helper'\n\ntype PlannedFile = {\n componentName: string\n filePath: string\n fileType: string\n destPath: string\n content: string\n existedBefore: boolean\n}\n\n/**\n * Service for managing component operations\n */\nexport class ComponentService {\n private readonly fileSystem: IFileSystemService\n private readonly dependencyService: DependencyService\n\n /**\n * Create a new ComponentService instance\n * @param registryService - Service for registry operations\n * @param fileSystem - Optional file system service (creates new one if not provided)\n * @param configManager - Service for configuration management\n */\n constructor(\n private readonly registryService: IRegistryService,\n fileSystem?: IFileSystemService,\n private readonly configManager?: IConfigManager,\n ) {\n this.fileSystem = fileSystem ?? new FilesystemService()\n this.dependencyService = new DependencyService(this.fileSystem)\n if (!this.configManager) {\n throw new Error('ConfigManager is required')\n }\n }\n\n /**\n * Add multiple components to the project\n * @param componentNames - Array of component names to add\n * @returns Promise resolving to result of the operation\n */\n async addComponents(componentNames: readonly string[]): Promise<AddResult> {\n const result: {\n added: string[]\n skipped: string[]\n failed: FailedComponent[]\n } = {\n added: [],\n skipped: [],\n failed: [],\n }\n\n for (const componentName of componentNames) {\n try {\n const componentResult = await this.addComponent(componentName)\n result.added.push(...componentResult.added)\n result.skipped.push(...componentResult.skipped)\n result.failed.push(...componentResult.failed)\n } catch (error) {\n result.failed.push({\n name: componentName,\n error: (error as Error).message,\n })\n }\n }\n\n return result\n }\n\n /**\n * Add a single component to the project\n * @param componentName - Name of the component to add\n * @returns Promise resolving to result of the operation\n * @throws Error if component fetch fails\n */\n private async addComponent(componentName: string): Promise<AddResult> {\n const result: {\n added: string[]\n skipped: string[]\n failed: FailedComponent[]\n } = {\n added: [],\n skipped: [],\n failed: [],\n }\n\n // Fetch component metadata\n const component = await this.registryService.fetchComponent(componentName)\n\n // Resolve dependencies\n const componentsToAdd =\n await this.registryService.resolveDependencies(component)\n\n // Install component dependencies (npm/composer)\n if (component.dependencies) {\n const packageManager = this.configManager!.getPackageManager()\n try {\n await this.dependencyService.installDependencies(\n component.dependencies,\n packageManager,\n )\n } catch (error) {\n logger.warn(\n `Failed to install dependencies for ${componentName}: ${\n (error as Error).message\n }`,\n )\n // Continue with file installation even if dependencies fail\n }\n }\n\n // Get components path\n const componentsPath = this.configManager!.getComponentsPath()\n\n const plannedFiles: PlannedFile[] = []\n\n for (const comp of componentsToAdd) {\n for (const file of comp.files) {\n // Determine destination based on file type\n const dest = this.getDestinationPath(comp, file, componentsPath)\n\n // Check if file exists and handle conflict\n const existedBefore = await this.fileSystem.fileExists(dest)\n if (existedBefore) {\n const action = await this.handleFileConflict(file.path)\n if (action === 'skip') {\n result.skipped.push(`${comp.name}/${file.path}`)\n continue\n } else if (action === 'cancel') {\n logger.error('Cancelled.')\n process.exit(0)\n }\n }\n\n const content = await this.registryService.fetchFile(\n comp.name,\n file.path,\n )\n\n plannedFiles.push({\n componentName: comp.name,\n filePath: file.path,\n fileType: file.type,\n destPath: dest,\n content,\n existedBefore,\n })\n }\n }\n\n if (plannedFiles.length > 0) {\n try {\n await this.applyFileBatch(plannedFiles)\n plannedFiles.forEach((file) =>\n result.added.push(`${file.componentName}/${file.filePath}`),\n )\n\n const jsComponents = new Set(\n plannedFiles\n .filter((file) => file.fileType === 'js')\n .map((file) => file.componentName),\n )\n for (const jsComponent of Array.from(jsComponents)) {\n await this.autoImportJs(jsComponent)\n }\n } catch (error) {\n plannedFiles.forEach((file) =>\n result.failed.push({\n name: `${file.componentName}/${file.filePath}`,\n error: (error as Error).message,\n }),\n )\n }\n }\n\n return result\n }\n\n /**\n * Automatically import component JS into the main JS entry\n * @param componentName - Name of the component\n */\n private async autoImportJs(componentName: string): Promise<void> {\n try {\n const jsEntry = this.configManager?.getJsEntryPath()\n if (!jsEntry || !(await this.fileSystem.fileExists(jsEntry))) {\n return\n }\n\n const importPath = `./ui/${componentName}`\n injectComponentJs(jsEntry, componentName, importPath)\n logger.success(`Auto-imported ${componentName} into ${jsEntry}`)\n } catch (error) {\n logger.warn(\n `Failed to auto-import JS for ${componentName}: ${\n (error as Error).message\n }`,\n )\n }\n }\n\n /**\n * Get the destination path for a component file\n * @param component - Component metadata\n * @param file - File metadata\n * @param componentsPath - Base components path\n * @returns Destination file path\n */\n private getDestinationPath(\n component: VelarComponentMeta,\n file: VelarComponentFile,\n componentsPath: string,\n ): string {\n switch (file.type) {\n case 'blade':\n return path.join(componentsPath, `${component.name}.blade.php`)\n case 'js':\n return path.join('resources/js/ui', `${component.name}.js`)\n case 'css':\n return path.join('resources/css/components', `${component.name}.css`)\n default:\n return path.join(componentsPath, file.path)\n }\n }\n\n /**\n * Handle file conflict by prompting user\n * @param filePath - Path of the conflicting file\n * @returns Promise resolving to user action (\"skip\", \"overwrite\", or \"cancel\")\n */\n private async handleFileConflict(\n filePath: string,\n ): Promise<'skip' | 'overwrite' | 'cancel'> {\n const { action } = await prompts(\n {\n type: 'select',\n name: 'action',\n message: `File \"${filePath}\" already exists. What do you want to do?`,\n choices: [\n { title: 'Skip', value: 'skip' },\n { title: 'Overwrite', value: 'overwrite' },\n { title: 'Cancel', value: 'cancel' },\n ],\n initial: 0,\n },\n {\n onCancel: () => {\n logger.error('Cancelled.')\n process.exit(0)\n },\n },\n )\n\n return action as 'skip' | 'overwrite' | 'cancel'\n }\n\n private async applyFileBatch(plannedFiles: PlannedFile[]): Promise<void> {\n const tempFiles: string[] = []\n const backupTargets: string[] = []\n\n try {\n for (const file of plannedFiles) {\n const tempPath = `${file.destPath}.velar-tmp`\n await this.fileSystem.writeFile(tempPath, file.content)\n tempFiles.push(tempPath)\n }\n\n for (const file of plannedFiles) {\n if (!file.existedBefore) {\n continue\n }\n\n const backupPath = createFileBackup(file.destPath)\n if (!backupPath) {\n throw new Error(`Failed to create backup for ${file.destPath}`)\n }\n backupTargets.push(file.destPath)\n }\n\n for (const file of plannedFiles) {\n const tempPath = `${file.destPath}.velar-tmp`\n await fsExtra.move(tempPath, file.destPath, { overwrite: true })\n }\n\n backupTargets.forEach((filePath) => deleteFileBackup(filePath))\n } catch (error) {\n for (const file of plannedFiles) {\n if (await this.fileSystem.fileExists(file.destPath)) {\n await fsExtra.remove(file.destPath)\n }\n if (file.existedBefore) {\n restoreFileBackup(file.destPath)\n }\n }\n\n for (const tempFile of tempFiles) {\n if (await this.fileSystem.fileExists(tempFile)) {\n await fsExtra.remove(tempFile)\n }\n }\n\n throw error\n }\n }\n}\n","import type { AddResult, RegistryData } from '@/src/types'\nimport type { IRegistryService, IConfigManager } from '../types/interfaces'\nimport { ComponentService } from './component-service'\nimport { FilesystemService } from './filesystem-service'\nimport { logger } from '../utils/logger'\n\n/**\n * Service for handling component addition operations\n */\nexport class AddService {\n private readonly componentService: ComponentService\n\n /**\n * Create a new AddService instance\n * @param registryService - Service for registry operations\n * @param configManager - Service for configuration management\n * @param componentService - Optional component service (creates new one if not provided)\n */\n constructor(\n private readonly registryService: IRegistryService,\n private readonly configManager: IConfigManager,\n componentService?: ComponentService,\n ) {\n // ComponentService will be created if not provided\n // This allows for dependency injection in tests\n this.componentService =\n componentService ??\n new ComponentService(\n registryService,\n new FilesystemService(),\n configManager,\n )\n }\n\n /**\n * Validate that Velar is initialized\n * @throws Error if not initialized\n */\n validateInitialization(): void {\n if (!this.configManager.validate()) {\n throw new Error('Velar is not initialized')\n }\n }\n\n /**\n * Validate that components exist in the registry\n * @param componentNames - Names of components to validate\n * @param registry - Registry data\n * @throws Error if any component is not found\n */\n validateComponents(\n componentNames: readonly string[],\n registry: RegistryData,\n ): void {\n for (const componentName of componentNames) {\n const found = registry.components.find((c) => c.name === componentName)\n if (!found) {\n throw new Error(`Component \"${componentName}\" not found`)\n }\n }\n }\n\n /**\n * Get available components from registry\n * @returns Promise resolving to registry data\n * @throws NetworkError if fetch fails\n */\n async getAvailableComponents(): Promise<RegistryData> {\n return await this.registryService.fetchRegistry()\n }\n\n /**\n * Add components to the project\n * @param componentNames - Names of components to add\n * @returns Promise resolving to result of the operation\n */\n async addComponents(componentNames: readonly string[]): Promise<AddResult> {\n return await this.componentService.addComponents(componentNames)\n }\n\n /**\n * Display the results of adding components\n * @param result - Result of the add operation\n */\n displayResults(result: AddResult): void {\n result.added.forEach((name) => logger.success(`Added ${name}`))\n result.skipped.forEach((name) => logger.warn(`Skipped ${name}`))\n result.failed.forEach(({ name, error }) =>\n logger.error(`Failed to add ${name}: ${error}`),\n )\n }\n\n /**\n * Display next steps after adding components\n * @param result - Result of the add operation\n */\n displayNextSteps(result: AddResult): void {\n if (result.added.length === 0) {\n return\n }\n\n console.log('\\n🎉 Happy coding! Enjoy building beautiful components!')\n\n // Check if JS files were added but not auto-imported\n const jsFiles = result.added.filter((name) => name.endsWith('.js'))\n const hasJsEntry =\n this.configManager.validate() && this.configManager.getJsEntryPath()\n\n if (jsFiles.length > 0 && !hasJsEntry) {\n console.log(' Import JS files in your app.js:')\n jsFiles.forEach((file) => {\n const fileName = file.split('/')[1]\n if (fileName) {\n console.log(` import './ui/${fileName}'`)\n }\n })\n }\n }\n}\n","/**\n * Get the GitHub registry API URL\n * @returns GitHub API URL for the Velar registry\n */\nexport const getGitHubRegistryUrl = (): string => {\n return 'https://api.github.com/repos/velar-ui/registry/contents'\n}\n","/**\n * Base error class for registry-related errors\n */\nexport class RegistryError extends Error {\n /**\n * Create a new RegistryError\n * @param message - Error message\n * @param cause - Original error that caused this error\n */\n constructor(\n message: string,\n public readonly cause?: Error,\n ) {\n super(message)\n this.name = 'RegistryError'\n }\n}\n\n/**\n * Error thrown when a network request fails\n */\nexport class NetworkError extends RegistryError {\n /**\n * Create a new NetworkError\n * @param message - Error message\n * @param cause - Original error that caused this error\n */\n constructor(message: string, cause?: Error) {\n super(message, cause)\n this.name = 'NetworkError'\n }\n}\n\n/**\n * Error thrown when a component is not found in the registry\n */\nexport class ComponentNotFoundError extends RegistryError {\n /**\n * Create a new ComponentNotFoundError\n * @param componentName - Name of the component that was not found\n * @param cause - Original error that caused this error\n */\n constructor(componentName: string, cause?: Error) {\n super(`Component \"${componentName}\" not found`, cause)\n this.name = 'ComponentNotFoundError'\n }\n}\n","import { NetworkError } from '../errors/errors'\nimport type { FetchOptions } from '../types'\n\n/**\n * Default retry options\n */\nconst DEFAULT_RETRY_OPTIONS: Required<FetchOptions> = {\n maxRetries: 3,\n initialDelay: 1000,\n backoffFactor: 2,\n maxDelay: 10000,\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n timeout: 30000,\n headers: {},\n}\n\n/**\n * Sleep utility for retry delays\n * @param ms - Milliseconds to sleep\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Calculate delay for retry attempt with exponential backoff\n * @param attempt - Current attempt number (0-indexed)\n * @param initialDelay - Initial delay in milliseconds\n * @param backoffFactor - Factor to multiply delay by each attempt\n * @param maxDelay - Maximum delay in milliseconds\n * @returns Delay in milliseconds\n */\nfunction calculateDelay(\n attempt: number,\n initialDelay: number,\n backoffFactor: number,\n maxDelay: number,\n): number {\n const delay = initialDelay * Math.pow(backoffFactor, attempt)\n return Math.min(delay, maxDelay)\n}\n\n/**\n * Check if a status code is retryable\n * @param status - HTTP status code\n * @param retryableStatusCodes - List of retryable status codes\n * @returns True if status code is retryable\n */\nfunction isRetryableStatus(\n status: number,\n retryableStatusCodes: readonly number[],\n): boolean {\n return retryableStatusCodes.includes(status)\n}\n\n/**\n * Create a fetch request with timeout\n * @param url - URL to fetch\n * @param options - Fetch options including timeout\n * @returns Promise resolving to Response\n */\nasync function fetchWithTimeout(\n url: string,\n options: FetchOptions,\n): Promise<Response> {\n const { timeout = DEFAULT_RETRY_OPTIONS.timeout, headers = {} } = options\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n try {\n const response = await fetch(url, {\n signal: controller.signal,\n headers: {\n 'User-Agent': 'Velar-CLI',\n ...headers,\n },\n })\n return response\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n throw new NetworkError(\n `Request timeout after ${timeout}ms for ${url}`,\n error,\n )\n }\n throw error\n } finally {\n clearTimeout(timeoutId)\n }\n}\n\n/**\n * HTTP service with retry logic and timeout support\n */\nexport class HttpService {\n /**\n * Fetch a URL with retry logic and timeout\n * @param url - URL to fetch\n * @param options - Fetch options including retry configuration\n * @returns Promise resolving to Response\n * @throws NetworkError if all retries fail\n */\n async fetch(url: string, options: FetchOptions = {}): Promise<Response> {\n const retryOptions = {\n maxRetries: options.maxRetries ?? DEFAULT_RETRY_OPTIONS.maxRetries,\n initialDelay: options.initialDelay ?? DEFAULT_RETRY_OPTIONS.initialDelay,\n backoffFactor:\n options.backoffFactor ?? DEFAULT_RETRY_OPTIONS.backoffFactor,\n maxDelay: options.maxDelay ?? DEFAULT_RETRY_OPTIONS.maxDelay,\n retryableStatusCodes:\n options.retryableStatusCodes ??\n DEFAULT_RETRY_OPTIONS.retryableStatusCodes,\n timeout: options.timeout ?? DEFAULT_RETRY_OPTIONS.timeout,\n headers: options.headers ?? DEFAULT_RETRY_OPTIONS.headers,\n }\n\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt <= retryOptions.maxRetries; attempt++) {\n try {\n const response = await fetchWithTimeout(url, {\n ...options,\n timeout: retryOptions.timeout,\n headers: retryOptions.headers,\n })\n\n // If response is successful or not retryable, return it\n if (\n response.ok ||\n !isRetryableStatus(response.status, retryOptions.retryableStatusCodes)\n ) {\n return response\n }\n console.log('Attempt: ', attempt)\n // If this is the last attempt, throw error\n if (attempt === retryOptions.maxRetries) {\n throw new NetworkError(\n `Request failed after ${retryOptions.maxRetries + 1} attempts: ${response.status} ${response.statusText}`,\n )\n }\n\n // Calculate delay and wait before retry\n const delay = calculateDelay(\n attempt,\n retryOptions.initialDelay,\n retryOptions.backoffFactor,\n retryOptions.maxDelay,\n )\n await sleep(delay)\n } catch (error) {\n lastError = error as Error\n\n // Don't retry on certain errors\n if (\n error instanceof NetworkError &&\n error.message.includes('timeout')\n ) {\n if (attempt === retryOptions.maxRetries) {\n throw error\n }\n const delay = calculateDelay(\n attempt,\n retryOptions.initialDelay,\n retryOptions.backoffFactor,\n retryOptions.maxDelay,\n )\n await sleep(delay)\n continue\n }\n\n // If this is the last attempt, throw error\n if (attempt === retryOptions.maxRetries) {\n if (lastError instanceof NetworkError) {\n throw lastError\n }\n throw new NetworkError(\n `Request failed after ${retryOptions.maxRetries + 1} attempts: ${lastError.message}`,\n lastError,\n )\n }\n\n // Calculate delay and wait before retry\n const delay = calculateDelay(\n attempt,\n retryOptions.initialDelay,\n retryOptions.backoffFactor,\n retryOptions.maxDelay,\n )\n await sleep(delay)\n }\n }\n\n throw new NetworkError(\n `Request failed after ${retryOptions.maxRetries + 1} attempts: ${lastError?.message ?? 'Unknown error'}`,\n lastError ?? undefined,\n )\n }\n\n /**\n * Fetch JSON from a URL with retry logic\n * @param url - URL to fetch\n * @param options - Fetch options\n * @returns Promise resolving to parsed JSON\n * @throws NetworkError if fetch or parsing fails\n */\n async fetchJson<T>(url: string, options?: FetchOptions): Promise<T> {\n const response = await this.fetch(url, options)\n\n if (!response.ok) {\n throw new NetworkError(\n `Failed to fetch JSON from ${url}: ${response.status} ${response.statusText}`,\n )\n }\n\n try {\n return (await response.json()) as T\n } catch (error) {\n throw new NetworkError(\n `Failed to parse JSON from ${url}: ${(error as Error).message}`,\n error as Error,\n )\n }\n }\n\n /**\n * Fetch text from a URL with retry logic\n * @param url - URL to fetch\n * @param options - Fetch options\n * @returns Promise resolving to text content\n * @throws NetworkError if fetch fails\n */\n async fetchText(url: string, options?: FetchOptions): Promise<string> {\n const response = await this.fetch(url, options)\n\n if (!response.ok) {\n throw new NetworkError(\n `Failed to fetch text from ${url}: ${response.status} ${response.statusText}`,\n )\n }\n\n try {\n return await response.text()\n } catch (error) {\n throw new NetworkError(\n `Failed to read text from ${url}: ${(error as Error).message}`,\n error as Error,\n )\n }\n }\n}\n","import { getGitHubRegistryUrl } from './environment'\nimport { NetworkError, ComponentNotFoundError } from '../errors/errors'\nimport { HttpService } from '../services/http-service'\nimport type { GitHubFile, RegistryData, VelarComponentMeta } from '../types'\n\n/**\n * HTTP service instance for making requests\n */\nconst httpService = new HttpService()\n\n/**\n * Fetch a meta.json from a given URL and return as VelarComponentMeta\n * @param metaUrl - URL to fetch meta.json from\n * @returns Promise resolving to VelarComponentMeta\n * @throws NetworkError if fetch or parsing fails\n */\nexport async function fetchComponentMetaFromUrl(\n metaUrl: string,\n): Promise<VelarComponentMeta> {\n try {\n const raw = await httpService.fetchText(metaUrl)\n\n // Try to parse as VelarComponentMeta directly (raw JSON)\n try {\n const meta = JSON.parse(raw) as VelarComponentMeta\n if (meta && Array.isArray(meta.files)) {\n return meta\n }\n } catch {\n // Fallback to next logic\n }\n\n // If not, try as GitHubFile (API response)\n try {\n const file = JSON.parse(raw) as GitHubFile\n if (!file.download_url) {\n throw new NetworkError('GitHubFile missing download_url')\n }\n const meta = await httpService.fetchJson<VelarComponentMeta>(\n file.download_url,\n )\n if (meta && Array.isArray(meta.files)) {\n return meta\n }\n throw new NetworkError('Invalid meta.json structure')\n } catch (e) {\n if (e instanceof NetworkError) {\n throw e\n }\n throw new NetworkError(\n `Failed to parse meta.json from ${metaUrl}: ${(e as Error).message}`,\n e as Error,\n )\n }\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error\n }\n throw new NetworkError(\n `Failed to fetch component meta from ${metaUrl}: ${(error as Error).message}`,\n error as Error,\n )\n }\n}\n\n/**\n * Fetch the GitHub registry data\n * @param branch - Git branch to fetch from (default: \"main\")\n * @returns Promise resolving to RegistryData\n * @throws NetworkError if fetch fails\n */\nexport async function fetchGitHubRegistry(\n branch: string = 'main',\n): Promise<RegistryData> {\n try {\n // First try to get registry.json from the root\n const registryUrl = `https://raw.githubusercontent.com/velar-ui/registry/${branch}/registry.json`\n try {\n const registryData =\n await httpService.fetchJson<RegistryData>(registryUrl)\n return registryData\n } catch {\n // Fallback to listing components directory\n }\n\n // Fallback to listing components directory\n const files = await httpService.fetchJson<GitHubFile[]>(\n `${getGitHubRegistryUrl()}/components`,\n )\n\n const components: VelarComponentMeta[] = []\n\n for (const file of files) {\n if (file.type === 'dir') {\n try {\n // Try to get meta.json for each component\n const meta = await httpService.fetchJson<VelarComponentMeta>(\n `${getGitHubRegistryUrl()}/components/${file.name}/meta.json`,\n )\n components.push({\n ...meta,\n name: file.name,\n path: file.path,\n })\n } catch {\n // Skip failed components but continue with others\n components.push({\n name: file.name,\n path: file.path,\n files: [],\n })\n }\n }\n }\n\n return { components }\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error\n }\n throw new NetworkError(\n `Failed to fetch remote registry: ${(error as Error).message}`,\n error as Error,\n )\n }\n}\n\n/**\n * Fetch component metadata from GitHub\n * @param componentName - Name of the component to fetch\n * @returns Promise resolving to GitHubFile\n * @throws ComponentNotFoundError if component doesn't exist\n * @throws NetworkError if fetch fails\n */\nexport async function fetchComponent(\n componentName: string,\n): Promise<GitHubFile> {\n try {\n const metaUrl = `${getGitHubRegistryUrl()}/components/${componentName}/meta.json`\n const response = await httpService.fetch(metaUrl)\n\n if (response.status === 404) {\n throw new ComponentNotFoundError(componentName)\n }\n\n if (!response.ok) {\n throw new NetworkError(\n `Component meta not found: ${response.status} ${response.statusText}`,\n )\n }\n\n return await httpService.fetchJson<GitHubFile>(metaUrl)\n } catch (error) {\n if (\n error instanceof ComponentNotFoundError ||\n error instanceof NetworkError\n ) {\n throw error\n }\n throw new NetworkError(\n `Failed to fetch component meta for \"${componentName}\": ${(error as Error).message}`,\n error as Error,\n )\n }\n}\n\n/**\n * Fetch a component file content from GitHub\n * @param componentName - Name of the component\n * @param filePath - Path to the file within the component directory\n * @returns Promise resolving to file content as string\n * @throws ComponentNotFoundError if component or file doesn't exist\n * @throws NetworkError if fetch fails\n */\nexport async function fetchComponentFile(\n componentName: string,\n filePath: string,\n): Promise<string> {\n try {\n const fileUrl = `${getGitHubRegistryUrl()}/components/${componentName}/${filePath}`\n const response = await httpService.fetch(fileUrl)\n\n if (response.status === 404) {\n throw new ComponentNotFoundError(componentName)\n }\n\n if (!response.ok) {\n throw new NetworkError(\n `File not found: ${response.status} ${response.statusText}`,\n )\n }\n\n const file = await httpService.fetchJson<GitHubFile>(fileUrl)\n\n if (!file.download_url) {\n throw new NetworkError('File has no download URL')\n }\n\n return await httpService.fetchText(file.download_url)\n } catch (error) {\n if (\n error instanceof ComponentNotFoundError ||\n error instanceof NetworkError\n ) {\n throw error\n }\n throw new NetworkError(\n `Failed to fetch file \"${filePath}\" for component \"${componentName}\": ${(error as Error).message}`,\n error as Error,\n )\n }\n}\n","import type { GitHubFile, RegistryData, VelarComponentMeta } from '../types'\nimport type { IRegistryService } from '../types/interfaces'\nimport {\n fetchComponent,\n fetchComponentFile,\n fetchGitHubRegistry,\n} from '../utils/remote-registry'\n\nimport { HttpService } from './http-service'\n\nimport { spinner } from '../utils/spinner'\n\n/**\n * Service for interacting with the Velar component registry\n */\nexport class RegistryService implements IRegistryService {\n private readonly httpService: HttpService\n\n /**\n * Create a new RegistryService instance\n * @param httpService - Optional HTTP service instance (creates new one if not provided)\n */\n constructor(httpService?: HttpService) {\n this.httpService = httpService ?? new HttpService()\n }\n\n /**\n * Fetch the complete registry data\n * @returns Promise resolving to registry data\n * @throws NetworkError if fetch fails\n */\n async fetchRegistry(): Promise<RegistryData> {\n return await spinner.withTask(\n 'Fetching registry...',\n () => fetchGitHubRegistry(),\n undefined,\n 'Failed to fetch registry',\n )\n }\n\n /**\n * Fetch metadata for a specific component\n * @param name - Component name\n * @returns Promise resolving to component metadata\n * @throws ComponentNotFoundError if component doesn't exist\n * @throws NetworkError if fetch fails\n */\n async fetchComponent(name: string): Promise<VelarComponentMeta> {\n const file = await spinner.withTask(\n `Fetching component \"${name}\" metadata...`,\n () => fetchComponent(name),\n undefined,\n `Failed to fetch component \"${name}\"`,\n )\n return await this.parseComponentMeta(file)\n }\n\n /**\n * Fetch file content for a component\n * @param componentUrl - Component URL or name\n * @param path - File path within component\n * @returns Promise resolving to file content\n * @throws ComponentNotFoundError if component or file doesn't exist\n * @throws NetworkError if fetch fails\n */\n async fetchFile(componentUrl: string, path: string): Promise<string> {\n const componentName = componentUrl.split('/').pop() || componentUrl\n return await spinner.withTask(\n `Downloading ${path}...`,\n () => fetchComponentFile(componentName, path),\n undefined,\n `Failed to fetch file \"${path}\"`,\n )\n }\n\n /**\n * Resolve component dependencies\n * @param component - Component metadata\n * @returns Promise resolving to array of components including dependencies\n */\n async resolveDependencies(\n component: VelarComponentMeta,\n ): Promise<readonly VelarComponentMeta[]> {\n const visited = new Set<string>()\n const resolved: VelarComponentMeta[] = []\n\n const resolve = async (comp: VelarComponentMeta) => {\n if (visited.has(comp.name)) return\n visited.add(comp.name)\n resolved.push(comp)\n\n // Component dependencies would be resolved here if they exist\n // For now, just add the component itself\n }\n\n await resolve(component)\n return resolved\n }\n\n /**\n * Parse component metadata from GitHub file\n * @param file - GitHub file metadata\n * @returns Promise resolving to component metadata\n * @throws NetworkError if download or parsing fails\n */\n private async parseComponentMeta(\n file: GitHubFile,\n ): Promise<VelarComponentMeta> {\n if (!file.download_url) {\n throw new Error('GitHub file has no download URL')\n }\n\n try {\n const raw = await this.httpService.fetchText(file.download_url)\n return JSON.parse(raw) as VelarComponentMeta\n } catch (error) {\n throw new Error(\n `Failed to parse component meta: ${(error as Error).message}`,\n )\n }\n }\n}\n","import { ConfigManager } from '@/src/config/config-manager'\nimport { AddService } from '@/src/services/add-service'\nimport { RegistryService } from '@/src/services/registry-service'\nimport { logger } from '@/src/utils/logger'\nimport { z } from 'zod'\nimport prompts from 'prompts'\n\nexport type AddOptions = {\n components?: string[]\n yes: boolean\n overwrite: boolean\n cwd: string\n all: boolean\n path?: string\n silent: boolean\n srcDir?: boolean\n cssVariables?: boolean\n}\n\nasync function promptForRegistryComponents(\n options: AddOptions,\n availableComponents: readonly string[],\n): Promise<string[]> {\n if (options.all) {\n return [...availableComponents]\n }\n\n if (options.components?.length) {\n return options.components\n }\n\n logger.info('Use arrow keys and space to select, then press enter.')\n\n const { components } = await prompts({\n type: 'multiselect',\n name: 'components',\n message: 'Which components would you like to add?',\n hint: 'Space to select. A to toggle all. Enter to submit.',\n instructions: false,\n choices: availableComponents.map((name) => ({\n title: name,\n value: name,\n selected: options.all ? true : options.components?.includes(name),\n })),\n })\n\n if (!components?.length) {\n logger.warn('No components selected. Exiting.')\n logger.info('')\n process.exit(1)\n }\n\n const result = z.array(z.string()).safeParse(components)\n if (!result.success) {\n logger.error('Something went wrong. Please try again.')\n process.exit(1)\n }\n\n return result.data\n}\n\nexport async function addComponents(options: AddOptions): Promise<void> {\n const configManager = new ConfigManager()\n await configManager.load()\n\n const registryService = new RegistryService()\n const addService = new AddService(registryService, configManager)\n\n try {\n addService.validateInitialization()\n } catch {\n logger.error('Velar is not initialized')\n logger.log('Run velar init first')\n process.exit(1)\n }\n\n const registry = await addService.getAvailableComponents()\n\n const available = registry.components\n .map((component: { name: string }) => component.name)\n .sort((a: string, b: string) => a.localeCompare(b))\n const componentNames = await promptForRegistryComponents(options, available)\n\n try {\n addService.validateComponents(componentNames, registry)\n } catch (err) {\n logger.error((err as Error).message)\n logger.log('Run velar list to see available components')\n process.exit(1)\n }\n\n const result = await addService.addComponents(componentNames)\n addService.displayResults(result)\n addService.displayNextSteps(result)\n}\n","#!/usr/bin/env node\nimport { ErrorHandler } from '@/src/errors/ErrorHandler'\nimport { addComponents } from '@/src/utils/add-components'\nimport { Command } from 'commander'\nimport { z } from 'zod'\nimport path from 'path'\n\nexport const addOptionsSchema = z.object({\n components: z.array(z.string()).optional(),\n yes: z.boolean(),\n overwrite: z.boolean(),\n cwd: z.string(),\n all: z.boolean(),\n path: z.string().optional(),\n silent: z.boolean(),\n srcDir: z.boolean().optional(),\n cssVariables: z.boolean().optional(),\n})\n\n/**\n * Register the 'add' command with the CLI program\n * @param program - Commander program instance\n */\nexport const add = new Command()\n .name('add')\n .argument('[components...]', 'Names of components to add')\n .option('-y, --yes', 'skip confirmation prompt.', false)\n .option('-o, --overwrite', 'overwrite existing files.', false)\n .option(\n '-c, --cwd <cwd>',\n 'the working directory. defaults to the current directory.',\n process.cwd(),\n )\n .option('-a, --all', 'add all available components', false)\n .option('-p, --path <path>', 'the path to add the component to.')\n .option('-s, --silent', 'mute output.', false)\n .option(\n '--src-dir',\n 'use the src directory when creating a new project.',\n false,\n )\n .option(\n '--no-src-dir',\n 'do not use the src directory when creating a new project.',\n )\n .option('--css-variables', 'use CSS variables for theming.', true)\n .option('--no-css-variables', 'do not use CSS variables for theming.')\n .description('Add one or more UI components to your Laravel project')\n .action(async (components, opts) => {\n const errorHandler = new ErrorHandler()\n\n try {\n const rawOptions = {\n components,\n cwd: path.resolve(opts.cwd),\n ...opts,\n cssVariables: opts.cssVariables ?? true,\n }\n\n const options = addOptionsSchema.parse(rawOptions)\n await addComponents(options)\n } catch (error) {\n errorHandler.handle(error as Error, 'add command')\n process.exit(1)\n }\n })\n","import chalk from 'chalk'\nimport Table from 'cli-table3'\nimport type { VelarComponentMeta } from '@/src/types'\nimport { RegistryService } from '@/src/services/registry-service'\nimport { logger } from '@/src/utils/logger'\n\nexport type ListOptions = {\n query?: string\n limit?: number\n offset?: number\n json: boolean\n}\n\nfunction filterComponents(\n components: readonly VelarComponentMeta[],\n query?: string,\n): VelarComponentMeta[] {\n if (!query) {\n return [...components]\n }\n\n const normalized = query.toLowerCase()\n return components.filter((component) => {\n const nameMatch = component.name.toLowerCase().includes(normalized)\n const descriptionMatch = component.description\n ? component.description.toLowerCase().includes(normalized)\n : false\n const categoryMatch = component.categories\n ? component.categories.some((category) =>\n category.toLowerCase().includes(normalized),\n )\n : false\n\n return nameMatch || descriptionMatch || categoryMatch\n })\n}\n\nfunction sliceComponents(\n components: VelarComponentMeta[],\n offset?: number,\n limit?: number,\n): VelarComponentMeta[] {\n const start = Math.max(0, offset ?? 0)\n if (limit === undefined) {\n return components.slice(start)\n }\n return components.slice(start, start + Math.max(0, limit))\n}\n\nexport async function listComponents(options: ListOptions): Promise<void> {\n const registryService = new RegistryService()\n const registry = await registryService.fetchRegistry()\n\n const sorted = [...registry.components].sort((a, b) =>\n a.name.localeCompare(b.name),\n )\n\n const filtered = filterComponents(sorted, options.query)\n const sliced = sliceComponents(filtered, options.offset, options.limit)\n\n if (options.json) {\n console.log(\n JSON.stringify(\n {\n total: filtered.length,\n count: sliced.length,\n offset: options.offset ?? 0,\n limit: options.limit ?? null,\n components: sliced,\n },\n null,\n 2,\n ),\n )\n return\n }\n\n if (sliced.length === 0) {\n logger.warn('No components found.')\n return\n }\n\n console.log(chalk.bold('\\nAvailable components:'))\n console.log('')\n\n const table = new Table({\n head: [\n chalk.bold('Component'),\n chalk.bold('Description'),\n chalk.bold('Categories'),\n ],\n colWidths: [24, 50, 24],\n wordWrap: true,\n style: {\n head: [],\n border: [],\n },\n })\n\n for (const component of sliced) {\n table.push([\n chalk.cyan(component.name),\n chalk.white(component.description || 'No description'),\n chalk.gray(component.categories?.join(', ') || '-'),\n ])\n }\n\n console.log(table.toString())\n console.log('')\n logger.info(`Run ${chalk.green('velar add <component>')} to add one.`)\n}\n","import { Command } from 'commander'\nimport { z } from 'zod'\nimport path from 'path'\nimport { listComponents } from '@/src/utils/list-components'\nimport { ErrorHandler } from '@/src/errors/ErrorHandler'\n\nconst listOptionsSchema = z.object({\n cwd: z.string(),\n query: z.string().optional(),\n limit: z.number().optional(),\n offset: z.number().optional(),\n json: z.boolean(),\n})\n\nexport const list = new Command()\n .name('list')\n .alias('search')\n .description('List or search components from the registry')\n .option(\n '-c, --cwd <cwd>',\n 'the working directory. defaults to the current directory.',\n process.cwd(),\n )\n .option('-q, --query <query>', 'query string')\n .option(\n '-l, --limit <number>',\n 'maximum number of items to display',\n undefined,\n )\n .option('-o, --offset <number>', 'number of items to skip', undefined)\n .option('--json', 'output JSON', false)\n .action(async (opts) => {\n const errorHandler = new ErrorHandler()\n\n try {\n const options = listOptionsSchema.parse({\n cwd: path.resolve(opts.cwd),\n query: opts.query,\n limit: opts.limit ? Number.parseInt(opts.limit, 10) : undefined,\n offset: opts.offset ? Number.parseInt(opts.offset, 10) : undefined,\n json: Boolean(opts.json),\n })\n\n process.chdir(options.cwd)\n await listComponents(options)\n } catch (error) {\n errorHandler.handle(error as Error, 'list command')\n process.exit(1)\n }\n })\n","import chalk from 'chalk'\nimport { Command } from 'commander'\nimport { init } from '@/src/commands/init'\nimport { add } from '@/src/commands/add'\nimport { list } from '@/src/commands/list'\n\nimport packageJson from '../package.json'\n/**\n * Display a nice introduction banner\n */\nfunction displayIntro(): void {\n console.log('')\n console.log(chalk.bold.cyan(` ▼ VELAR CLI v${packageJson.version}`))\n console.log(chalk.gray(' Tailwind CSS v4+ components for Laravel'))\n console.log('')\n}\n\n/**\n * Velar CLI program entry point\n */\nconst program = new Command()\nprogram\n .name('velar')\n .description('Velar CLI: Copy UI components into your Laravel project')\n .version(\n packageJson.version || '1.0.0',\n '-v, --version',\n 'display the version number',\n )\n .hook('preAction', () => {\n displayIntro()\n })\n\nprogram.addCommand(add).addCommand(init).addCommand(list)\n\nprogram.parse(process.argv)\n"]}
File without changes
File without changes
@@ -0,0 +1,29 @@
1
+ :root {
2
+ --radius: 0.625rem;
3
+
4
+ --background: oklch(1 0 0);
5
+ --foreground: oklch(0.145 0 0);
6
+
7
+ --primary: oklch(0.205 0 0);
8
+ --primary-foreground: oklch(0.985 0 0);
9
+
10
+ --secondary: oklch(0.97 0 0);
11
+ --secondary-foreground: oklch(0.205 0 0);
12
+
13
+ --border: oklch(0.922 0 0);
14
+ --ring: oklch(0.708 0 0);
15
+ }
16
+
17
+ .dark {
18
+ --background: oklch(0.145 0 0);
19
+ --foreground: oklch(0.985 0 0);
20
+
21
+ --primary: oklch(0.922 0 0);
22
+ --primary-foreground: oklch(0.205 0 0);
23
+
24
+ --secondary: oklch(0.269 0 0);
25
+ --secondary-foreground: oklch(0.985 0 0);
26
+
27
+ --border: oklch(1 0 0 / 10%);
28
+ --ring: oklch(0.439 0 0);
29
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "velyx",
3
+ "version": "1.0.0",
4
+ "description": "CLI to add composable UI components to Laravel projects",
5
+ "author": "",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "engines": {
9
+ "node": ">=20"
10
+ },
11
+ "bin": {
12
+ "velyx": "./dist/index.js"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "keywords": [
18
+ "laravel",
19
+ "cli",
20
+ "ui",
21
+ "blade",
22
+ "tailwind",
23
+ "alpine"
24
+ ],
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/velyx-labs/cli.git"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "dependencies": {
33
+ "@clack/prompts": "^0.11.0",
34
+ "chalk": "^5.6.2",
35
+ "changeset": "^0.2.6",
36
+ "cli-table3": "^0.6.5",
37
+ "commander": "^14.0.2",
38
+ "fs-extra": "^11.3.3",
39
+ "kleur": "^4.1.5",
40
+ "log-symbols": "^7.0.1",
41
+ "ora": "^9.1.0",
42
+ "prompts": "^2.4.2",
43
+ "vite-tsconfig-paths": "^6.0.5",
44
+ "zod": "^3.24.1",
45
+ "zod-to-json-schema": "^3.24.6"
46
+ },
47
+ "devDependencies": {
48
+ "@eslint/js": "^9.39.2",
49
+ "@eslint/json": "^0.14.0",
50
+ "@eslint/markdown": "^7.5.1",
51
+ "@types/fs-extra": "^11.0.4",
52
+ "@types/node": "^25.0.9",
53
+ "@types/prompts": "^2.4.9",
54
+ "@vitest/coverage-v8": "^4.0.18",
55
+ "eslint": "^9.39.2",
56
+ "globals": "^17.0.0",
57
+ "jiti": "^2.6.1",
58
+ "prettier": "3.8.0",
59
+ "rimraf": "^6.0.1",
60
+ "tsc-alias": "^1.8.16",
61
+ "tsup": "^8.5.0",
62
+ "typescript": "^5.9.3",
63
+ "typescript-eslint": "^8.53.0",
64
+ "vitest": "^4.0.18"
65
+ },
66
+ "scripts": {
67
+ "build": "tsup",
68
+ "check:ci": "pnpm run lint && pnpm run typecheck",
69
+ "clean": "rimraf dist",
70
+ "dev": "tsup --watch",
71
+ "check": "pnpm run format:write && eslint --fix",
72
+ "format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache",
73
+ "format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache",
74
+ "lint": "eslint",
75
+ "pub:beta": "pnpm build && pnpm publish --no-git-checks --access public --tag beta",
76
+ "pub:next": "pnpm build && pnpm publish --no-git-checks --access public --tag next",
77
+ "pub:release": "pnpm build && pnpm publish --access public",
78
+ "release": "changeset version",
79
+ "start": "node dist/index.js",
80
+ "test": "vitest run",
81
+ "test:coverage": "vitest run --coverage",
82
+ "test:watch": "vitest",
83
+ "typecheck": "tsc --noEmit"
84
+ }
85
+ }