untitledui 0.1.61 → 0.1.63

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/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ The MIT License below applies to the Untitled UI CLI tool in this repository
2
+ ONLY. The components, page templates, Storybook files, and other assets that the
3
+ CLI downloads from Untitled UI are proprietary, are licensed separately under
4
+ the Untitled UI commercial license, and are NOT covered by the MIT license
5
+ below.
6
+
7
+ ----------------------------------------------------------------------
8
+
9
+ MIT License
10
+
11
+ Copyright (c) 2026 Untitled UI
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
package/README.md CHANGED
@@ -1,9 +1,12 @@
1
- [![npm version](https://img.shields.io/npm/v/untitledui.svg)](https://www.npmjs.com/package/untitledui)
2
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
3
-
4
1
  # Untitled UI CLI
5
2
 
6
- The official CLI for [Untitled UI React](https://www.untitledui.com/react) quickly scaffold projects, add components, and install page examples with an interactive interface.
3
+ The official command-line tool for [Untitled UI React](https://www.untitledui.com/react)—scaffold projects, add components and page examples, search the library, and upgrade your project, all from your terminal. Just run, pick, and build.
4
+
5
+ [Learn more](https://www.untitledui.com/react) • [Documentation](https://www.untitledui.com/react/docs/cli) • [Figma](https://www.untitledui.com/figma) • [FAQs](https://www.untitledui.com/faqs)
6
+
7
+ ## Documentation
8
+
9
+ Check out our documentation here → [untitledui.com/react/docs/cli](https://www.untitledui.com/react/docs/cli)
7
10
 
8
11
  ## Installation
9
12
 
@@ -19,7 +22,9 @@ Or install globally:
19
22
  npm install -g untitledui
20
23
  ```
21
24
 
22
- ## Quick Start
25
+ Requires [Node.js](https://nodejs.org/en) 18 or later.
26
+
27
+ ## Quick start
23
28
 
24
29
  ```bash
25
30
  # Create a new project
@@ -31,6 +36,9 @@ npx untitledui@latest add button toggle avatar
31
36
  # Add a page example
32
37
  npx untitledui@latest example dashboards-01/05
33
38
 
39
+ # Search the library in natural language
40
+ npx untitledui@latest search "dark pricing table"
41
+
34
42
  # Authenticate for PRO access
35
43
  npx untitledui@latest login
36
44
  ```
@@ -39,72 +47,77 @@ npx untitledui@latest login
39
47
 
40
48
  ### `init`
41
49
 
42
- Initialize a new project or configure an existing one with Untitled UI.
50
+ Initialize a new project or configure Untitled UI in an existing one.
43
51
 
44
52
  ```bash
45
53
  npx untitledui@latest init [directory] [options]
46
54
  ```
47
55
 
48
- | Option | Description |
49
- |---|---|
50
- | `--vite` | Initialize a Vite project |
51
- | `--nextjs` | Initialize a Next.js project |
52
- | `-o, --overwrite` | Overwrite existing files |
53
- | `--colors-list` | Show available brand colors |
54
- | `-c, --color <name>` | Set the brand color |
55
-
56
- **Examples:**
57
-
58
- ```bash
59
- npx untitledui@latest init my-app --nextjs
60
- npx untitledui@latest init my-app --vite --color blue
61
- ```
56
+ | Option | Description |
57
+ | --------------------- | ----------------------------------------------------- |
58
+ | `--vite` | Initialize a Vite project |
59
+ | `--nextjs` | Initialize a Next.js project |
60
+ | `-o, --overwrite` | Overwrite existing files |
61
+ | `--colors-list` | Show the available brand colors |
62
+ | `-c, --color <name>` | Set the brand color |
63
+ | `-y, --yes` | Non-interactive mode — use defaults (for AI/CI) |
64
+ | `--license <key>` | API key for PRO access (alternative to stored config) |
65
+ | `--lib-version <ver>` | Component library version (`7` or `8`) |
62
66
 
63
67
  ### `add`
64
68
 
65
- Add components to your project.
69
+ Add one or more components to your project.
66
70
 
67
71
  ```bash
68
72
  npx untitledui@latest add [components...] [options]
69
73
  ```
70
74
 
71
- | Option | Description |
72
- |---|---|
73
- | `-a, --all` | Add all available components |
74
- | `-o, --overwrite` | Overwrite existing files |
75
- | `-p, --path <path>` | Custom components directory |
76
- | `-d, --dir <directory>` | Project directory |
77
- | `-t, --type <type>` | Component type (`base`, `marketing`, `shared-assets`, `application`, `foundations`) |
78
-
79
- **Examples:**
80
-
81
- ```bash
82
- npx untitledui@latest add button
83
- npx untitledui@latest add button toggle avatar
84
- npx untitledui@latest add --all --type marketing
85
- ```
75
+ | Option | Description |
76
+ | -------------------------- | ----------------------------------------------------------------------------------- |
77
+ | `-a, --all` | Add all available components |
78
+ | `-o, --overwrite` | Overwrite existing files |
79
+ | `-p, --path <path>` | Path to add the component to |
80
+ | `-d, --dir <directory>` | Directory where the project is located |
81
+ | `-t, --type <type>` | Component type (`base`, `marketing`, `shared-assets`, `application`, `foundations`) |
82
+ | `--include-all-components` | Include all base components without prompting |
83
+ | `-y, --yes` | Non-interactive mode — use defaults (for AI/CI) |
84
+ | `--license <key>` | API key for PRO access (alternative to stored config) |
85
+ | `--lib-version <ver>` | Component library version (`7` or `8`) |
86
86
 
87
87
  ### `example`
88
88
 
89
- Add a page example to your project.
89
+ Add a full page example to your project.
90
90
 
91
91
  ```bash
92
92
  npx untitledui@latest example [example] [options]
93
93
  ```
94
94
 
95
- | Option | Description |
96
- |---|---|
97
- | `-o, --overwrite` | Overwrite existing files |
98
- | `-p, --path <path>` | Custom components directory |
99
- | `-e, --example-path <path>` | Custom example file directory |
95
+ | Option | Description |
96
+ | --------------------------- | --------------------------------------------------------- |
97
+ | `-o, --overwrite` | Overwrite existing files |
98
+ | `-p, --path <path>` | Path to add the components to |
99
+ | `-e, --example-path <path>` | Path to add the example file to |
100
+ | `--include-all-components` | Include all components from the example without prompting |
101
+ | `-y, --yes` | Non-interactive mode — use defaults (for AI/CI) |
102
+ | `-c, --color <name>` | Brand color (passed through to `init`) |
103
+ | `--license <key>` | API key for PRO access (alternative to stored config) |
104
+ | `--lib-version <ver>` | Component library version (`7` or `8`) |
100
105
 
101
- **Examples:**
106
+ ### `search`
107
+
108
+ Search components, templates, and icons using natural language.
102
109
 
103
110
  ```bash
104
- npx untitledui@latest example application
105
- npx untitledui@latest example dashboards-01/05
111
+ npx untitledui@latest search <query...> [options]
106
112
  ```
107
113
 
114
+ | Option | Description |
115
+ | ---------------------- | ------------------------------------------------------------------------- |
116
+ | `-t, --type <type>` | Filter by type: `components`, `templates`, `icons`, `all` (default `all`) |
117
+ | `-l, --limit <number>` | Max results per category (default `5`) |
118
+ | `-k, --key <key>` | API key for PRO access |
119
+ | `--lib-version <ver>` | Component library version (`7` or `8`) |
120
+
108
121
  ### `login`
109
122
 
110
123
  Authenticate with Untitled UI to access PRO components.
@@ -115,6 +128,37 @@ npx untitledui@latest login
115
128
 
116
129
  Opens a browser window for authentication. Your credentials are stored locally at `~/.untitledui/config.json`.
117
130
 
131
+ ### `migrate`
132
+
133
+ Migrate components for RTL (right-to-left) support.
134
+
135
+ ```bash
136
+ npx untitledui@latest migrate [path] [options]
137
+ ```
138
+
139
+ | Option | Description |
140
+ | -------------- | ------------------------------------- |
141
+ | `--dry-run` | Preview changes without writing files |
142
+ | `--skip-icons` | Skip directional icon swapping |
143
+ | `-y, --yes` | Skip prompts and use defaults |
144
+
145
+ ### `upgrade`
146
+
147
+ Upgrade your project to the latest version of Untitled UI.
148
+
149
+ ```bash
150
+ npx untitledui@latest upgrade [options]
151
+ ```
152
+
153
+ | Option | Description |
154
+ | --------------- | ------------------------------------- |
155
+ | `--dry-run` | Preview changes without writing files |
156
+ | `--skip-theme` | Skip `theme.css` replacement |
157
+ | `--skip-deps` | Skip dependency updates |
158
+ | `--skip-config` | Skip config file updates |
159
+ | `--path <dir>` | Directory to scan for source files |
160
+ | `-y, --yes` | Skip prompts and use defaults |
161
+
118
162
  ## Configuration
119
163
 
120
164
  The CLI detects your project setup automatically:
@@ -125,14 +169,33 @@ The CLI detects your project setup automatically:
125
169
  - **Tailwind CSS**: v4+ with automatic dependency installation
126
170
  - **Custom paths**: Supports `components.json` for alias configuration
127
171
 
128
- ## Documentation
172
+ ## Resources
129
173
 
130
- Full documentation is available at [untitledui.com/react/docs](https://www.untitledui.com/react/docs/introduction).
174
+ Untitled UI React is built on top of [Untitled UI Figma](https://www.untitledui.com/figma), the world's largest and most popular Figma UI kit and design system. Explore more:
131
175
 
132
- ## Bug Reports
176
+ **[Untitled UI Figma:](https://www.untitledui.com/figma)** The world's largest Figma UI kit and design system.
177
+ <br/>
178
+ **[Untitled UI Icons:](https://www.untitledui.com/icons)** A clean, consistent, and neutral icon library crafted specifically for modern UI design.
179
+ <br/>
180
+ **[Untitled UI file icons:](https://www.untitledui.com/resources/file-icons)** Free file format icons, designed specifically for modern web and UI design.
181
+ <br/>
182
+ **[Untitled UI flag icons:](https://www.untitledui.com/resources/flag-icons)** Free country flag icons, designed specifically for modern web and UI design.
183
+ <br/>
184
+ **[Untitled UI avatars:](https://www.untitledui.com/resources/avatars)** Free placeholder user avatars and profile pictures to use in your projects.
185
+ <br/>
186
+ **[Untitled UI logos:](https://www.untitledui.com/resources/logos)** Free fictional company logos to use in your projects.
133
187
 
134
- Found a bug? Please report it on our [issue tracker](https://github.com/untitleduico/react/issues).
188
+ ## Bug reports
189
+
190
+ Found a bug? Please report it on our [issue tracker](https://github.com/untitleduico/cli/issues).
135
191
 
136
192
  ## License
137
193
 
138
- MIT © [Untitled UI](https://www.untitledui.com/react)
194
+ The Untitled UI CLI (this tool) is licensed under the MIT license, which means you can use it for free in unlimited commercial projects.
195
+
196
+ > [!NOTE]
197
+ > The MIT license covers the CLI tool only. The components, page examples, Storybook files, and other assets the CLI downloads are subject to a separate [license agreement](https://www.untitledui.com/license). [Untitled UI React PRO](https://www.untitledui.com/react) includes hundreds more advanced UI components and page examples.
198
+
199
+ [Untitled UI license agreement →](https://www.untitledui.com/license)
200
+
201
+ [Frequently asked questions →](https://www.untitledui.com/faqs)
@@ -735,7 +735,7 @@
735
735
  --color-bg-primary-solid: var(--color-bg-secondary);
736
736
  --color-bg-error-solid_hover: var(--color-red-500);
737
737
 
738
- --color-app-store-badg-border: var(--color-white);
738
+ --color-app-store-badge-border: var(--color-white);
739
739
  --color-avatar-styles-bg-neutral: 224 224 224 1;
740
740
  --color-featured-icon-light-fg-brand: var(--color-brand-200);
741
741
  --color-featured-icon-light-fg-error: var(--color-red-200);
package/dist/index.mjs CHANGED
@@ -1,21 +1,21 @@
1
1
  #!/usr/bin/env node
2
- import{Command as i3}from"commander";import O from"chalk";import{Command as r1}from"commander";import*as s from"fs";import w$ from"ora";import*as m from"path";import V$ from"prompts";import{Project as i1}from"ts-morph";import*as Q$ from"fs";import*as e$ from"path";import w1 from"os";var I0=e$.join(w1.homedir(),".untitledui"),$0=e$.join(I0,"config.json");function E0($=$0){if(!Q$.existsSync($))return{};try{return JSON.parse(Q$.readFileSync($,"utf-8"))}catch{return{}}}function q$($=$0){return E0($).license||""}function u$($,z=I0,Q=$0){if(!Q$.existsSync(z))Q$.mkdirSync(z,{recursive:!0});let U=E0(Q);if(U.license!==$)U.license=$,Q$.writeFileSync(Q,JSON.stringify(U,null,2),"utf-8")}import*as P$ from"fs";import*as T0 from"path";function A$($,z){if(z)return z;let Q=T0.resolve($,"components.json");if(P$.existsSync(Q))try{return JSON.parse(P$.readFileSync(Q,"utf-8")).version??"8"}catch{}return"8"}import v1 from"node-fetch";var x0={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};async function g$($,z,Q,U){let Y=z.map((X)=>{if(X.includes("modals/"))if(X.includes("-modal"))return X;else return X+"-modal";return X});try{let X=await v1("https://www.untitledui.com/react/api/components",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({type:$,components:Y,key:Q,version:U})});if(!X.ok)console.log(x0?.[X.statusText]||x0.no_components_found),process.exit(1);return await X.json()}catch(X){return null}}import z0 from"node-fetch";var D$={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};async function R0($,z="",Q){let U=`https://www.untitledui.com/react/api/components/list?key=${z}&type=${$}${Q?`&version=${Q}`:""}`;try{let Z=await z0(U),Y=await Z.json();if(!Z.ok)console.log(D$?.[Z.statusText]||D$.no_components_found),process.exit(1);if(!Y?.components?.length)return null;return Y}catch(Z){return console.error(Z),null}}async function S0($,z="",Q,U){let Z=`https://www.untitledui.com/react/api/components/list?key=${z}&type=${$}&subfolders=${Q.join(",")}${U?`&version=${U}`:""}`;try{let Y=await z0(Z);if(!Y.ok)console.log(D$?.[Y.statusText]||D$.no_components_found),process.exit(1);let X=await Y.json();if(!X?.components?.length)return null;return X}catch(Y){return console.error(Y),null}}async function w0($="",z){let Q=`https://www.untitledui.com/react/api/components/list?key=${$}${z?`&version=${z}`:""}`;try{let U=await z0(Q);if(!U.ok)console.log(D$?.[U.statusText]||D$.no_components_found),process.exit(1);let Z=await U.json();if(!Z?.types?.length)return null;return Z}catch(U){return console.error(U),null}}import Z0 from"fast-glob";import*as h$ from"fs";import*as W$ from"path";import{Project as g1}from"ts-morph";import{loadConfig as d0}from"tsconfig-paths";import C1 from"prettier";async function v0($,z="typescript"){try{return await C1.format($,{parser:z,printWidth:160,tabWidth:4})}catch(Q){return console.error("Error formatting with Prettier:",Q),$}}import Z$ from"chalk";import J$ from"fast-glob";import*as U$ from"fs";import*as Y$ from"path";import{loadConfig as f$}from"tsconfig-paths";import C0 from"fs";import F1 from"path";function F0($=""){let z=F1.join($,"package.json");if(!C0.existsSync(z))return null;else return JSON.parse(C0.readFileSync(z,"utf-8"))}import Q0 from"fs";import O0 from"path";import{createMatchPath as k0}from"tsconfig-paths";function u0($,z){let Q=O0.posix.join($,"index"),U=(Y)=>{try{return Q0.existsSync(Y)}catch{return!0}},Z=k0(z.absoluteBaseUrl,z.paths)(Q,void 0,U,[".ts",".tsx",".jsx",".js",".css"]);if(!Z)Z=k0(z.absoluteBaseUrl,z.paths)(Q,void 0,()=>!0,[".ts",".tsx",".jsx",".js",".css"]);if(Z){let Y=Z.split("/").slice(0,-1).join("/");try{if(Q0.existsSync(Y)&&Q0.statSync(Y).isFile())return O0.dirname(Y)}catch{}return Y}else return}var a=["**/node_modules/**",".next","public","dist","build"],d$=!1,P0={"next-app":"Next.js (App)","next-pages":"Next.js (Pages)",vite:"Vite",other:"Other"};async function M$($){let z=U$.existsSync(Y$.resolve($,"src")),Q=U$.existsSync(Y$.resolve($,`${z?"src/":""}app`)),[U,Z,Y,X,H]=await Promise.all([J$.glob("**/{next,vite,astro}.config.*|gatsby-config.*",{cwd:$,deep:2,ignore:a}),O1($),u1($),P1($),F0($)]),B=U$.existsSync(Y$.resolve($,"components.json")),J=null;if(B)J=JSON.parse(U$.readFileSync(Y$.resolve($,"components.json"),"utf-8"));let j=J$.sync(["**/**/theme.css"],{cwd:$,absolute:!0,onlyFiles:!0,ignore:a}),_=j?.[0]&&U$.readFileSync(j[0],"utf-8").match(/(--color-brand+-\d{1,3}):\s*(rgb\([^)]+\))/g)?.[1]||void 0,L={tailwind:{config:Y||void 0,brandColor:_?.replace(/--color-([^-]+(?:-[^-]+)?)-\d+:.*/,"$1")||void 0},examples:J?.examples||void 0,aliases:J?.aliases||X||{},paths:await k1(J?.aliases||{})||{},isTsx:Z,isSrcDir:z,isAppDir:Q,isComponentsJson:!!B,framework:"other",version:J?.version||void 0};if(U.find((b)=>b.startsWith("next.config."))?.length)return L.framework=Q?"next-app":"next-pages",L;else if(U.find((b)=>b.startsWith("vite.config."))?.length)return L.framework="vite",L;else if(Object.keys(H?.dependencies||{}).includes("react"))return L.framework="next-pages",L;else if(U?.length||U$.existsSync(Y$.resolve($,"package.json")))return L.framework="other",L;return null}async function O1($){return(await J$.glob("tsconfig.*",{cwd:$,deep:2,ignore:a})).length>0}async function k1($){let z={},Q=[],U=Object.entries($).filter(([,B])=>B);if(U.length===0)return null;let Z=process.cwd(),X=f$(Z).resultType==="success",H=await g0(Z);if(!H){if(!d$){if(d$=!0,process.stdout.write("\r\x1B[K"),X)console.log(Z$.yellow(`
3
- ⚠ Could not resolve path aliases from components.json - no paths configured in tsconfig.json.`));else console.log(Z$.yellow(`
4
- ⚠ Could not resolve path aliases from components.json - tsconfig.json not found.`));console.log(Z$.dim(` The following aliases will be used for imports but files will be placed in default locations:
5
- `)),U.forEach(([B,J])=>{console.log(Z$.dim(` ${B}: ${J}`))}),console.log(Z$.dim(`
2
+ import{Command as n3}from"commander";import k from"chalk";import{Command as i1}from"commander";import*as s from"fs";import w$ from"ora";import*as m from"path";import V$ from"prompts";import{Project as n1}from"ts-morph";import*as z$ from"fs";import*as e$ from"path";import v1 from"os";var T0=e$.join(v1.homedir(),".untitledui"),$0=e$.join(T0,"config.json");function x0($=$0){if(!z$.existsSync($))return{};try{return JSON.parse(z$.readFileSync($,"utf-8"))}catch{return{}}}function q$($=$0){return x0($).license||""}function u$($,z=T0,Q=$0){if(!z$.existsSync(z))z$.mkdirSync(z,{recursive:!0});let U=x0(Q);if(U.license!==$)U.license=$,z$.writeFileSync(Q,JSON.stringify(U,null,2),"utf-8")}import*as P$ from"fs";import*as R0 from"path";function A$($,z){if(z)return z;let Q=R0.resolve($,"components.json");if(P$.existsSync(Q))try{return JSON.parse(P$.readFileSync(Q,"utf-8")).version??"8"}catch{}return"8"}import C1 from"node-fetch";var S0={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};function w0($){if($.includes("modals/")&&!$.includes("-modal"))return $+"-modal";return $}async function g$($,z,Q,U){try{let Y=await C1("https://www.untitledui.com/react/api/components",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({type:$,components:z,key:Q,version:U})});if(!Y.ok)console.log(S0?.[Y.statusText]||S0.no_components_found),process.exit(1);let W=await Y.json();if(W.missing?.length)console.warn(`Skipped ${W.missing.length} unresolved component(s): ${W.missing.join(", ")}`);return W}catch(Y){return null}}import z0 from"node-fetch";var D$={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};async function Q0($,z="",Q){let U=`https://www.untitledui.com/react/api/components/list?key=${z}&type=${$}${Q?`&version=${Q}`:""}`;try{let Z=await z0(U),Y=await Z.json();if(!Z.ok)console.log(D$?.[Z.statusText]||D$.no_components_found),process.exit(1);if(!Y?.components?.length)return null;return Y}catch(Z){return console.error(Z),null}}async function Z0($,z="",Q,U){let Z=`https://www.untitledui.com/react/api/components/list?key=${z}&type=${$}&subfolders=${Q.join(",")}${U?`&version=${U}`:""}`;try{let Y=await z0(Z);if(!Y.ok)console.log(D$?.[Y.statusText]||D$.no_components_found),process.exit(1);let W=await Y.json();if(!W?.components?.length)return null;return W}catch(Y){return console.error(Y),null}}async function v0($="",z){let Q=`https://www.untitledui.com/react/api/components/list?key=${$}${z?`&version=${z}`:""}`;try{let U=await z0(Q);if(!U.ok)console.log(D$?.[U.statusText]||D$.no_components_found),process.exit(1);let Z=await U.json();if(!Z?.types?.length)return null;return Z}catch(U){return console.error(U),null}}import U0 from"fast-glob";import*as h$ from"fs";import*as U$ from"path";import{Project as d1}from"ts-morph";import{loadConfig as f0}from"tsconfig-paths";import F1 from"prettier";async function C0($,z="typescript"){try{return await F1.format($,{parser:z,printWidth:160,tabWidth:4})}catch(Q){return console.error("Error formatting with Prettier:",Q),$}}import Q$ from"chalk";import J$ from"fast-glob";import*as Y$ from"fs";import*as Z$ from"path";import{loadConfig as f$}from"tsconfig-paths";import F0 from"fs";import O1 from"path";function O0($=""){let z=O1.join($,"package.json");if(!F0.existsSync(z))return null;else return JSON.parse(F0.readFileSync(z,"utf-8"))}import Y0 from"fs";import k0 from"path";import{createMatchPath as u0}from"tsconfig-paths";function P0($,z){let Q=k0.posix.join($,"index"),U=(Y)=>{try{return Y0.existsSync(Y)}catch{return!0}},Z=u0(z.absoluteBaseUrl,z.paths)(Q,void 0,U,[".ts",".tsx",".jsx",".js",".css"]);if(!Z)Z=u0(z.absoluteBaseUrl,z.paths)(Q,void 0,()=>!0,[".ts",".tsx",".jsx",".js",".css"]);if(Z){let Y=Z.split("/").slice(0,-1).join("/");try{if(Y0.existsSync(Y)&&Y0.statSync(Y).isFile())return k0.dirname(Y)}catch{}return Y}else return}var p=["**/node_modules/**",".next","public","dist","build"],d$=!1,g0={"next-app":"Next.js (App)","next-pages":"Next.js (Pages)",vite:"Vite",other:"Other"};async function y$($){let z=Y$.existsSync(Z$.resolve($,"src")),Q=Y$.existsSync(Z$.resolve($,`${z?"src/":""}app`)),[U,Z,Y,W,H]=await Promise.all([J$.glob("**/{next,vite,astro}.config.*|gatsby-config.*",{cwd:$,deep:2,ignore:p}),k1($),P1($),g1($),O0($)]),X=Y$.existsSync(Z$.resolve($,"components.json")),G=null;if(X)G=JSON.parse(Y$.readFileSync(Z$.resolve($,"components.json"),"utf-8"));let N=J$.sync(["**/**/theme.css"],{cwd:$,absolute:!0,onlyFiles:!0,ignore:p}),b=N?.[0]&&Y$.readFileSync(N[0],"utf-8").match(/(--color-brand+-\d{1,3}):\s*(rgb\([^)]+\))/g)?.[1]||void 0,j={tailwind:{config:Y||void 0,brandColor:b?.replace(/--color-([^-]+(?:-[^-]+)?)-\d+:.*/,"$1")||void 0},examples:G?.examples||void 0,aliases:G?.aliases||W||{},paths:await u1(G?.aliases||{})||{},isTsx:Z,isSrcDir:z,isAppDir:Q,isComponentsJson:!!X,framework:"other",version:G?.version||void 0};if(U.find((_)=>_.startsWith("next.config."))?.length)return j.framework=Q?"next-app":"next-pages",j;else if(U.find((_)=>_.startsWith("vite.config."))?.length)return j.framework="vite",j;else if(Object.keys(H?.dependencies||{}).includes("react"))return j.framework="next-pages",j;else if(U?.length||Y$.existsSync(Z$.resolve($,"package.json")))return j.framework="other",j;return null}async function k1($){return(await J$.glob("tsconfig.*",{cwd:$,deep:2,ignore:p})).length>0}async function u1($){let z={},Q=[],U=Object.entries($).filter(([,X])=>X);if(U.length===0)return null;let Z=process.cwd(),W=f$(Z).resultType==="success",H=await d0(Z);if(!H){if(!d$){if(d$=!0,process.stdout.write("\r\x1B[K"),W)console.log(Q$.yellow(`
3
+ ⚠ Could not resolve path aliases from components.json - no paths configured in tsconfig.json.`));else console.log(Q$.yellow(`
4
+ ⚠ Could not resolve path aliases from components.json - tsconfig.json not found.`));console.log(Q$.dim(` The following aliases will be used for imports but files will be placed in default locations:
5
+ `)),U.forEach(([X,G])=>{console.log(Q$.dim(` ${X}: ${G}`))}),console.log(Q$.dim(`
6
6
  To fix this, add matching paths to your tsconfig.json.
7
- `))}return null}for(let[B,J]of Object.entries($))if(J){let j=await u0(J.replace(/\/\*$/,""),H);if(j)z[B]=Y$.relative(process.cwd(),j);else Q.push(`${B}: ${J}`)}if(Q.length>0&&!d$)d$=!0,process.stdout.write("\r\x1B[K"),console.log(Z$.yellow(`
8
- ⚠ Could not resolve the following path aliases from tsconfig.json:`)),Q.forEach((B)=>{console.log(Z$.dim(` ${B}`))}),console.log(Z$.dim(`
9
- These aliases will be used for imports but files will be placed in default locations.`)),console.log(Z$.dim(` To fix this, add matching paths to your tsconfig.json.
10
- `));return z}async function g0($){let[z,Q]=await Promise.all([J$.glob("next.config.*",{cwd:$,deep:1,ignore:a}),J$.glob("vite.config.*",{cwd:$,deep:1,ignore:a})]),U=z.length>0,Z=Q.length>0,Y=null;if(U)Y=f$($);else if(Z){if(Y=f$($),Y?.resultType==="failed"||!Object.keys(Y.paths||{}).length){let X=await J$.glob(["tsconfig.app.*","*/tsconfig.app.*"],{cwd:$,deep:1,onlyFiles:!0,absolute:!0,ignore:a}),[H]=X;if(H)try{let J=function(L){return L.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"").replace(/,(\s*[}\]])/g,"$1")},B=U$.readFileSync(H,"utf-8"),j=J(B),_=JSON.parse(j);if(_.compilerOptions?.paths)Y={resultType:"success",paths:_?.compilerOptions?.paths,baseUrl:_.compilerOptions.baseUrl||".",configFileAbsolutePath:H,absoluteBaseUrl:Y$.resolve($,_.compilerOptions.baseUrl||".")}}catch{}}}else Y=f$($);if(!Y||Y?.resultType==="failed"||!Object.keys(Y.paths).length)return null;return Y}async function u1($){let z=await J$.glob("tailwind.config.*",{cwd:$,deep:2,ignore:a});if(!z.length)return null;return z[0]}async function P1($){let z=await g0($);if(!z)return null;let Q={},U={app:/\/?app\/\*$/,components:/\/?components\/\*$/,utils:/\/?utils\/\*$/,styles:/\/?styles\/\*$/,hooks:/\/?hooks\/\*$/,src:/^(\.\/src\/\*|\.\/\*|\/src\/\*|src\/\*|\/\*|\*)$/};for(let[Z,Y]of Object.entries(z.paths)){let X=Z.replace(/\/\*$/,"/");for(let[H,B]of Object.entries(U))if(Y.some((J)=>B.test(J))){Q[H]=X;break}}return Q||null}function I$($,z){let Q=d0($),U=Z0.sync(["tailwind.config.*","**/globals.css","package.json"],{cwd:$,deep:4,absolute:!0,onlyFiles:!0,ignore:a}),Z=Z0.sync("**/{layout,_app,main}.tsx",{cwd:z?W$.posix.join($,z):$,deep:4,absolute:!0,onlyFiles:!0,ignore:a});return{tailwindFile:U.find((X)=>X.includes("tailwind.config.")),cssFile:U.find((X)=>X.includes("globals.css")),packageJson:U.find((X)=>X.includes("package.json")),tsConfig:Q?.resultType==="success"?Q?.configFileAbsolutePath:void 0,layoutFile:Z.find((X)=>X.includes("layout")),appFile:Z.find((X)=>X.includes("_app")),mainFile:Z.find((X)=>X.includes("main"))}}function E$($,z,Q={}){if($.startsWith("@/components/")){if(Q?.components)return $.replace(/^@\/components\//,W$.posix.join(Q.components,"/"));if(z)return $.replace(/^@\/components\//,W$.posix.join("@",z,"/"))}if($.startsWith("@/app/")&&Q?.app)return $.replace(/^@\/app\//,W$.posix.join(Q.app,"/"));if($.startsWith("@/utils/")&&Q?.utils)return $.replace(/^@\/utils\//,W$.posix.join(Q.utils,"/"));if($.startsWith("@/hooks/")&&Q?.hooks)return $.replace(/^@\/hooks\//,W$.posix.join(Q.hooks,"/"));if($.startsWith("@/styles/")&&Q?.styles)return $.replace(/^@\/styles\//,W$.posix.join(Q.styles,"/"));if($.startsWith("@/")&&Q?.src)return $.replace(/^@\//,W$.posix.join(Q.src,"/"));return $}async function f0($,z,Q="@/*"){let U=await d0($);if(U?.resultType==="failed")return null;let Z={};if(!Object.keys(U.paths).length){U.paths={[Q]:[`./${z?"src/":""}*`]},Z.src=Q.replace(/\/\*$/,"");let Y=await h$.promises.readFile(U.configFileAbsolutePath,"utf-8"),X,H=/(?:\/\/\s*)?"paths":\s*\{(?:[^{}]|\{[^}]*\})*\}/;if(!H.test(Y))X=Y.replace(/"compilerOptions":\s*{/,`"compilerOptions": {
11
- "paths": ${JSON.stringify(U.paths)},`);else X=Y.replace(H,`"paths": ${JSON.stringify(U.paths)}`);let J=new g1,j=await v0(X,"json");return J.createSourceFile(U.configFileAbsolutePath,j,{overwrite:!0}),await J.save(),Z}return Z||null}function h0($){let z=Z0.sync(["vite.config.*"],{cwd:$,absolute:!0,onlyFiles:!0,ignore:a})?.[0];if(!z)return!1;try{let Q=h$.readFileSync(z,"utf-8");return d1(Q)}catch{return!1}}function d1($){let z=$.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"");if(!["tailwindcss","@tailwindcss/vite","tailwind("].some((Y)=>z.includes(Y)))return!1;return["plugins:","postcss:","css:"].some((Y)=>z.includes(Y))}var f1=["npm","config","user","agent"].join("_");function L$($){if($===void 0)$=process.env[f1]||"";if($.startsWith("yarn"))return"yarn";if($.startsWith("pnpm"))return"pnpm";if($.startsWith("bun"))return"bun";return"npm"}function X$(){switch(L$()){case"yarn":return"yarn";case"pnpm":return"pnpx";case"bun":return"bunx";default:return"npx"}}function m0(){switch(L$()){case"yarn":return"yarn dev";case"pnpm":return"pnpm dev";case"bun":return"bun dev";default:return"npm run dev"}}import h1 from"async-retry";import{execa as c0}from"execa";async function B$($,z){let Q=Array.isArray($)?$:Array.from($);if(!Q.length)return;let{cwd:U,dev:Z=!1,spinner:Y,label:X=Z?"devDependencies":"dependencies"}=z,H=L$(),J=[H==="npm"?"install":"add",...Z?["-D"]:[],...Q];Y.start(`Installing ${X}`),await h1(()=>c0(H,J,{cwd:U}).catch(async(j)=>{if(j.message.includes("peer"))Y.warn(`${X} conflict detected. Retrying with --legacy-peer-deps...`),Y.start(`Installing ${X} with --legacy-peer-deps flag`),await c0(H,[...J,"--legacy-peer-deps"],{cwd:U});else throw j}),{retries:1}),Y.succeed(`${X} installed`)}var f=($)=>{if($.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
12
- `),process.exit(1)};function m$($){return $.replace(/^[ \t]*\/\/\s*(TODO:|collapse-(start|end)).*\r?\n?|[ \t]*{\s*\/\*\s*(TODO:|collapse-(start|end)).*?\*\/\s*}\r?\n?/gm,"")}import H$ from"path";function c$($,z,Q){let U=$.replace(/^(components|utils|hooks|styles)\//,"");if($.includes("components")&&z?.components)return H$.relative(process.cwd(),H$.posix.join(z.components,U));if($.includes("utils")&&z?.utils)return H$.relative(process.cwd(),H$.posix.join(z.utils,U));if($.includes("hooks")&&z?.hooks)return H$.relative(process.cwd(),H$.posix.join(z.hooks,U));if($.includes("styles")&&z?.styles)return H$.relative(process.cwd(),H$.posix.join(z.styles,U));return H$.posix.join(Q?"src":"",$)}import l0 from"node-fetch";import{Readable as m1,pipeline as c1}from"stream";import{x as l1}from"tar";import{promisify as p1}from"util";var a1=p1(c1);async function p0($,z){try{let Q=await s1(z);await a1(Q,l1({cwd:$,strip:1}))}catch(Q){throw Error(`Failed to download or extract repository from API: ${Q instanceof Error?Q.message:Q}`)}}async function s1($){let z=`https://www.untitledui.com/react/api/download-repo?template=${$.template}`;try{let Q=await l0(z,{method:"GET",headers:{"Content-Type":"application/json",Accept:"application/octet-stream"}});if(Q.status===403||Q.status===404)throw Error("Repository not found");if(!Q.ok)throw Error(`Failed to download from API. Status: ${Q.status} ${Q.statusText}`);if(!Q.body)throw Error("Response body is empty");return m1.from(Q.body)}catch(Q){throw Error(`Error downloading tarball: ${Q instanceof Error?Q.message:Q}`)}}async function a0($){let z=`https://www.untitledui.com/react/api/validate-key?key=${$}`;try{return(await l0(z)).status===200}catch{return!1}}async function l$($,z){if(!await a0($))z.fail("Invalid license key"),process.exit(1);u$($)}var N={components:[],path:"",type:void 0,license:q$()},s0=new r1().name("add").description("add a component to your project").argument("[components...]","the components to add").option("-a, --all","add all available components",!1).option("-o, --overwrite","overwrite existing files.",!1).option("-p, --path <path>","the path to add the component to.").option("-d, --dir <directory>","the directory where the project is located.").option("-t, --type <base|marketing|shared-assets|application|foundations>","the type of the component to add.").option("--include-all-components","automatically include all base components without prompting.",!1).option("-y, --yes","non-interactive mode - use defaults for all prompts (for AI agents/CI).",!1).option("--license <key>","API key for PRO access (alternative to stored config)").option("--lib-version <version>","component library version (7 or 8)").action(async($,z)=>{if($)N.components=$;if(z){if(N.all=z.all,N.dir=z.dir,N.path=z.path,N.overwrite=z.overwrite,N.includeAllComponents=z.includeAllComponents,N.license=z.license||N.license,N.version=z.libVersion,N.yes=z.yes,z.yes)N.includeAllComponents=!0,N.overwrite=!0}try{await Y0(N)}catch(Q){console.error(O.red(Q))}});async function Y0($){if($)N={...N,...$};let z=w$().start(),Q=m.posix.join(process.cwd(),N.dir||"");if(!s.existsSync(m.resolve(Q,"package.json")))z.warn("This command should be run in a project directory."),process.exit(1);let Z=A$(Q,N.version),Y=await M$(Q);if(N.license)await l$(N.license,z);z.stop();let X=[];if(N.components.length){let W=await g$(N.type,N.components,N.license,Z);if(W&&W.pro&&W.pro.length>0){if(console.log(),W.pro.length===1){let y=W.pro[0]?.split("/")[1]||W.pro[0];console.log(O.yellow(`\uD83D\uDD12 The ${O.cyan(y)} component requires PRO access.`))}else console.log(O.yellow("\uD83D\uDD12 The following components require PRO access:")),W.pro.forEach((y)=>{let V=y?.split("/")[1]||y;console.log(` • ${O.cyan(V)}`)});console.log(),console.log("To access PRO components:"),console.log(` ${O.green("→")} If you've already purchased: ${O.cyan(`${X$()} untitledui@latest login`)}`),console.log(` ${O.green("→")} To purchase PRO components: ${O.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(!W?.components.length)console.log("No components found"),process.exit(1);X.push(...W.components)}if(!N?.type&&!N?.components.length){if(N.yes)console.log(O.red("Error: In non-interactive mode (--yes), you must specify components as arguments.")),process.exit(1);let W=await w0(N.license,Z);if(!W)console.log("No component types found"),process.exit(1);let y=await V$({type:"select",name:"type",onState:f,message:`What type of ${O.cyan("component")} are you adding?`,choices:W?.types.map((V)=>({title:V,value:V}))});N.type=y.type}if(!N?.path&&!Y?.paths?.components)if(N.yes)N.path="components";else{let W=await V$({type:"text",name:"path",onState:f,message:`Where would you like to add the ${O.cyan("components")}?`,initial:"components"});N.path=W.path}if(N?.path&&Y&&Y.paths)Y.paths.components=m.posix.join(Y?.isSrcDir?"src":"",N.path);if(Y&&!Object.keys(Y?.aliases).length){let W="@/*";if(!N.yes){let y=/^[^*"]+\/\*\s*$/;W=(await V$({type:"text",name:"aliasPrefix",onState:f,initial:"@/*",message:`What is the ${O.cyan("import alias")} for your project?`,validate:(w)=>y.test(w)?!0:"Import alias must follow the pattern <prefix>/*"}))?.aliasPrefix}Y.aliases=await f0(Q,Y?.isSrcDir,W)}if(!N?.components.length){if(N.yes)console.log(O.red("Error: In non-interactive mode (--yes), you must specify components as arguments.")),process.exit(1);let W=await R0(N?.type,N.license,Z);if(!W)console.log("No components found"),process.exit(1);let y=await V$({type:"multiselect",name:"components",onState:f,message:`Which ${O.cyan("components")} would you like to add?`,choices:W?.components?.map((E)=>({title:E?.name+(E?.count?` (${E?.count} variants)`:"")||"example",value:E||"example",selected:N.components.includes(E.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!y.components||!y.components.length)console.log("No option selected. Exiting..."),process.exit(1);let V=y.components.filter((E)=>E?.type==="file").map((E)=>E.name),w=y.components.filter((E)=>E?.type==="dir").map((E)=>E.name),T=[];if(w.length){let E=await S0(N?.type,N.license,w,Z);if(E&&E.components.length)for(let C of E.components){let[d,F]=Object.entries(C)[0]||[],R=await V$({type:"select",name:"component",onState:f,message:`Which ${O.cyan("variant")} from ${O.cyan(d)} would you like to add?`,choices:F?.map((q)=>({title:q?.name.replace(/-modal/g,"")||"example",value:q?.name||"example",selected:N.components.includes(q.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!R.component)console.log("No variant selected for "+O.cyan(d));T.push(d+"/"+R.component)}else console.log("No variants found")}N.components=[...T,...V]}if(!N.components?.length)z.warn("No components selected. Exiting."),process.exit(1);let H=I$(Q),B=new Map,J=new Set,j=new Set,_=new i1({tsConfigFilePath:H?.tsConfig});if(z.start(),N.type&&N.components.length){let W=await g$(N.type,N.components,N.license,Z);if(!W?.components.length)console.log("No components found"),process.exit(1);X.push(...W.components)}let L=new Set;if(X.forEach((W)=>{W?.components?.forEach((y)=>{L.add({name:y.name,path:y.path})})}),z.stop(),L.size){let W=Array.from(L).filter((y)=>!s.existsSync(m.posix.join(Q,`${Y?.isSrcDir?"src":""}`,y?.path?.replace(/components\//,N.path+"/"))));if(W?.length)if(N.includeAllComponents)N.baseComponents=W.map((y)=>y.name);else{let y=await V$({type:"multiselect",name:"baseComponents",onState:f,message:"Select which base components you want to add",choices:W.map((V)=>({title:V?.name,value:V?.name,selected:!0})),instructions:!1,hint:"- Space to select. Return to submit"});if(N.baseComponents=y.baseComponents,!W.length&&!y.baseComponents?.length)z.warn("No components selected")}}if(z.start(),N?.baseComponents?.length){let W=await g$("",N.baseComponents,N.license,Z);if(!W||!W?.components.length)console.log("No base components found");else X.push(...W.components)}z.stop();let b=new Set;for(let W of X){let y=w$(`Adding ${W.name}...`).start(),V=W.files;W?.dependencies?.forEach((T)=>J.add(T)),W?.devDependencies?.forEach((T)=>j.add(T));let w=!1;try{for(let{path:T,code:E}of V||[]){let C=m.posix.join(Q,c$(T,Y?.paths,Y?.isSrcDir)),d=Y?.framework==="vite"?E.replace(`"use client";
13
-
14
- `,""):E,F=m$(d),R=m.dirname(C);if(s.existsSync(C)&&!N.overwrite&&!b.has(C)){if(s.readFileSync(C,"utf-8")!==F)B.set(C,{code:F,path:C}),w=!0}else if(!b.has(C)){let q=R.split(m.sep),K="";for(let A of q)if(K=K?m.join(K,A):A,K&&s.existsSync(K)&&s.statSync(K).isFile())throw Error(`Cannot create directory '${R}' because '${K}' is an existing file.
15
- Please check your path aliases in components.json and tsconfig.json.`);s.mkdirSync(R,{recursive:!0}),s.writeFileSync(C,F),b.add(C);let M=_.getSourceFile(m.resolve(C));if(M)M.replaceWithText(F);else M=_.addSourceFileAtPath(m.resolve(C));M.getImportDeclarations().forEach((A)=>{let x=A.getModuleSpecifierValue();A.setModuleSpecifier(E$(x,N.path,Y?.aliases))}),await M.save()}}if(w)y.warn(`Some files of ${O.yellow(W.name)} already exist`);else y.succeed(`${O.green(W.name)} is added successfully`)}catch(T){y.fail(`
16
- Failed to add the component ${O.red(W.name)}`),console.error(O.red(T)),process.exit(1)}}if(B.size&&!N?.overwrite){console.log(`
17
- Following files already exist in the directory.`),B.forEach((y)=>{console.log(O.green(`- ${m.relative(Q,y.path)}`))});let W=!1;if(N.yes)W=!0;else{let y=await V$({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0});if(y.overwrite===void 0)console.log(`
18
- Use ${O.cyan("--overwrite")} or ${O.cyan("-o")} flag to overwrite existing files, or run with ${O.cyan("node")} instead of ${O.cyan("bun")}.`),process.exit(1);W=y.overwrite}if(W){let y=w$("Overwriting files").start();B.forEach((V)=>{let w=_.addSourceFileAtPath(m.resolve(V.path));w.replaceWithText(V.code),w.getImportDeclarations().forEach((T)=>{let E=T.getModuleSpecifierValue();T.setModuleSpecifier(E$(E,N.path,Y?.aliases))}),w.saveSync()}),y.succeed("Files are overwritten")}}if(J.size){let W=w$().start();await B$(J,{cwd:Q,spinner:W,label:"component dependencies"})}if(j.size){let W=w$().start();await B$(j,{cwd:Q,dev:!0,spinner:W,label:"component devDependencies"})}if(N.message!==void 0){if(N.message)console.log(N.message);return}process.exit(0)}import X0 from"chalk";import{Command as e1}from"commander";import*as K$ from"fs";import $3 from"http";import z3 from"open";import Q3 from"ora";import Z3 from"os";import*as H0 from"path";import{URL as Y3}from"url";import*as p$ from"fs";import*as j$ from"path";import{fileURLToPath as n1}from"url";var o1=n1(import.meta.url),U0=j$.dirname(o1);function t1(){let $=[j$.join(U0,"..","templates","auth-template.html"),j$.join(U0,"templates","auth-template.html"),j$.join(process.cwd(),"node_modules","untitledui","templates","auth-template.html"),j$.join(U0,"..","..","templates","auth-template.html")];for(let z of $)if(p$.existsSync(z))return z;throw Error("Auth template file not found. Please ensure the CLI package is properly installed.")}function r0(){try{let $=t1();return p$.readFileSync($,"utf-8")}catch($){return console.warn("Warning: Using fallback auth template. Some styling may be missing."),`<!doctype html>
7
+ `))}return null}for(let[X,G]of Object.entries($))if(G){let N=await P0(G.replace(/\/\*$/,""),H);if(N)z[X]=Z$.relative(process.cwd(),N);else Q.push(`${X}: ${G}`)}if(Q.length>0&&!d$)d$=!0,process.stdout.write("\r\x1B[K"),console.log(Q$.yellow(`
8
+ ⚠ Could not resolve the following path aliases from tsconfig.json:`)),Q.forEach((X)=>{console.log(Q$.dim(` ${X}`))}),console.log(Q$.dim(`
9
+ These aliases will be used for imports but files will be placed in default locations.`)),console.log(Q$.dim(` To fix this, add matching paths to your tsconfig.json.
10
+ `));return z}async function d0($){let[z,Q]=await Promise.all([J$.glob("next.config.*",{cwd:$,deep:1,ignore:p}),J$.glob("vite.config.*",{cwd:$,deep:1,ignore:p})]),U=z.length>0,Z=Q.length>0,Y=null;if(U)Y=f$($);else if(Z){if(Y=f$($),Y?.resultType==="failed"||!Object.keys(Y.paths||{}).length){let W=await J$.glob(["tsconfig.app.*","*/tsconfig.app.*"],{cwd:$,deep:1,onlyFiles:!0,absolute:!0,ignore:p}),[H]=W;if(H)try{let G=function(j){return j.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"").replace(/,(\s*[}\]])/g,"$1")},X=Y$.readFileSync(H,"utf-8"),N=G(X),b=JSON.parse(N);if(b.compilerOptions?.paths)Y={resultType:"success",paths:b?.compilerOptions?.paths,baseUrl:b.compilerOptions.baseUrl||".",configFileAbsolutePath:H,absoluteBaseUrl:Z$.resolve($,b.compilerOptions.baseUrl||".")}}catch{}}}else Y=f$($);if(!Y||Y?.resultType==="failed"||!Object.keys(Y.paths).length)return null;return Y}async function P1($){let z=await J$.glob("tailwind.config.*",{cwd:$,deep:2,ignore:p});if(!z.length)return null;return z[0]}async function g1($){let z=await d0($);if(!z)return null;let Q={},U={app:/\/?app\/\*$/,components:/\/?components\/\*$/,utils:/\/?utils\/\*$/,styles:/\/?styles\/\*$/,hooks:/\/?hooks\/\*$/,src:/^(\.\/src\/\*|\.\/\*|\/src\/\*|src\/\*|\/\*|\*)$/};for(let[Z,Y]of Object.entries(z.paths)){let W=Z.replace(/\/\*$/,"/");for(let[H,X]of Object.entries(U))if(Y.some((G)=>X.test(G))){Q[H]=W;break}}return Q||null}function I$($,z){let Q=f0($),U=U0.sync(["tailwind.config.*","**/globals.css","package.json"],{cwd:$,deep:4,absolute:!0,onlyFiles:!0,ignore:p}),Z=U0.sync("**/{layout,_app,main}.tsx",{cwd:z?U$.posix.join($,z):$,deep:4,absolute:!0,onlyFiles:!0,ignore:p});return{tailwindFile:U.find((W)=>W.includes("tailwind.config.")),cssFile:U.find((W)=>W.includes("globals.css")),packageJson:U.find((W)=>W.includes("package.json")),tsConfig:Q?.resultType==="success"?Q?.configFileAbsolutePath:void 0,layoutFile:Z.find((W)=>W.includes("layout")),appFile:Z.find((W)=>W.includes("_app")),mainFile:Z.find((W)=>W.includes("main"))}}function E$($,z,Q={}){if($.startsWith("@/components/")){if(Q?.components)return $.replace(/^@\/components\//,U$.posix.join(Q.components,"/"));if(z)return $.replace(/^@\/components\//,U$.posix.join("@",z,"/"))}if($.startsWith("@/app/")&&Q?.app)return $.replace(/^@\/app\//,U$.posix.join(Q.app,"/"));if($.startsWith("@/utils/")&&Q?.utils)return $.replace(/^@\/utils\//,U$.posix.join(Q.utils,"/"));if($.startsWith("@/hooks/")&&Q?.hooks)return $.replace(/^@\/hooks\//,U$.posix.join(Q.hooks,"/"));if($.startsWith("@/styles/")&&Q?.styles)return $.replace(/^@\/styles\//,U$.posix.join(Q.styles,"/"));if($.startsWith("@/")&&Q?.src)return $.replace(/^@\//,U$.posix.join(Q.src,"/"));return $}async function h0($,z,Q="@/*"){let U=await f0($);if(U?.resultType==="failed")return null;let Z={};if(!Object.keys(U.paths).length){U.paths={[Q]:[`./${z?"src/":""}*`]},Z.src=Q.replace(/\/\*$/,"");let Y=await h$.promises.readFile(U.configFileAbsolutePath,"utf-8"),W,H=/(?:\/\/\s*)?"paths":\s*\{(?:[^{}]|\{[^}]*\})*\}/;if(!H.test(Y))W=Y.replace(/"compilerOptions":\s*{/,`"compilerOptions": {
11
+ "paths": ${JSON.stringify(U.paths)},`);else W=Y.replace(H,`"paths": ${JSON.stringify(U.paths)}`);let G=new d1,N=await C0(W,"json");return G.createSourceFile(U.configFileAbsolutePath,N,{overwrite:!0}),await G.save(),Z}return Z||null}function m0($){let z=U0.sync(["vite.config.*"],{cwd:$,absolute:!0,onlyFiles:!0,ignore:p})?.[0];if(!z)return!1;try{let Q=h$.readFileSync(z,"utf-8");return f1(Q)}catch{return!1}}function f1($){let z=$.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"");if(!["tailwindcss","@tailwindcss/vite","tailwind("].some((Y)=>z.includes(Y)))return!1;return["plugins:","postcss:","css:"].some((Y)=>z.includes(Y))}var h1=["npm","config","user","agent"].join("_");function L$($){if($===void 0)$=process.env[h1]||"";if($.startsWith("yarn"))return"yarn";if($.startsWith("pnpm"))return"pnpm";if($.startsWith("bun"))return"bun";return"npm"}function W$(){switch(L$()){case"yarn":return"yarn";case"pnpm":return"pnpx";case"bun":return"bunx";default:return"npx"}}function c0(){switch(L$()){case"yarn":return"yarn dev";case"pnpm":return"pnpm dev";case"bun":return"bun dev";default:return"npm run dev"}}import m1 from"async-retry";import{execa as l0}from"execa";async function X$($,z){let Q=Array.isArray($)?$:Array.from($);if(!Q.length)return;let{cwd:U,dev:Z=!1,spinner:Y,label:W=Z?"devDependencies":"dependencies"}=z,H=L$(),G=[H==="npm"?"install":"add",...Z?["-D"]:[],...Q];Y.start(`Installing ${W}`),await m1(()=>l0(H,G,{cwd:U}).catch(async(N)=>{if(N.message.includes("peer"))Y.warn(`${W} conflict detected. Retrying with --legacy-peer-deps...`),Y.start(`Installing ${W} with --legacy-peer-deps flag`),await l0(H,[...G,"--legacy-peer-deps"],{cwd:U});else throw N}),{retries:1}),Y.succeed(`${W} installed`)}var f=($)=>{if($.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
12
+ `),process.exit(1)};function m$($){return $.replace(/^[ \t]*\/\/\s*(TODO:|collapse-(start|end)).*\r?\n?|[ \t]*{\s*\/\*\s*(TODO:|collapse-(start|end)).*?\*\/\s*}\r?\n?/gm,"")}import B$ from"path";function c$($,z,Q){let U=$.replace(/^(components|utils|hooks|styles)\//,"");if($.includes("components")&&z?.components)return B$.relative(process.cwd(),B$.posix.join(z.components,U));if($.includes("utils")&&z?.utils)return B$.relative(process.cwd(),B$.posix.join(z.utils,U));if($.includes("hooks")&&z?.hooks)return B$.relative(process.cwd(),B$.posix.join(z.hooks,U));if($.includes("styles")&&z?.styles)return B$.relative(process.cwd(),B$.posix.join(z.styles,U));return B$.posix.join(Q?"src":"",$)}import a0 from"node-fetch";import{Readable as c1,pipeline as l1}from"stream";import{x as a1}from"tar";import{promisify as p1}from"util";var s1=p1(l1);async function p0($,z){try{let Q=await r1(z);await s1(Q,a1({cwd:$,strip:1}))}catch(Q){throw Error(`Failed to download or extract repository from API: ${Q instanceof Error?Q.message:Q}`)}}async function r1($){let z=`https://www.untitledui.com/react/api/download-repo?template=${$.template}`;try{let Q=await a0(z,{method:"GET",headers:{"Content-Type":"application/json",Accept:"application/octet-stream"}});if(Q.status===403||Q.status===404)throw Error("Repository not found");if(!Q.ok)throw Error(`Failed to download from API. Status: ${Q.status} ${Q.statusText}`);if(!Q.body)throw Error("Response body is empty");return c1.from(Q.body)}catch(Q){throw Error(`Error downloading tarball: ${Q instanceof Error?Q.message:Q}`)}}async function s0($){let z=`https://www.untitledui.com/react/api/validate-key?key=${$}`;try{return(await a0(z)).status===200}catch{return!1}}async function l$($,z){if(!await s0($))z.fail("Invalid license key"),process.exit(1);u$($)}var V={components:[],path:"",type:void 0,license:q$()},r0=new i1().name("add").description("add a component to your project").argument("[components...]","the components to add").option("-a, --all","add all available components",!1).option("-o, --overwrite","overwrite existing files.",!1).option("-p, --path <path>","the path to add the component to.").option("-d, --dir <directory>","the directory where the project is located.").option("-t, --type <base|marketing|shared-assets|application|foundations>","the type of the component to add.").option("--include-all-components","automatically include all base components without prompting.",!1).option("-y, --yes","non-interactive mode - use defaults for all prompts (for AI agents/CI).",!1).option("--license <key>","API key for PRO access (alternative to stored config)").option("--lib-version <version>","component library version (7 or 8)").action(async($,z)=>{if($)V.components=$.map(w0);if(z){if(V.all=z.all,V.dir=z.dir,V.path=z.path,V.type=z.type,V.overwrite=z.overwrite,V.includeAllComponents=z.includeAllComponents,V.license=z.license||V.license,V.version=z.libVersion,V.yes=z.yes,z.yes)V.includeAllComponents=!0,V.overwrite=!0}try{await W0(V)}catch(Q){console.error(k.red(Q))}});async function W0($){if($)V={...V,...$};let z=w$().start(),Q=m.posix.join(process.cwd(),V.dir||"");if(!s.existsSync(m.resolve(Q,"package.json")))z.warn("This command should be run in a project directory."),process.exit(1);let Z=A$(Q,V.version),Y=await y$(Q);if(V.license)await l$(V.license,z);z.stop();let W=[],H=!1;if(V.components.length){let K=await g$(V.type,V.components,V.license,Z);if(K&&K.pro&&K.pro.length>0){if(console.log(),K.pro.length===1){let M=K.pro[0]?.split("/")[1]||K.pro[0];console.log(k.yellow(`\uD83D\uDD12 The ${k.cyan(M)} component requires PRO access.`))}else console.log(k.yellow("\uD83D\uDD12 The following components require PRO access:")),K.pro.forEach((M)=>{let v=M?.split("/")[1]||M;console.log(` • ${k.cyan(v)}`)});console.log(),console.log("To access PRO components:"),console.log(` ${k.green("→")} If you've already purchased: ${k.cyan(`${W$()} untitledui@latest login`)}`),console.log(` ${k.green("→")} To purchase PRO components: ${k.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(!K?.components.length)console.log("No components found"),process.exit(1);W.push(...K.components),H=!0}if(!V?.type&&!V?.components.length){if(V.yes&&!V.all)console.log(k.red("Error: In non-interactive mode (--yes), you must specify components as arguments.")),process.exit(1);if(V.all&&V.yes)console.log(k.red("Error: --all requires --type <name> in non-interactive mode.")),process.exit(1);let K=await v0(V.license,Z);if(!K)console.log("No component types found"),process.exit(1);let M=await V$({type:"select",name:"type",onState:f,message:`What type of ${k.cyan("component")} are you adding?`,choices:K?.types.map((v)=>({title:v,value:v}))});V.type=M.type}if(V.all&&V.type&&!V.components.length){let K=await Q0(V.type,V.license,Z);if(!K?.components?.length)console.log("No components found"),process.exit(1);let M=K.components.filter((E)=>E.type==="file").map((E)=>E.name),v=K.components.filter((E)=>E.type==="dir").map((E)=>E.name),R=[];if(v.length){let E=await Z0(V.type,V.license,v,Z);if(E?.components)for(let T of E.components){let C=Object.entries(T)[0];if(!C)continue;let[O,S]=C;if(S?.length)R.push(...S.map((J)=>`${O}/${J.name}`))}}V.components=[...R,...M]}if(!V?.path&&!Y?.paths?.components)if(V.yes)V.path="components";else{let K=await V$({type:"text",name:"path",onState:f,message:`Where would you like to add the ${k.cyan("components")}?`,initial:"components"});V.path=K.path}if(V?.path&&Y&&Y.paths)Y.paths.components=m.posix.join(Y?.isSrcDir?"src":"",V.path);if(Y&&!Object.keys(Y?.aliases).length){let K="@/*";if(!V.yes){let M=/^[^*"]+\/\*\s*$/;K=(await V$({type:"text",name:"aliasPrefix",onState:f,initial:"@/*",message:`What is the ${k.cyan("import alias")} for your project?`,validate:(R)=>M.test(R)?!0:"Import alias must follow the pattern <prefix>/*"}))?.aliasPrefix}Y.aliases=await h0(Q,Y?.isSrcDir,K)}if(!V?.components.length){if(V.yes)console.log(k.red("Error: In non-interactive mode (--yes), you must specify components as arguments.")),process.exit(1);let K=await Q0(V?.type,V.license,Z);if(!K)console.log("No components found"),process.exit(1);let M=await V$({type:"multiselect",name:"components",onState:f,message:`Which ${k.cyan("components")} would you like to add?`,choices:K?.components?.map((T)=>({title:T?.name+(T?.count?` (${T?.count} variants)`:"")||"example",value:T||"example",selected:V.components.includes(T.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!M.components||!M.components.length)console.log("No option selected. Exiting..."),process.exit(1);let v=M.components.filter((T)=>T?.type==="file").map((T)=>T.name),R=M.components.filter((T)=>T?.type==="dir").map((T)=>T.name),E=[];if(R.length){let T=await Z0(V?.type,V.license,R,Z);if(T&&T.components.length)for(let C of T.components){let[O,S]=Object.entries(C)[0]||[],J=await V$({type:"select",name:"component",onState:f,message:`Which ${k.cyan("variant")} from ${k.cyan(O)} would you like to add?`,choices:S?.map((q)=>({title:q?.name.replace(/-modal/g,"")||"example",value:q?.name||"example",selected:V.components.includes(q.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!J.component)console.log("No variant selected for "+k.cyan(O));E.push(O+"/"+J.component)}else console.log("No variants found")}V.components=[...E,...v]}if(!V.components?.length)z.warn("No components selected. Exiting."),process.exit(1);let X=I$(Q),G=new Map,N=new Set,b=new Set,j=new n1({tsConfigFilePath:X?.tsConfig});if(z.start(),V.type&&V.components.length&&!H){let K=await g$(V.type,V.components,V.license,Z);if(!K?.components.length)console.log("No components found"),process.exit(1);W.push(...K.components)}let _=new Set;if(W.forEach((K)=>{K?.components?.forEach((M)=>{_.add({name:M.name,path:M.path})})}),z.stop(),_.size){let K=Array.from(_).filter((M)=>!s.existsSync(m.posix.join(Q,`${Y?.isSrcDir?"src":""}`,M?.path?.replace(/components\//,V.path+"/"))));if(K?.length)if(V.includeAllComponents)V.baseComponents=K.map((M)=>M.name);else{let M=await V$({type:"multiselect",name:"baseComponents",onState:f,message:"Select which base components you want to add",choices:K.map((v)=>({title:v?.name,value:v?.name,selected:!0})),instructions:!1,hint:"- Space to select. Return to submit"});if(V.baseComponents=M.baseComponents,!K.length&&!M.baseComponents?.length)z.warn("No components selected")}}if(z.start(),V?.baseComponents?.length){let K=await g$("",V.baseComponents,V.license,Z);if(!K||!K?.components.length)console.log("No base components found");else W.push(...K.components)}z.stop();let B=new Set;for(let K of W){let M=w$(`Adding ${K.name}...`).start(),v=K.files;K?.dependencies?.forEach((E)=>N.add(E)),K?.devDependencies?.forEach((E)=>b.add(E));let R=!1;try{for(let{path:E,code:T}of v||[]){let C=m.posix.join(Q,c$(E,Y?.paths,Y?.isSrcDir)),O=Y?.framework==="vite"?T.replace(`"use client";
13
+
14
+ `,""):T,S=m$(O),J=m.dirname(C);if(s.existsSync(C)&&!V.overwrite&&!B.has(C)){if(s.readFileSync(C,"utf-8")!==S)G.set(C,{code:S,path:C}),R=!0}else if(!B.has(C)){let q=J.split(m.sep),L="";for(let x of q)if(L=L?m.join(L,x):x,L&&s.existsSync(L)&&s.statSync(L).isFile())throw Error(`Cannot create directory '${J}' because '${L}' is an existing file.
15
+ Please check your path aliases in components.json and tsconfig.json.`);s.mkdirSync(J,{recursive:!0}),s.writeFileSync(C,S),B.add(C);let A=j.getSourceFile(m.resolve(C));if(A)A.replaceWithText(S);else A=j.addSourceFileAtPath(m.resolve(C));A.getImportDeclarations().forEach((x)=>{let u=x.getModuleSpecifierValue();x.setModuleSpecifier(E$(u,V.path,Y?.aliases))}),await A.save()}}if(R)M.warn(`Some files of ${k.yellow(K.name)} already exist`);else M.succeed(`${k.green(K.name)} is added successfully`)}catch(E){M.fail(`
16
+ Failed to add the component ${k.red(K.name)}`),console.error(k.red(E)),process.exit(1)}}if(G.size&&!V?.overwrite){console.log(`
17
+ Following files already exist in the directory.`),G.forEach((M)=>{console.log(k.green(`- ${m.relative(Q,M.path)}`))});let K=!1;if(V.yes)K=!0;else{let M=await V$({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0});if(M.overwrite===void 0)console.log(`
18
+ Use ${k.cyan("--overwrite")} or ${k.cyan("-o")} flag to overwrite existing files, or run with ${k.cyan("node")} instead of ${k.cyan("bun")}.`),process.exit(1);K=M.overwrite}if(K){let M=w$("Overwriting files").start();G.forEach((v)=>{let R=j.addSourceFileAtPath(m.resolve(v.path));R.replaceWithText(v.code),R.getImportDeclarations().forEach((E)=>{let T=E.getModuleSpecifierValue();E.setModuleSpecifier(E$(T,V.path,Y?.aliases))}),R.saveSync()}),M.succeed("Files are overwritten")}}if(N.size){let K=w$().start();await X$(N,{cwd:Q,spinner:K,label:"component dependencies"})}if(b.size){let K=w$().start();await X$(b,{cwd:Q,dev:!0,spinner:K,label:"component devDependencies"})}if(V.message!==void 0){if(V.message)console.log(V.message);return}process.exit(0)}import H0 from"chalk";import{Command as $3}from"commander";import*as H$ from"fs";import z3 from"http";import Q3 from"open";import Z3 from"ora";import Y3 from"os";import*as q0 from"path";import{URL as U3}from"url";import*as a$ from"fs";import*as j$ from"path";import{fileURLToPath as o1}from"url";var t1=o1(import.meta.url),X0=j$.dirname(t1);function e1(){let $=[j$.join(X0,"..","templates","auth-template.html"),j$.join(X0,"templates","auth-template.html"),j$.join(process.cwd(),"node_modules","untitledui","templates","auth-template.html"),j$.join(X0,"..","..","templates","auth-template.html")];for(let z of $)if(a$.existsSync(z))return z;throw Error("Auth template file not found. Please ensure the CLI package is properly installed.")}function i0(){try{let $=e1();return a$.readFileSync($,"utf-8")}catch($){return console.warn("Warning: Using fallback auth template. Some styling may be missing."),`<!doctype html>
19
19
  <html lang="en">
20
20
  <head>
21
21
  <meta charset="UTF-8" />
@@ -61,120 +61,120 @@ Use ${O.cyan("--overwrite")} or ${O.cyan("-o")} flag to overwrite existing files
61
61
  {{AUTO_CLOSE_SCRIPT}}
62
62
  </div>
63
63
  </body>
64
- </html>`}}function i0(){return r0().replace("{{TITLE}}","Authentication successful").replace("{{HEADING}}","Authentication successful").replace("{{DESCRIPTION}}","You can now close this tab and return to your terminal.").replace("{{AUTO_CLOSE_SCRIPT}}","<script>setTimeout(() => window.close(), 10000);</script>")}function a$($){return r0().replace("{{TITLE}}","Authentication failed").replace("{{HEADING}}","Authentication failed").replace("{{DESCRIPTION}}",$).replace("{{AUTO_CLOSE_SCRIPT}}","")}var B0=H0.join(Z3.homedir(),".untitledui"),W0=H0.join(B0,"config.json"),n0=new e1().name("login").description("authenticate with Untitled UI to access PRO components").action(async()=>{let $=Q3("Starting authentication...").start();try{await U3($),$.succeed("Authentication completed successfully!"),console.log(X0.green(`
65
- ✨ You can now access PRO components with the CLI!`)),process.exit(0)}catch(z){$.fail(`Authentication failed: ${z instanceof Error?z.message:z}`),process.exit(1)}});async function U3($){return new Promise((z,Q)=>{let U=$3.createServer((Z,Y)=>{let X=new Y3(Z.url,"http://localhost");if(X.pathname==="/callback"){let H=X.searchParams.get("apiKey"),B=X.searchParams.get("error");if(B){Y.writeHead(400,{"Content-Type":"text/html"}),Y.end(a$(decodeURIComponent(B))),U.close(),Q(Error(decodeURIComponent(B)));return}if(!H){Y.writeHead(400,{"Content-Type":"text/html"}),Y.end(a$("No Access Token received")),U.close(),Q(Error("No Access Token received"));return}try{W3(H),Y.writeHead(200,{"Content-Type":"text/html"}),Y.end(i0()),U.close(),z()}catch(J){Y.writeHead(500,{"Content-Type":"text/html"}),Y.end(a$("Failed to save authentication data")),U.close(),Q(J)}}else Y.writeHead(404),Y.end("Not found")});U.listen(0,"localhost",()=>{let X=`https://www.untitledui.com/react/api/cli-auth?port=${U.address().port}`;$.text="Opening browser for authentication...",z3(X).catch((H)=>{console.log(X0.yellow(`
66
- Failed to open browser automatically: ${H.message}`)),console.log(X0.cyan(`Please manually open: ${X}
67
- `))}),$.text="Waiting for authentication in browser..."}),setTimeout(()=>{U.close(),Q(Error("Authentication timeout. Please try again."))},300000)})}function W3($){if(!K$.existsSync(B0))K$.mkdirSync(B0,{recursive:!0});let z={};if(K$.existsSync(W0))try{z=JSON.parse(K$.readFileSync(W0,"utf-8"))}catch{z={}}z.license=$,K$.writeFileSync(W0,JSON.stringify(z,null,2),"utf-8")}import J3 from"async-retry";import I from"chalk";import{Command as y3}from"commander";import*as c from"fs";import v$ from"ora";import*as S from"path";import N$ from"prompts";import{Project as G3}from"ts-morph";import X3 from"node-fetch";async function T$($,z,Q){try{let Z=await X3("https://www.untitledui.com/react/api/components/example",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({example:$,key:z,version:Q})});if(!Z.ok){if(Z.status===401||Z.status===403)return{type:"error",status:Z.status,message:"PRO access required"};return console.error(`API error: ${Z.status} - ${Z.statusText}`),null}return await Z.json()}catch(Z){return console.error(Z),null}}import G0 from"async-retry";import h from"chalk";import{Command as B3}from"commander";import{execa as M0}from"execa";import i$ from"fast-glob";import r from"fs";import x$ from"ora";import*as u from"path";import n$ from"prompts";import{Project as H3}from"ts-morph";import{fileURLToPath as K3}from"url";import*as s$ from"fs";import*as o0 from"path";function K0($,z){let Q=o0.join($,"package.json");if(!s$.existsSync(Q))return z;let U=JSON.parse(s$.readFileSync(Q,"utf-8")),Z={...U.dependencies,...U.devDependencies},Y=[];for(let X of z){let H=Z[X];if(!H){Y.push(X);continue}if(X==="tailwindcss"){let B=H.match(/\d+/);if((B?parseInt(B[0],10):0)<4)Y.push(X)}}return Y}import q0 from"chalk";import*as y$ from"fs";import*as r$ from"path";function J0($){if(!y$.existsSync(r$.resolve($)))console.log(q0.red(`Error: CSS file not found at ${$}`)),process.exit(1);let z=y$.readFileSync(r$.resolve($),"utf-8"),Q=/(--color-[a-zA-Z-]+-\d{1,3}):\s*(rgb\([^)]+\))/g,U={},Z;while((Z=Q.exec(z))!==null)if(Z[1]&&Z[2])U[Z[1]]=Z[2];return U}function y0($,z,Q){let U=r$.resolve(Q);if(!y$.existsSync(U)){console.log(q0.red(`Error: CSS file not found at ${U}`));return}let Z=y$.readFileSync(U,"utf-8"),Y=J0(Q),X={},H={};for(let[J,j]of Object.entries(Y))if(J.startsWith(`--color-${$}-`)){let _=J.replace(`--color-${$}-`,"");X[_]=J}else if(J.startsWith(`--color-${z}-`)){let _=J.replace(`--color-${z}-`,"");H[_]=j}let B=!1;for(let[J,j]of Object.entries(X))if(H[J]){let _=H[J],L=new RegExp(`(${j}):\\s*rgb\\([^)]*\\);?`,"g");if(L.test(Z))Z=Z.replace(L,`$1: ${_};`),B=!0;else console.log(q0.yellow(`No match found for ${j}`))}if(B)y$.writeFileSync(U,Z,"utf-8")}var q3=K3(import.meta.url),t0=u.dirname(q3),$1="vite",z1="nextjs",e0={[z1]:"Next.js",[$1]:"Vite"},o="",v={color:"",template:"",framework:void 0,license:q$()},Q1=new B3().name("init").description("initialize a new project or adjust an existing one").argument("[directory]").usage("[directory] [options]").helpOption("-h, --help","display this help message.").option("--vite","initialize a Vite project.",!1).option("--nextjs","initialize a Next.js project.",!1).option("-o, --overwrite","overwrite existing files.",!1).option("--colors-list","show the colors list.",!1).option("-c, --color <color-name>","specify a color for the project.").option("--license <key>","API key for PRO access (alternative to stored config)").option("--lib-version <version>","component library version (7 or 8)").action(async($,z)=>{if($)o=$;if(z){if(v.color=z.color,v.template=z.template,v.overwrite=z.overwrite,v.colorsList=z.colorsList,v.license=z.license||v.license,v.version=z.libVersion,v.vite=z.vite,v.nextjs=z.nextjs,z.vite)v.framework=$1;if(z.nextjs)v.framework=z1}try{await L0(z),process.exit(0)}catch(Q){console.error(h.red(Q)),process.exit(1)}});async function L0($,z=null){let Q=process.cwd(),U=r.existsSync(u.resolve(Q,"package.json")),Z=u.resolve(u.join(t0,"../config/styles","theme.css")),Y=J0(Z??""),X=Array.from(new Set(Object.keys(Y).map((j)=>j?.split("--color-")?.[1]?.replace(/-\d{1,3}/,"")))),H=x$().start(),B=await M$(Q);if(v.license)u$(v.license);if(!U){if(H.stop(),!o){let _=await n$({onState:f,type:"text",name:"path",message:"What is your project named?",initial:"untitled-ui"});if(typeof _.path==="string")o=_.path.trim()}if(z)z.projectPath=o;let j=r.existsSync(u.resolve(u.posix.join(Q,o,"package.json")));if(r.existsSync(u.resolve(u.posix.join(Q,o)))&&j)H.fail(h.red("Directory already exists!")),process.exit(1);if(v.vite&&v.nextjs||!v.framework){let _=await n$({type:"select",name:"framework",onState:f,message:`Which ${h.cyan("framework")} would you like to use?`,choices:Object.entries(e0).map(([L,b])=>({title:b,value:L}))});v.framework=_.framework}H.succeed("Framework is selected: "+h.green(e0[v.framework]))}else if(B?.framework==="other")H.fail("Unsupported project framework"),console.log(`Please refer to the documentation ${h.cyan("https://www.untitledui.com/docs")} for supported frameworks or proceed with manual installation.`),process.exit(1);else if(B?.framework.startsWith("next")||B?.framework.startsWith("vite"))if(!z&&!B.tailwind.brandColor)H.succeed(h.yellow(`Detected ${P0[B.framework]} project, proceeding with the setup...`));else H.stop();if(v.colorsList||!v.color&&!B?.tailwind.brandColor){let j=await n$({type:"select",name:"color",onState:f,initial:$.color??"",message:`Which ${h.cyan("color")} would you like to use as the ${h.cyanBright("brand")} color?`,choices:X.map((_)=>({title:_,value:_}))});if(v.color=j.color,v.colorsList&&B)B.tailwind.brandColor=j.color}let J=u.posix.join(Q,o||"");if(o&&!U){let j=u.resolve(o);console.log(`
68
- Creating a new project in ${h.blue(o)}`);let _=x$("Downloading and extracting the repository...").start();try{r.mkdirSync(j,{recursive:!0}),await G0(()=>p0(j,{template:v.framework}),{retries:2}),_.succeed("Files are downloaded and extracted successfully!");let L=x$({text:"Installing dependencies..."}).start(),b=i$.sync(["**/styles/theme.css"],{cwd:j,absolute:!0,onlyFiles:!0})[0];if(y0("brand",v.color||"",b??""),await G0(()=>M0(L$(),["install"],{cwd:J}).catch(async(W)=>{if(W.message.includes("peer"))L.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),L.start("Installing dependencies with --legacy-peer-deps flag"),await M0(L$(),["install","--legacy-peer-deps"],{cwd:J})}),{retries:1}),await G0(()=>M0("git",["init"],{cwd:J}),{retries:1}),L.succeed("Dependencies are installed"),!z)console.log(`
64
+ </html>`}}function n0(){return i0().replace("{{TITLE}}","Authentication successful").replace("{{HEADING}}","Authentication successful").replace("{{DESCRIPTION}}","You can now close this tab and return to your terminal.").replace("{{AUTO_CLOSE_SCRIPT}}","<script>setTimeout(() => window.close(), 10000);</script>")}function p$($){return i0().replace("{{TITLE}}","Authentication failed").replace("{{HEADING}}","Authentication failed").replace("{{DESCRIPTION}}",$).replace("{{AUTO_CLOSE_SCRIPT}}","")}var K0=q0.join(Y3.homedir(),".untitledui"),B0=q0.join(K0,"config.json"),o0=new $3().name("login").description("authenticate with Untitled UI to access PRO components").action(async()=>{let $=Z3("Starting authentication...").start();try{await W3($),$.succeed("Authentication completed successfully!"),console.log(H0.green(`
65
+ ✨ You can now access PRO components with the CLI!`)),process.exit(0)}catch(z){$.fail(`Authentication failed: ${z instanceof Error?z.message:z}`),process.exit(1)}});async function W3($){return new Promise((z,Q)=>{let U=z3.createServer((Z,Y)=>{let W=new U3(Z.url,"http://localhost");if(W.pathname==="/callback"){let H=W.searchParams.get("apiKey"),X=W.searchParams.get("error");if(X){Y.writeHead(400,{"Content-Type":"text/html"}),Y.end(p$(decodeURIComponent(X))),U.close(),Q(Error(decodeURIComponent(X)));return}if(!H){Y.writeHead(400,{"Content-Type":"text/html"}),Y.end(p$("No Access Token received")),U.close(),Q(Error("No Access Token received"));return}try{X3(H),Y.writeHead(200,{"Content-Type":"text/html"}),Y.end(n0()),U.close(),z()}catch(G){Y.writeHead(500,{"Content-Type":"text/html"}),Y.end(p$("Failed to save authentication data")),U.close(),Q(G)}}else Y.writeHead(404),Y.end("Not found")});U.listen(0,"localhost",()=>{let W=`https://www.untitledui.com/react/api/cli-auth?port=${U.address().port}`;$.text="Opening browser for authentication...",Q3(W).catch((H)=>{console.log(H0.yellow(`
66
+ Failed to open browser automatically: ${H.message}`)),console.log(H0.cyan(`Please manually open: ${W}
67
+ `))}),$.text="Waiting for authentication in browser..."}),setTimeout(()=>{U.close(),Q(Error("Authentication timeout. Please try again."))},300000)})}function X3($){if(!H$.existsSync(K0))H$.mkdirSync(K0,{recursive:!0});let z={};if(H$.existsSync(B0))try{z=JSON.parse(H$.readFileSync(B0,"utf-8"))}catch{z={}}z.license=$,H$.writeFileSync(B0,JSON.stringify(z,null,2),"utf-8")}import G3 from"async-retry";import I from"chalk";import{Command as M3}from"commander";import*as c from"fs";import v$ from"ora";import*as F from"path";import N$ from"prompts";import{Project as y3}from"ts-morph";import B3 from"node-fetch";async function T$($,z,Q){try{let Z=await B3("https://www.untitledui.com/react/api/components/example",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({example:$,key:z,version:Q})});if(!Z.ok){if(Z.status===401||Z.status===403)return{type:"error",status:Z.status,message:"PRO access required"};return console.error(`API error: ${Z.status} - ${Z.statusText}`),null}return await Z.json()}catch(Z){return console.error(Z),null}}import L0 from"async-retry";import h from"chalk";import{Command as H3}from"commander";import{execa as V0}from"execa";import i$ from"fast-glob";import r from"fs";import x$ from"ora";import*as P from"path";import n$ from"prompts";import{Project as K3}from"ts-morph";import{fileURLToPath as q3}from"url";import*as s$ from"fs";import*as t0 from"path";function J0($,z){let Q=t0.join($,"package.json");if(!s$.existsSync(Q))return z;let U=JSON.parse(s$.readFileSync(Q,"utf-8")),Z={...U.dependencies,...U.devDependencies},Y=[];for(let W of z){let H=Z[W];if(!H){Y.push(W);continue}if(W==="tailwindcss"){let X=H.match(/\d+/);if((X?parseInt(X[0],10):0)<4)Y.push(W)}}return Y}import G0 from"chalk";import*as G$ from"fs";import*as r$ from"path";function M0($){if(!G$.existsSync(r$.resolve($)))console.log(G0.red(`Error: CSS file not found at ${$}`)),process.exit(1);let z=G$.readFileSync(r$.resolve($),"utf-8"),Q=/(--color-[a-zA-Z-]+-\d{1,3}):\s*(rgb\([^)]+\))/g,U={},Z;while((Z=Q.exec(z))!==null)if(Z[1]&&Z[2])U[Z[1]]=Z[2];return U}function y0($,z,Q){let U=r$.resolve(Q);if(!G$.existsSync(U)){console.log(G0.red(`Error: CSS file not found at ${U}`));return}let Z=G$.readFileSync(U,"utf-8"),Y=M0(Q),W={},H={};for(let[G,N]of Object.entries(Y))if(G.startsWith(`--color-${$}-`)){let b=G.replace(`--color-${$}-`,"");W[b]=G}else if(G.startsWith(`--color-${z}-`)){let b=G.replace(`--color-${z}-`,"");H[b]=N}let X=!1;for(let[G,N]of Object.entries(W))if(H[G]){let b=H[G],j=new RegExp(`(${N}):\\s*rgb\\([^)]*\\);?`,"g");if(j.test(Z))Z=Z.replace(j,`$1: ${b};`),X=!0;else console.log(G0.yellow(`No match found for ${N}`))}if(X)G$.writeFileSync(U,Z,"utf-8")}var J3=q3(import.meta.url),e0=P.dirname(J3),z1="vite",Q1="nextjs",$1={[Q1]:"Next.js",[z1]:"Vite"},t="",w={color:"",template:"",framework:void 0,license:q$()},Z1=new H3().name("init").description("initialize a new project or adjust an existing one").argument("[directory]").usage("[directory] [options]").helpOption("-h, --help","display this help message.").option("--vite","initialize a Vite project.",!1).option("--nextjs","initialize a Next.js project.",!1).option("-o, --overwrite","overwrite existing files.",!1).option("--colors-list","show the colors list.",!1).option("-c, --color <color-name>","specify a color for the project.").option("-y, --yes","non-interactive mode - use defaults for all prompts (for AI agents/CI).",!1).option("--license <key>","API key for PRO access (alternative to stored config)").option("--lib-version <version>","component library version (7 or 8)").action(async($,z)=>{if($)t=$;if(z){if(w.color=z.color,w.template=z.template,w.overwrite=z.overwrite,w.colorsList=z.colorsList,w.yes=z.yes,w.license=z.license||w.license,w.version=z.libVersion,w.vite=z.vite,w.nextjs=z.nextjs,z.vite)w.framework=z1;if(z.nextjs)w.framework=Q1}try{await j0(z),process.exit(0)}catch(Q){console.error(h.red(Q)),process.exit(1)}});async function j0($,z=null){if($.yes)w.yes=!0;if($.overwrite)w.overwrite=!0;if($.color)w.color=$.color;let Q=process.cwd(),U=r.existsSync(P.resolve(Q,"package.json")),Z=P.resolve(P.join(e0,"../config/styles","theme.css")),Y=M0(Z??""),W=Array.from(new Set(Object.keys(Y).map((N)=>N?.split("--color-")?.[1]?.replace(/-\d{1,3}/,"")))),H=x$().start(),X=await y$(Q);if(w.license)u$(w.license);if(!U){if(H.stop(),!t){let b=await n$({onState:f,type:"text",name:"path",message:"What is your project named?",initial:"untitled-ui"});if(typeof b.path==="string")t=b.path.trim()}if(z)z.projectPath=t;let N=r.existsSync(P.resolve(P.posix.join(Q,t,"package.json")));if(r.existsSync(P.resolve(P.posix.join(Q,t)))&&N)H.fail(h.red("Directory already exists!")),process.exit(1);if(w.vite&&w.nextjs||!w.framework){let b=await n$({type:"select",name:"framework",onState:f,message:`Which ${h.cyan("framework")} would you like to use?`,choices:Object.entries($1).map(([j,_])=>({title:_,value:j}))});w.framework=b.framework}H.succeed("Framework is selected: "+h.green($1[w.framework]))}else if(X?.framework==="other")H.fail("Unsupported project framework"),console.log(`Please refer to the documentation ${h.cyan("https://www.untitledui.com/docs")} for supported frameworks or proceed with manual installation.`),process.exit(1);else if(X?.framework.startsWith("next")||X?.framework.startsWith("vite"))if(!z&&!X.tailwind.brandColor)H.succeed(h.yellow(`Detected ${g0[X.framework]} project, proceeding with the setup...`));else H.stop();if(w.colorsList||!w.color&&!X?.tailwind.brandColor)if($.yes){if(w.color=$.color??X?.tailwind.brandColor??"brand",w.colorsList&&X)X.tailwind.brandColor=w.color}else{let N=await n$({type:"select",name:"color",onState:f,initial:$.color??"",message:`Which ${h.cyan("color")} would you like to use as the ${h.cyanBright("brand")} color?`,choices:W.map((b)=>({title:b,value:b}))});if(w.color=N.color,w.colorsList&&X)X.tailwind.brandColor=N.color}let G=P.posix.join(Q,t||"");if(t&&!U){let N=P.resolve(t);console.log(`
68
+ Creating a new project in ${h.blue(t)}`);let b=x$("Downloading and extracting the repository...").start();try{r.mkdirSync(N,{recursive:!0}),await L0(()=>p0(N,{template:w.framework}),{retries:2}),b.succeed("Files are downloaded and extracted successfully!");let j=x$({text:"Installing dependencies..."}).start(),_=i$.sync(["**/styles/theme.css"],{cwd:N,absolute:!0,onlyFiles:!0})[0];if(y0("brand",w.color||"",_??""),await L0(()=>V0(L$(),["install"],{cwd:G}).catch(async(B)=>{if(B.message.includes("peer"))j.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),j.start("Installing dependencies with --legacy-peer-deps flag"),await V0(L$(),["install","--legacy-peer-deps"],{cwd:G})}),{retries:1}),await L0(()=>V0("git",["init"],{cwd:G}),{retries:1}),j.succeed("Dependencies are installed"),!z)console.log(`
69
69
  Your project is ready, to get started run the following commands:
70
70
 
71
- cd ${h.cyan(o)}
72
- ${h.cyan(m0())}`)}catch(L){if(_.fail(h.red(`
73
- Failed to download and extract the repository`)),L instanceof Error)console.error(L.message);else console.error(`
74
- `);r.rmdirSync(j,{recursive:!0}),process.exit(1)}}else{let j=x$(),_=new Set,L=B?.examples||"",b=I$(Q,L),W=u.resolve(u.join(t0,"../config")),V=A$(Q,v.version)==="7"?u.join(W,"v7"):W,w=i$.sync(["styles/**"],{cwd:V,onlyFiles:!0});w.push(...i$.sync(["postcss.config.*"],{cwd:W,onlyFiles:!0}));let T=K0(Q,["tailwindcss","tailwindcss-animate","@tailwindcss/typography","tailwindcss-react-aria-components"]),E=B?.framework==="vite",C=E?[]:K0(Q,["@tailwindcss/postcss","postcss"]);if(!z&&!B?.tailwind.brandColor)j.start("Copying files to the project directory");if(w.forEach((R)=>{let q=R.includes("postcss.config");if(q&&E)return;let K=u.posix.join(q?W:V,R),M=u.posix.join(Q,q?R:c$(R,B?.paths,B?.isSrcDir));if(r.existsSync(M)){if(v?.overwrite)r.copyFileSync(K,M);else{let A=r.readFileSync(M,"utf-8"),x=r.readFileSync(K,"utf-8");if(A!==x){if(R.endsWith("theme.css")&&B?.tailwind.brandColor)return;_.add({targetFile:M,sourceFile:K})}}return}r.mkdirSync(u.dirname(M),{recursive:!0}),r.writeFileSync(M,""),r.copyFileSync(K,M)}),j.stop(),_.size&&!v?.overwrite){if(console.log(`
75
- `),j.fail("Following files already exist in the directory."),_.forEach((q)=>{console.log(`- ${h.green(q.targetFile)}`)}),(await n$({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let q=x$("Overwriting files").start();_.forEach((K)=>{r.copyFileSync(K.sourceFile,K.targetFile)}),q.succeed("Files are overwritten")}}if(b?.tailwindFile)console.log(`
71
+ cd ${h.cyan(t)}
72
+ ${h.cyan(c0())}`)}catch(j){if(b.fail(h.red(`
73
+ Failed to download and extract the repository`)),j instanceof Error)console.error(j.message);else console.error(`
74
+ `);r.rmSync(N,{recursive:!0,force:!0}),process.exit(1)}}else{let N=x$(),b=new Set,j=X?.examples||"",_=I$(Q,j),B=P.resolve(P.join(e0,"../config")),M=A$(Q,w.version)==="7"?P.join(B,"v7"):B,v=i$.sync(["styles/**"],{cwd:M,onlyFiles:!0});v.push(...i$.sync(["postcss.config.*"],{cwd:B,onlyFiles:!0}));let R=J0(Q,["tailwindcss","tailwindcss-animate","@tailwindcss/typography","tailwindcss-react-aria-components"]),E=X?.framework==="vite",T=E?[]:J0(Q,["@tailwindcss/postcss","postcss"]);if(!z&&!X?.tailwind.brandColor)N.start("Copying files to the project directory");if(v.forEach((S)=>{let J=S.includes("postcss.config");if(J&&E)return;let q=P.posix.join(J?B:M,S),L=P.posix.join(Q,J?S:c$(S,X?.paths,X?.isSrcDir));if(r.existsSync(L)){if(w?.overwrite)r.copyFileSync(q,L);else{let A=r.readFileSync(L,"utf-8"),x=r.readFileSync(q,"utf-8");if(A!==x){if(S.endsWith("theme.css")&&X?.tailwind.brandColor)return;b.add({targetFile:L,sourceFile:q})}}return}r.mkdirSync(P.dirname(L),{recursive:!0}),r.writeFileSync(L,""),r.copyFileSync(q,L)}),N.stop(),b.size&&!w?.overwrite&&!w?.yes){if(console.log(`
75
+ `),N.fail("Following files already exist in the directory."),b.forEach((J)=>{console.log(`- ${h.green(J.targetFile)}`)}),(await n$({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let J=x$("Overwriting files").start();b.forEach((q)=>{r.copyFileSync(q.sourceFile,q.targetFile)}),J.succeed("Files are overwritten")}}if(_?.tailwindFile)console.log(`
76
76
  Tailwind config file exists in the project directory. You can add it to your globals.css as follows:`),console.log(`
77
- ${h.cyan(`@config "../${B?.isSrcDir?"../":""}${u.relative(Q,b.tailwindFile)}";`)}
78
- `);if(B?.framework==="vite"){if(!h0(Q))console.log(`
77
+ ${h.cyan(`@config "../${X?.isSrcDir?"../":""}${P.relative(Q,_.tailwindFile)}";`)}
78
+ `);if(X?.framework==="vite"){if(!m0(Q))console.log(`
79
79
  Tailwind CSS is not configured in your Vite project. Please refer to the documentation ${h.cyan("https://www.untitledui.com/react/integrations/vite")} for manual installation.
80
- `)}let d=b?.layoutFile||b?.appFile||B?.framework==="vite"&&b?.mainFile||"";if(d){let q=new H3({tsConfigFilePath:u.resolve(b?.tsConfig||"")}).addSourceFileAtPath(u.resolve(d)),K="styles/globals.css";if(!q.getImportDeclarations().some((A)=>{let x=A.getModuleSpecifierValue();return/(?:styles\/)?globals\.css$/.test(x)})){let A=B?.aliases?.styles||B?.aliases?.src||"",x=B?.aliases?.styles?`${A}globals.css`:`${A}styles/globals.css`;q.addImportDeclaration({moduleSpecifier:x})}q.saveSync()}let F=i$.sync(["**/theme.css"],{cwd:Q,absolute:!0,onlyFiles:!0,ignore:a});if(!F?.length)return j.fail(`Failed to copy ${h.cyan("theme.css")} file.
81
- Ensure that the ${h.cyan("theme.css")} file exists in the project directory under your ${h.yellow("styles")} folder.`);if((v.color||!B?.tailwind.brandColor)&&y0("brand",v.color||"brand",F[0]??""),T.length||C.length){let R=x$().start("Installing dependencies");if(T.length)await B$(T,{cwd:J,spinner:R,label:"dependencies"});if(C.length)await B$(C,{cwd:J,dev:!0,spinner:R,label:"devDependencies"});R.succeed("Dependencies are installed")}if(!z&&!B?.tailwind.brandColor)j.succeed(h.green("Project setup is completed!"));if(z&&U){H.stop(),j.stop();return}else console.log(`
82
- Your project is ready, you can now start adding components.`)}}var G={path:"",example:"",license:q$(),components:[]},V0={},Z1=new y3().name("example").description("add an example to the project").argument("[example]","the example to add").option("-o, --overwrite","overwrite existing files.",!1).option("-p, --path <path>","the path to add the components to.").option("-e, --example-path <example-path>","the path to add the example file to.").option("--include-all-components","automatically include all components from the example without prompting.",!1).option("-y, --yes","non-interactive mode - use defaults for all prompts (for AI agents/CI).",!1).option("--license <key>","API key for PRO access (alternative to stored config)").option("--lib-version <version>","component library version (7 or 8)").action(async($,z)=>{if($)G.example=$;if(z){if(G.path=z.path,G.overwrite=z.overwrite,G.examplePath=z.examplePath,G.includeAllComponents=z.includeAllComponents,G.yes=z.yes,G.license=z.license||G.license,G.version=z.libVersion,z.yes)G.includeAllComponents=!0,G.overwrite=!0}try{await L0(z,V0),await M3()}catch(Q){console.error(I.red(Q))}});async function M3(){let $=v$().start(),z=S.posix.join(process.cwd(),V0?.projectPath||"");if(!c.existsSync(S.posix.join(S.resolve(z,"package.json"))))$.warn("This command should be run in a project directory."),process.exit(1);let U=A$(z,G.version),Z=await M$(z);if(G.license)await l$(G.license,$);if($.stop(),!G.example){if(G.yes)console.error(I.red("Error: Example name is required in non-interactive mode.")),console.log(`Usage: ${I.cyan("npx untitledui example <example-name> --yes")}`),console.log(`Example: ${I.cyan("npx untitledui example dashboards-01/01 --yes")}`),process.exit(1);let W=await N$({type:"select",name:"example",onState:f,message:"Select which type of example you want to add",choices:[{title:"Application",value:"application"},{title:"Marketing",value:"marketing"}]});G.example=W.example}let Y=null;if(G.example){let W=await T$(G.example,G.license,U);if(W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(I.yellow(`\uD83D\uDD12 The ${I.cyan(G.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${I.green("→")} If you've already purchased: ${I.cyan(`${X$()} untitledui@latest login`)}`),console.log(` ${I.green("→")} To purchase PRO examples: ${I.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1);if(W?.type==="directory"){if(G.yes)if(W.results.length>0)G.example=W.results[0]||"",console.log(I.yellow(`Auto-selecting: ${G.example}`)),W=await T$(G.example,G.license,U);else console.error(I.red("Error: No examples found in directory.")),process.exit(1);else{let y=await N$({type:"select",name:"example",onState:f,message:`Select a folder or file in "${G.example}"`,choices:W.results.map((V)=>({title:V,value:V}))});if(!y.example)return;G.example=y.example,W=await T$(y.example,G.license,U)}if(W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(I.yellow(`\uD83D\uDD12 The ${I.cyan(G.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${I.green("→")} If you've already purchased: ${I.cyan(`${X$()} untitledui@latest login`)}`),console.log(` ${I.green("→")} To purchase PRO examples: ${I.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(W?.type==="json-files"){if(G.yes)if(W.results.length>0)G.example=`${G.example}/${W.results[0]}`,console.log(I.yellow(`Auto-selecting: ${G.example}`)),W=await T$(G.example,G.license,U);else console.error(I.red("Error: No example files found.")),process.exit(1);else{let y=await N$({type:"select",name:"example",onState:f,message:`Select which example you want to add from "${G.example}"`,choices:W.results.map((V)=>({title:V,value:`${G.example}/${V}`}))});if(!y.example)return;G.example=y.example,W=await T$(y.example,G.license,U)}if(W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(I.yellow(`\uD83D\uDD12 The ${I.cyan(G.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${I.green("→")} If you've already purchased: ${I.cyan(`${X$()} untitledui@latest login`)}`),console.log(` ${I.green("→")} To purchase PRO examples: ${I.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(W?.type==="json-file")Y=W.content}if(!Y)$.fail("No example found"),process.exit(1);let X=Z?.examples||"";if(X){let W=await M$(S.posix.join(z,X));if(W)Z={...W,aliases:Z?.aliases||{}};G.examplePath=X}if(!G?.examplePath){let W=Z?.isAppDir?"app":"pages",y=Z?.isSrcDir?S.posix.join("src",W):W;if(G.yes)G.examplePath=y,console.log(I.yellow(`Using default example path: ${y}`));else{let V=await N$({type:"text",name:"examplePath",onState:f,message:`Where would you like to add the ${I.cyan(G?.example)} example?`,initial:y});G.examplePath=V.examplePath}}if(G.examplePath&&!c.existsSync(S.posix.join(z,G.examplePath)))c.mkdirSync(S.posix.join(z,G.examplePath),{recursive:!0}),console.log(I.green(`Created directory ${G.examplePath}`));if(!G?.path&&!Z?.paths?.components)if(G.yes)G.path="components",console.log(I.yellow("Using default components path: components"));else{let W=await N$({type:"text",name:"path",onState:f,message:`Where would you like to add the ${I.cyan("components")}?`,initial:"components"});G.path=W.path}if(G?.path&&Z?.paths&&!Z.paths.components)Z.paths.components=S.posix.join(Z?.isSrcDir?"src":"",G.path);if(!G?.path&&Z?.paths?.components)G.path=Z.paths.components.replace(/^src\//,"");let H=Y.components.filter((W)=>!c.existsSync(S.posix.join(z,`${Z?.isSrcDir?"src":""}`,W?.path?.replace(/components\//,G.path+"/"))));if(H?.length)if(G.includeAllComponents)G.components=H.map((W)=>W.name);else{let W=await N$({type:"multiselect",name:"components",onState:f,message:`Select which components you want to add from ${I.cyan(Y.name)} example`,choices:H.map((y)=>({title:y?.name,value:y?.name,selected:!0})),instructions:!1,hint:"- Space to select. Return to submit"});if(G.components=W.components,!H.length&&!W.components?.length)$.warn("No components selected")}let B=I$(z),J=new Set,j=new G3({tsConfigFilePath:B?.tsConfig}),_=v$(`Adding ${G?.example}...`).start(),L="",b=new Set(Y.components.filter((W)=>G.components?.includes(W.name)).map((W)=>S.dirname(W.path)));try{for(let{path:W,code:y}of Y.files||[]){let V=S.dirname(W);if(Array.from(b).some((F)=>V===F||V.startsWith(F+"/")))continue;let T=S.posix.join(z,`${Z?.isSrcDir?"src":""}`,W.replace(/components\//,G.path+"/")),E=Z?.framework==="vite"?y.replace(`"use client";
83
-
84
- `,""):y,C=m$(E);if(W.includes("examples")){let F=S.basename(W);T=S.posix.join(z,G?.examplePath??"",F),L=S.posix.join(G?.examplePath??"",F)}let d=S.dirname(T);if(c.existsSync(T)&&!G.overwrite){if(c.readFileSync(T,"utf-8")!==C)J.add({code:C,path:T})}else{let F=d.split(S.sep),R="";for(let K of F)if(R=R?S.join(R,K):K,R&&c.existsSync(R)&&c.statSync(R).isFile())throw Error(`Cannot create directory '${d}' because '${R}' is an existing file.
85
- Please check your path aliases in components.json and tsconfig.json.`);c.mkdirSync(d,{recursive:!0}),c.writeFileSync(T,C);let q=j.getSourceFile(S.resolve(T));if(q)q.replaceWithText(C);else q=j.addSourceFileAtPath(S.resolve(T));q.getImportDeclarations().forEach((K)=>{let M=K.getModuleSpecifierValue();K.setModuleSpecifier(E$(M,G.path,Z?.aliases))}),await q.save()}}if(J.size)_.warn(`Some files of ${I.yellow(G?.example)} already exist`);else _.succeed(`${I.green(G?.example)} is added successfully`)}catch(W){_.fail(`
86
- Failed to add the component ${I.red(G?.example)}`),console.error(I.red(W)),process.exit(1)}if(J.size&&!G?.overwrite){console.log(`
87
- Following files already exist in the directory.`),J.forEach((y)=>{console.log(I.green(`- ${S.relative(z,y.path)}`))});let W=!1;if(G.yes)W=!0,console.log(I.yellow("Auto-overwriting existing files (--yes mode)"));else{let y=await N$({type:"confirm",name:"overwrite",onState:f,message:"Do you want to overwrite the existing files?",initial:!0});if(y.overwrite===void 0)console.log(`
88
- Use ${I.cyan("--overwrite")} or ${I.cyan("-o")} flag to overwrite existing files, or run with ${I.cyan("node")} instead of ${I.cyan("bun")}.`),process.exit(1);W=y.overwrite}if(W){let y=v$("Overwriting files").start();J.forEach((V)=>{let w=j.addSourceFileAtPath(S.resolve(V.path));w.replaceWithText(V.code),w.getImportDeclarations().forEach((T)=>{let E=T.getModuleSpecifierValue();T.setModuleSpecifier(E$(E,G.path,Z?.aliases))}),w.saveSync()}),y.succeed("Files are overwritten")}}if(Y?.dependencies?.length){let W=v$().start();await B$(Y.dependencies,{cwd:z,spinner:W,label:"example dependencies"})}if(Y?.devDependencies?.length){let W=v$().start();await B$(Y.devDependencies,{cwd:z,dev:!0,spinner:W,label:"example devDependencies"})}if(G?.components?.length)await J3(()=>Y0({components:G.components,dir:V0?.projectPath||"",path:G.path,license:G.license,message:""}),{retries:1});console.log(`
89
- \uD83C\uDF89 Example ${I.green(G.example)} has been added to ${I.green(L)}`),process.exit(0)}import P from"chalk";import{Command as L3}from"commander";import W1 from"fast-glob";import _$ from"fs";import Y1 from"ora";import C$ from"path";import V3 from"prompts";var j3={ArrowRight:"ArrowNext",ArrowLeft:"ArrowPrevious",ChevronRight:"ChevronNext",ChevronLeft:"ChevronPrevious",ChevronRightDouble:"ChevronNextDouble",ChevronLeftDouble:"ChevronPreviousDouble"},N3=[{pattern:/\bml-/g,replace:"ms-",description:"ml- → ms-"},{pattern:/\bmr-/g,replace:"me-",description:"mr- → me-"},{pattern:/\bpl-/g,replace:"ps-",description:"pl- → ps-"},{pattern:/\bpr-/g,replace:"pe-",description:"pr- → pe-"},{pattern:/(?<!from-|to-|placement-)(?<!\bin-placement-)\bleft-/g,replace:"start-",description:"left- → start-"},{pattern:/(?<!from-|to-|placement-)(?<!\bin-placement-)\bright-/g,replace:"end-",description:"right- → end-"},{pattern:/\brounded-l-/g,replace:"rounded-s-",description:"rounded-l- → rounded-s-"},{pattern:/\brounded-r-/g,replace:"rounded-e-",description:"rounded-r- → rounded-e-"},{pattern:/\brounded-tl-/g,replace:"rounded-ss-",description:"rounded-tl- → rounded-ss-"},{pattern:/\brounded-tr-/g,replace:"rounded-se-",description:"rounded-tr- → rounded-se-"},{pattern:/\brounded-bl-/g,replace:"rounded-es-",description:"rounded-bl- → rounded-es-"},{pattern:/\brounded-br-/g,replace:"rounded-ee-",description:"rounded-br- → rounded-ee-"},{pattern:/\bborder-l-/g,replace:"border-s-",description:"border-l- → border-s-"},{pattern:/\bborder-r-/g,replace:"border-e-",description:"border-r- → border-e-"},{pattern:/\bborder-l\b/g,replace:"border-s",description:"border-l → border-s"},{pattern:/\bborder-r\b/g,replace:"border-e",description:"border-r → border-e"},{pattern:/\btext-left\b/g,replace:"text-start",description:"text-left → text-start"},{pattern:/\btext-right\b/g,replace:"text-end",description:"text-right → text-end"},{pattern:/\bfloat-left\b/g,replace:"float-start",description:"float-left → float-start"},{pattern:/\bfloat-right\b/g,replace:"float-end",description:"float-right → float-end"},{pattern:/\bclear-left\b/g,replace:"clear-start",description:"clear-left → clear-start"},{pattern:/\bclear-right\b/g,replace:"clear-end",description:"clear-right → clear-end"},{pattern:/\bscroll-ml-/g,replace:"scroll-ms-",description:"scroll-ml- → scroll-ms-"},{pattern:/\bscroll-mr-/g,replace:"scroll-me-",description:"scroll-mr- → scroll-me-"},{pattern:/\bscroll-pl-/g,replace:"scroll-ps-",description:"scroll-pl- → scroll-ps-"},{pattern:/\bscroll-pr-/g,replace:"scroll-pe-",description:"scroll-pr- → scroll-pe-"}],G$="(?:(sm|md|lg|xl|2xl):)?";function b$($,z){let Q=$.match(/^(sm|md|lg|xl|2xl):/);return Q?`${$} ${Q[1]}:rtl:${z}`:`${$} rtl:${z}`}var b3=[{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-in-from-right(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-in-from-left)/g,replace:($)=>`${$} rtl:slide-in-from-left${$.replace("slide-in-from-right","")}`,description:"slide-in-from-right + rtl:slide-in-from-left",needsReview:!0},{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-in-from-left(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-in-from-right)/g,replace:($)=>`${$} rtl:slide-in-from-right${$.replace("slide-in-from-left","")}`,description:"slide-in-from-left + rtl:slide-in-from-right",needsReview:!0},{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-out-to-right(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-out-to-left)/g,replace:($)=>`${$} rtl:slide-out-to-left${$.replace("slide-out-to-right","")}`,description:"slide-out-to-right + rtl:slide-out-to-left",needsReview:!0},{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-out-to-left(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-out-to-right)/g,replace:($)=>`${$} rtl:slide-out-to-right${$.replace("slide-out-to-left","")}`,description:"slide-out-to-left + rtl:slide-out-to-right",needsReview:!0},{pattern:new RegExp(`(?<![-:])${G$}translate-x-([\\d./]+(?=\\s|$|")|full|px|\\[\\S+\\])(?!\\s+rtl:)`,"g"),replace:($)=>b$($,`-${$.replace(/^(sm|md|lg|xl|2xl):/,"")}`),description:"translate-x + rtl:-translate-x",needsReview:!0},{pattern:new RegExp(`(?<=^|\\s|")${G$}-translate-x-([\\d./]+(?=\\s|$|")|full|px|\\[\\S+\\])(?!\\s+rtl:)`,"g"),replace:($)=>{let z=$.match(/^(sm|md|lg|xl|2xl):/),Q=$.slice($.indexOf("-translate-x-")+13);return z?`${$} ${z[1]}:rtl:translate-x-${Q}`:`${$} rtl:translate-x-${Q}`},description:"-translate-x + rtl:translate-x",needsReview:!0},{pattern:new RegExp(`\\b${G$}space-x-(\\d+(?:\\.\\d+)?|\\[\\S+\\])(?!\\s+(?:sm:|md:|lg:|xl:|2xl:)?rtl:space-x-reverse)`,"g"),replace:($)=>b$($,"space-x-reverse"),description:"space-x + rtl:space-x-reverse",needsReview:!0},{pattern:new RegExp(`\\b${G$}divide-x(?:-(\\d+(?:\\.\\d+)?|\\[\\S+\\]))?(?!\\s+(?:sm:|md:|lg:|xl:|2xl:)?rtl:divide-x-reverse)`,"g"),replace:($)=>b$($,"divide-x-reverse"),description:"divide-x + rtl:divide-x-reverse",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${G$}bg-linear-to-r\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-linear-to-l)`,"g"),replace:($)=>b$($,"bg-linear-to-l"),description:"bg-linear-to-r + rtl:bg-linear-to-l",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${G$}bg-linear-to-l\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-linear-to-r)`,"g"),replace:($)=>b$($,"bg-linear-to-r"),description:"bg-linear-to-l + rtl:bg-linear-to-r",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${G$}bg-gradient-to-r\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-gradient-to-l)`,"g"),replace:($)=>b$($,"bg-gradient-to-l"),description:"bg-gradient-to-r + rtl:bg-gradient-to-l",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${G$}bg-gradient-to-l\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-gradient-to-r)`,"g"),replace:($)=>b$($,"bg-gradient-to-r"),description:"bg-gradient-to-l + rtl:bg-gradient-to-r",needsReview:!0}],_3=/\bleft-1\/2\b.*-translate-x-1\/2|-translate-x-1\/2.*\bleft-1\/2\b/,X1=/\b(ml-|mr-|pl-|pr-|left-|right-|rounded-[lr]-|rounded-t[lr]-|rounded-b[lr]-|border-[lr]|text-left|text-right|float-left|float-right|scroll-m[lr]-|scroll-p[lr]-|translate-x-|space-x-|divide-x|bg-linear-to-[lr]|bg-gradient-to-[lr]|slide-in-from-(?:left|right)|slide-out-to-(?:left|right))/;function B1($,z){let Q=$;for(let U of z)Q=Q.replace(U.pattern,U.replace);return Q}function A3($,z,Q){let U={file:$,changes:[]},Z=z.split(`
90
- `);for(let Y=0;Y<Z.length;Y++){let X=Z[Y];if(/^\s*(import\b|export\b.*from\b)/.test(X)||/\brequire\s*\(/.test(X))continue;if(_3.test(X))continue;let H=X,B=!1;if(H=H.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(J,j,_,L,b)=>{let W=j??_??L??b;if(W==null||!X1.test(W))return J;let y=B1(W,Q);if(y!==W)return B=!0,J.replace(W,y);return J}),B&&H!==X)Z[Y]=H,U.changes.push({line:Y+1,before:X.trim(),after:H.trim()})}return U}function D3($){let z=0,Q=$;for(let[U,Z]of Object.entries(j3)){let Y=new RegExp(`\\b${U}\\b`,"g"),X=Q;if(Q=Q.replace(Y,Z),Q!==X)z+=(X.match(Y)||[]).length}return{content:Q,swaps:z}}async function I3($){let z=C$.resolve($);return W1(["**/*.tsx","**/*.ts"],{cwd:z,absolute:!0,ignore:["**/node_modules/**","**/*.story.tsx","**/*.demo.tsx","**/*.test.tsx"]})}var H1="[data-rtl-flip]:dir(rtl) { transform: scaleX(-1); }";function U1($){let z=["global.css","globals.css","styles/global.css","styles/globals.css","src/global.css","src/globals.css","src/styles/global.css","src/styles/globals.css","app/global.css","app/globals.css"];for(let U of z){let Z=C$.resolve($,U);if(_$.existsSync(Z))return Z}let Q=W1.sync(["**/*.css"],{cwd:$,absolute:!0,ignore:["**/node_modules/**","**/dist/**","**/build/**","**/.next/**"]});for(let U of Q){let Z=_$.readFileSync(U,"utf-8");if(Z.includes("@import")&&Z.includes("tailwindcss"))return U}return Q[0]||null}function E3($,z){let Q=_$.readFileSync($,"utf-8");if(Q.includes("data-rtl-flip"))return!1;let U=Q.trimEnd()+`
91
-
92
- `+H1+`
93
- `;if(!z)_$.writeFileSync($,U);return!0}var K1=new L3().name("migrate").description("migrate components for RTL support").argument("[path]","path to migrate (defaults to current directory)").option("--dry-run","preview changes without writing files",!1).option("--skip-icons","skip directional icon swapping",!1).option("-y, --yes","skip prompts and use defaults",!1).action(async($,z)=>{console.log(P.bold(`
80
+ `)}let C=_?.layoutFile||_?.appFile||X?.framework==="vite"&&_?.mainFile||"";if(C){let J=new K3({tsConfigFilePath:P.resolve(_?.tsConfig||"")}).addSourceFileAtPath(P.resolve(C)),q="styles/globals.css";if(!J.getImportDeclarations().some((A)=>{let x=A.getModuleSpecifierValue();return/(?:styles\/)?globals\.css$/.test(x)})){let A=X?.aliases?.styles||X?.aliases?.src||"",x=X?.aliases?.styles?`${A}globals.css`:`${A}styles/globals.css`;J.addImportDeclaration({moduleSpecifier:x})}J.saveSync()}let O=i$.sync(["**/theme.css"],{cwd:Q,absolute:!0,onlyFiles:!0,ignore:p});if(!O?.length)return N.fail(`Failed to copy ${h.cyan("theme.css")} file.
81
+ Ensure that the ${h.cyan("theme.css")} file exists in the project directory under your ${h.yellow("styles")} folder.`);if((w.color||!X?.tailwind.brandColor)&&y0("brand",w.color||"brand",O[0]??""),R.length||T.length){let S=x$().start("Installing dependencies");if(R.length)await X$(R,{cwd:G,spinner:S,label:"dependencies"});if(T.length)await X$(T,{cwd:G,dev:!0,spinner:S,label:"devDependencies"});S.succeed("Dependencies are installed")}if(!z&&!X?.tailwind.brandColor)N.succeed(h.green("Project setup is completed!"));if(z&&U){H.stop(),N.stop();return}else console.log(`
82
+ Your project is ready, you can now start adding components.`)}}var y={path:"",example:"",license:q$(),components:[]},N0={},Y1=new M3().name("example").description("add an example to the project").argument("[example]","the example to add").option("-o, --overwrite","overwrite existing files.",!1).option("-p, --path <path>","the path to add the components to.").option("-e, --example-path <example-path>","the path to add the example file to.").option("--include-all-components","automatically include all components from the example without prompting.",!1).option("-y, --yes","non-interactive mode - use defaults for all prompts (for AI agents/CI).",!1).option("-c, --color <color-name>","specify a color for the project (passed through to init).").option("--license <key>","API key for PRO access (alternative to stored config)").option("--lib-version <version>","component library version (7 or 8)").action(async($,z)=>{if($)y.example=$;if(z){if(y.path=z.path,y.overwrite=z.overwrite,y.examplePath=z.examplePath,y.includeAllComponents=z.includeAllComponents,y.yes=z.yes,y.color=z.color,y.license=z.license||y.license,y.version=z.libVersion,z.yes)y.includeAllComponents=!0,y.overwrite=!0}try{await j0(z,N0),await L3()}catch(Q){console.error(I.red(Q))}});async function L3(){let $=v$().start(),z=F.posix.join(process.cwd(),N0?.projectPath||"");if(!c.existsSync(F.posix.join(F.resolve(z,"package.json"))))$.warn("This command should be run in a project directory."),process.exit(1);let U=A$(z,y.version),Z=await y$(z);if(y.license)await l$(y.license,$);if($.stop(),!y.example){if(y.yes)console.error(I.red("Error: Example name is required in non-interactive mode.")),console.log(`Usage: ${I.cyan("npx untitledui example <example-name> --yes")}`),console.log(`Example: ${I.cyan("npx untitledui example dashboards-01/01 --yes")}`),process.exit(1);let B=await N$({type:"select",name:"example",onState:f,message:"Select which type of example you want to add",choices:[{title:"Application",value:"application"},{title:"Marketing",value:"marketing"}]});y.example=B.example}let Y=null;if(y.example){let B=await T$(y.example,y.license,U);if(B?.type==="error"&&(B.status===401||B.status===403))console.log(),console.log(I.yellow(`\uD83D\uDD12 The ${I.cyan(y.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${I.green("→")} If you've already purchased: ${I.cyan(`${W$()} untitledui@latest login`)}`),console.log(` ${I.green("→")} To purchase PRO examples: ${I.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1);if(B?.type==="directory"){if(y.yes)if(B.results.length>0)y.example=B.results[0]||"",console.log(I.yellow(`Auto-selecting: ${y.example}`)),B=await T$(y.example,y.license,U);else console.error(I.red("Error: No examples found in directory.")),process.exit(1);else{let K=await N$({type:"select",name:"example",onState:f,message:`Select a folder or file in "${y.example}"`,choices:B.results.map((M)=>({title:M,value:M}))});if(!K.example)return;y.example=K.example,B=await T$(K.example,y.license,U)}if(B?.type==="error"&&(B.status===401||B.status===403))console.log(),console.log(I.yellow(`\uD83D\uDD12 The ${I.cyan(y.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${I.green("→")} If you've already purchased: ${I.cyan(`${W$()} untitledui@latest login`)}`),console.log(` ${I.green("→")} To purchase PRO examples: ${I.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(B?.type==="json-files"){if(y.yes)if(B.results.length>0)y.example=`${y.example}/${B.results[0]}`,console.log(I.yellow(`Auto-selecting: ${y.example}`)),B=await T$(y.example,y.license,U);else console.error(I.red("Error: No example files found.")),process.exit(1);else{let K=await N$({type:"select",name:"example",onState:f,message:`Select which example you want to add from "${y.example}"`,choices:B.results.map((M)=>({title:M,value:`${y.example}/${M}`}))});if(!K.example)return;y.example=K.example,B=await T$(K.example,y.license,U)}if(B?.type==="error"&&(B.status===401||B.status===403))console.log(),console.log(I.yellow(`\uD83D\uDD12 The ${I.cyan(y.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${I.green("→")} If you've already purchased: ${I.cyan(`${W$()} untitledui@latest login`)}`),console.log(` ${I.green("→")} To purchase PRO examples: ${I.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(B?.type==="json-file")Y=B.content}if(!Y)$.fail("No example found"),process.exit(1);let W=Z?.examples||"";if(W){let B=await y$(F.posix.join(z,W));if(B)Z={...B,aliases:Z?.aliases||{}};y.examplePath=W}if(!y?.examplePath){let B=Z?.isAppDir?"app":"pages",K=Z?.isSrcDir?F.posix.join("src",B):B;if(y.yes)y.examplePath=K,console.log(I.yellow(`Using default example path: ${K}`));else{let M=await N$({type:"text",name:"examplePath",onState:f,message:`Where would you like to add the ${I.cyan(y?.example)} example?`,initial:K});y.examplePath=M.examplePath}}if(y.examplePath&&!c.existsSync(F.posix.join(z,y.examplePath)))c.mkdirSync(F.posix.join(z,y.examplePath),{recursive:!0}),console.log(I.green(`Created directory ${y.examplePath}`));if(!y?.path&&!Z?.paths?.components)if(y.yes)y.path="components",console.log(I.yellow("Using default components path: components"));else{let B=await N$({type:"text",name:"path",onState:f,message:`Where would you like to add the ${I.cyan("components")}?`,initial:"components"});y.path=B.path}if(y?.path&&Z?.paths&&!Z.paths.components)Z.paths.components=F.posix.join(Z?.isSrcDir?"src":"",y.path);if(!y?.path&&Z?.paths?.components)y.path=Z.paths.components.replace(/^src\//,"");let H=Y.components.filter((B)=>!c.existsSync(F.posix.join(z,`${Z?.isSrcDir?"src":""}`,B?.path?.replace(/components\//,y.path+"/"))));if(H?.length)if(y.includeAllComponents)y.components=H.map((B)=>B.name);else{let B=await N$({type:"multiselect",name:"components",onState:f,message:`Select which components you want to add from ${I.cyan(Y.name)} example`,choices:H.map((K)=>({title:K?.name,value:K?.name,selected:!0})),instructions:!1,hint:"- Space to select. Return to submit"});if(y.components=B.components,!H.length&&!B.components?.length)$.warn("No components selected")}let X=I$(z),G=new Set,N=new y3({tsConfigFilePath:X?.tsConfig}),b=v$(`Adding ${y?.example}...`).start(),j="",_=new Set(Y.components.filter((B)=>y.components?.includes(B.name)).map((B)=>F.dirname(B.path)));try{for(let{path:B,code:K}of Y.files||[]){let M=F.dirname(B);if(Array.from(_).some((O)=>M===O||M.startsWith(O+"/")))continue;let R=F.posix.join(z,`${Z?.isSrcDir?"src":""}`,B.replace(/components\//,y.path+"/")),E=Z?.framework==="vite"?K.replace(`"use client";
83
+
84
+ `,""):K,T=m$(E);if(B.includes("examples")){let O=F.basename(B);R=F.posix.join(z,y?.examplePath??"",O),j=F.posix.join(y?.examplePath??"",O)}let C=F.dirname(R);if(c.existsSync(R)&&!y.overwrite){if(c.readFileSync(R,"utf-8")!==T)G.add({code:T,path:R})}else{let O=C.split(F.sep),S="";for(let q of O)if(S=S?F.join(S,q):q,S&&c.existsSync(S)&&c.statSync(S).isFile())throw Error(`Cannot create directory '${C}' because '${S}' is an existing file.
85
+ Please check your path aliases in components.json and tsconfig.json.`);c.mkdirSync(C,{recursive:!0}),c.writeFileSync(R,T);let J=N.getSourceFile(F.resolve(R));if(J)J.replaceWithText(T);else J=N.addSourceFileAtPath(F.resolve(R));J.getImportDeclarations().forEach((q)=>{let L=q.getModuleSpecifierValue();q.setModuleSpecifier(E$(L,y.path,Z?.aliases))}),await J.save()}}if(G.size)b.warn(`Some files of ${I.yellow(y?.example)} already exist`);else b.succeed(`${I.green(y?.example)} is added successfully`)}catch(B){b.fail(`
86
+ Failed to add the component ${I.red(y?.example)}`),console.error(I.red(B)),process.exit(1)}if(G.size&&!y?.overwrite){console.log(`
87
+ Following files already exist in the directory.`),G.forEach((K)=>{console.log(I.green(`- ${F.relative(z,K.path)}`))});let B=!1;if(y.yes)B=!0,console.log(I.yellow("Auto-overwriting existing files (--yes mode)"));else{let K=await N$({type:"confirm",name:"overwrite",onState:f,message:"Do you want to overwrite the existing files?",initial:!0});if(K.overwrite===void 0)console.log(`
88
+ Use ${I.cyan("--overwrite")} or ${I.cyan("-o")} flag to overwrite existing files, or run with ${I.cyan("node")} instead of ${I.cyan("bun")}.`),process.exit(1);B=K.overwrite}if(B){let K=v$("Overwriting files").start();G.forEach((M)=>{let v=N.addSourceFileAtPath(F.resolve(M.path));v.replaceWithText(M.code),v.getImportDeclarations().forEach((R)=>{let E=R.getModuleSpecifierValue();R.setModuleSpecifier(E$(E,y.path,Z?.aliases))}),v.saveSync()}),K.succeed("Files are overwritten")}}if(Y?.dependencies?.length){let B=v$().start();await X$(Y.dependencies,{cwd:z,spinner:B,label:"example dependencies"})}if(Y?.devDependencies?.length){let B=v$().start();await X$(Y.devDependencies,{cwd:z,dev:!0,spinner:B,label:"example devDependencies"})}if(y?.components?.length)await G3(()=>W0({components:y.components,dir:N0?.projectPath||"",path:y.path,license:y.license,message:""}),{retries:1});console.log(`
89
+ \uD83C\uDF89 Example ${I.green(y.example)} has been added to ${I.green(j)}`),process.exit(0)}import g from"chalk";import{Command as V3}from"commander";import X1 from"fast-glob";import b$ from"fs";import U1 from"ora";import C$ from"path";import j3 from"prompts";var N3={ArrowRight:"ArrowNext",ArrowLeft:"ArrowPrevious",ChevronRight:"ChevronNext",ChevronLeft:"ChevronPrevious",ChevronRightDouble:"ChevronNextDouble",ChevronLeftDouble:"ChevronPreviousDouble"},_3=[{pattern:/\bml-/g,replace:"ms-",description:"ml- → ms-"},{pattern:/\bmr-/g,replace:"me-",description:"mr- → me-"},{pattern:/\bpl-/g,replace:"ps-",description:"pl- → ps-"},{pattern:/\bpr-/g,replace:"pe-",description:"pr- → pe-"},{pattern:/(?<!from-|to-|placement-)(?<!\bin-placement-)\bleft-/g,replace:"start-",description:"left- → start-"},{pattern:/(?<!from-|to-|placement-)(?<!\bin-placement-)\bright-/g,replace:"end-",description:"right- → end-"},{pattern:/\brounded-l-/g,replace:"rounded-s-",description:"rounded-l- → rounded-s-"},{pattern:/\brounded-r-/g,replace:"rounded-e-",description:"rounded-r- → rounded-e-"},{pattern:/\brounded-tl-/g,replace:"rounded-ss-",description:"rounded-tl- → rounded-ss-"},{pattern:/\brounded-tr-/g,replace:"rounded-se-",description:"rounded-tr- → rounded-se-"},{pattern:/\brounded-bl-/g,replace:"rounded-es-",description:"rounded-bl- → rounded-es-"},{pattern:/\brounded-br-/g,replace:"rounded-ee-",description:"rounded-br- → rounded-ee-"},{pattern:/\bborder-l-/g,replace:"border-s-",description:"border-l- → border-s-"},{pattern:/\bborder-r-/g,replace:"border-e-",description:"border-r- → border-e-"},{pattern:/\bborder-l\b/g,replace:"border-s",description:"border-l → border-s"},{pattern:/\bborder-r\b/g,replace:"border-e",description:"border-r → border-e"},{pattern:/\btext-left\b/g,replace:"text-start",description:"text-left → text-start"},{pattern:/\btext-right\b/g,replace:"text-end",description:"text-right → text-end"},{pattern:/\bfloat-left\b/g,replace:"float-start",description:"float-left → float-start"},{pattern:/\bfloat-right\b/g,replace:"float-end",description:"float-right → float-end"},{pattern:/\bclear-left\b/g,replace:"clear-start",description:"clear-left → clear-start"},{pattern:/\bclear-right\b/g,replace:"clear-end",description:"clear-right → clear-end"},{pattern:/\bscroll-ml-/g,replace:"scroll-ms-",description:"scroll-ml- → scroll-ms-"},{pattern:/\bscroll-mr-/g,replace:"scroll-me-",description:"scroll-mr- → scroll-me-"},{pattern:/\bscroll-pl-/g,replace:"scroll-ps-",description:"scroll-pl- → scroll-ps-"},{pattern:/\bscroll-pr-/g,replace:"scroll-pe-",description:"scroll-pr- → scroll-pe-"}],M$="(?:(sm|md|lg|xl|2xl):)?";function _$($,z){let Q=$.match(/^(sm|md|lg|xl|2xl):/);return Q?`${$} ${Q[1]}:rtl:${z}`:`${$} rtl:${z}`}var b3=[{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-in-from-right(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-in-from-left)/g,replace:($)=>`${$} rtl:slide-in-from-left${$.replace("slide-in-from-right","")}`,description:"slide-in-from-right + rtl:slide-in-from-left",needsReview:!0},{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-in-from-left(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-in-from-right)/g,replace:($)=>`${$} rtl:slide-in-from-right${$.replace("slide-in-from-left","")}`,description:"slide-in-from-left + rtl:slide-in-from-right",needsReview:!0},{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-out-to-right(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-out-to-left)/g,replace:($)=>`${$} rtl:slide-out-to-left${$.replace("slide-out-to-right","")}`,description:"slide-out-to-right + rtl:slide-out-to-left",needsReview:!0},{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-out-to-left(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-out-to-right)/g,replace:($)=>`${$} rtl:slide-out-to-right${$.replace("slide-out-to-left","")}`,description:"slide-out-to-left + rtl:slide-out-to-right",needsReview:!0},{pattern:new RegExp(`(?<![-:])${M$}translate-x-([\\d./]+(?=\\s|$|")|full|px|\\[\\S+\\])(?!\\s+rtl:)`,"g"),replace:($)=>_$($,`-${$.replace(/^(sm|md|lg|xl|2xl):/,"")}`),description:"translate-x + rtl:-translate-x",needsReview:!0},{pattern:new RegExp(`(?<=^|\\s|")${M$}-translate-x-([\\d./]+(?=\\s|$|")|full|px|\\[\\S+\\])(?!\\s+rtl:)`,"g"),replace:($)=>{let z=$.match(/^(sm|md|lg|xl|2xl):/),Q=$.slice($.indexOf("-translate-x-")+13);return z?`${$} ${z[1]}:rtl:translate-x-${Q}`:`${$} rtl:translate-x-${Q}`},description:"-translate-x + rtl:translate-x",needsReview:!0},{pattern:new RegExp(`\\b${M$}space-x-(\\d+(?:\\.\\d+)?|\\[\\S+\\])(?!\\s+(?:sm:|md:|lg:|xl:|2xl:)?rtl:space-x-reverse)`,"g"),replace:($)=>_$($,"space-x-reverse"),description:"space-x + rtl:space-x-reverse",needsReview:!0},{pattern:new RegExp(`\\b${M$}divide-x(?:-(\\d+(?:\\.\\d+)?|\\[\\S+\\]))?(?!\\s+(?:sm:|md:|lg:|xl:|2xl:)?rtl:divide-x-reverse)`,"g"),replace:($)=>_$($,"divide-x-reverse"),description:"divide-x + rtl:divide-x-reverse",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${M$}bg-linear-to-r\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-linear-to-l)`,"g"),replace:($)=>_$($,"bg-linear-to-l"),description:"bg-linear-to-r + rtl:bg-linear-to-l",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${M$}bg-linear-to-l\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-linear-to-r)`,"g"),replace:($)=>_$($,"bg-linear-to-r"),description:"bg-linear-to-l + rtl:bg-linear-to-r",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${M$}bg-gradient-to-r\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-gradient-to-l)`,"g"),replace:($)=>_$($,"bg-gradient-to-l"),description:"bg-gradient-to-r + rtl:bg-gradient-to-l",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${M$}bg-gradient-to-l\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-gradient-to-r)`,"g"),replace:($)=>_$($,"bg-gradient-to-r"),description:"bg-gradient-to-l + rtl:bg-gradient-to-r",needsReview:!0}],A3=/\bleft-1\/2\b.*-translate-x-1\/2|-translate-x-1\/2.*\bleft-1\/2\b/,B1=/\b(ml-|mr-|pl-|pr-|left-|right-|rounded-[lr]-|rounded-t[lr]-|rounded-b[lr]-|border-[lr]|text-left|text-right|float-left|float-right|scroll-m[lr]-|scroll-p[lr]-|translate-x-|space-x-|divide-x|bg-linear-to-[lr]|bg-gradient-to-[lr]|slide-in-from-(?:left|right)|slide-out-to-(?:left|right))/;function H1($,z){let Q=$;for(let U of z)Q=Q.replace(U.pattern,U.replace);return Q}function D3($,z,Q){let U={file:$,changes:[]},Z=z.split(`
90
+ `);for(let Y=0;Y<Z.length;Y++){let W=Z[Y];if(/^\s*(import\b|export\b.*from\b)/.test(W)||/\brequire\s*\(/.test(W))continue;if(A3.test(W))continue;let H=W,X=!1;if(H=H.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(G,N,b,j,_)=>{let B=N??b??j??_;if(B==null||!B1.test(B))return G;let K=H1(B,Q);if(K!==B)return X=!0,G.replace(B,K);return G}),X&&H!==W)Z[Y]=H,U.changes.push({line:Y+1,before:W.trim(),after:H.trim()})}return U}function I3($){let z=0,Q=$;for(let[U,Z]of Object.entries(N3)){let Y=new RegExp(`\\b${U}\\b`,"g"),W=Q;if(Q=Q.replace(Y,Z),Q!==W)z+=(W.match(Y)||[]).length}return{content:Q,swaps:z}}async function E3($){let z=C$.resolve($);return X1(["**/*.tsx","**/*.ts"],{cwd:z,absolute:!0,ignore:["**/node_modules/**","**/*.story.tsx","**/*.demo.tsx","**/*.test.tsx"]})}var K1="[data-rtl-flip]:dir(rtl) { transform: scaleX(-1); }";function W1($){let z=["global.css","globals.css","styles/global.css","styles/globals.css","src/global.css","src/globals.css","src/styles/global.css","src/styles/globals.css","app/global.css","app/globals.css"];for(let U of z){let Z=C$.resolve($,U);if(b$.existsSync(Z))return Z}let Q=X1.sync(["**/*.css"],{cwd:$,absolute:!0,ignore:["**/node_modules/**","**/dist/**","**/build/**","**/.next/**"]});for(let U of Q){let Z=b$.readFileSync(U,"utf-8");if(Z.includes("@import")&&Z.includes("tailwindcss"))return U}return Q[0]||null}function T3($,z){let Q=b$.readFileSync($,"utf-8");if(Q.includes("data-rtl-flip"))return!1;let U=Q.trimEnd()+`
91
+
92
+ `+K1+`
93
+ `;if(!z)b$.writeFileSync($,U);return!0}var q1=new V3().name("migrate").description("migrate components for RTL support").argument("[path]","path to migrate (defaults to current directory)").option("--dry-run","preview changes without writing files",!1).option("--skip-icons","skip directional icon swapping",!1).option("-y, --yes","skip prompts and use defaults",!1).action(async($,z)=>{console.log(g.bold(`
94
94
  Migrate to RTL
95
- `));let Q=C$.resolve($||".");if(!_$.existsSync(Q))console.log(P.red(` Path not found: ${Q}`)),process.exit(1);let U=!z.skipIcons,Z=!0,Y=!1;if(!z.yes){let V=await V3([{type:z.skipIcons?null:"confirm",name:"swapIcons",message:"Swap directional icons for RTL-aware versions? (e.g. ArrowRight → ArrowNext)",initial:!0},{type:"confirm",name:"includeVariants",message:"Add rtl: variants for animations, gradients, translate, and space-x?",initial:!0},{type:z.dryRun?null:"confirm",name:"confirm",message:`Apply changes to ${P.cyan(Q)}?`,initial:!0}]);if(V.confirm===!1){console.log(P.yellow(`
95
+ `));let Q=C$.resolve($||".");if(!b$.existsSync(Q))console.log(g.red(` Path not found: ${Q}`)),process.exit(1);let U=!z.skipIcons,Z=!0,Y=!1;if(!z.yes){let M=await j3([{type:z.skipIcons?null:"confirm",name:"swapIcons",message:"Swap directional icons for RTL-aware versions? (e.g. ArrowRight → ArrowNext)",initial:!0},{type:"confirm",name:"includeVariants",message:"Add rtl: variants for animations, gradients, translate, and space-x?",initial:!0},{type:z.dryRun?null:"confirm",name:"confirm",message:`Apply changes to ${g.cyan(Q)}?`,initial:!0}]);if(M.confirm===!1){console.log(g.yellow(`
96
96
  Cancelled.
97
- `));return}U=!z.skipIcons&&V.swapIcons!==!1,Z=V.includeVariants!==!1,Y=U}else Y=U;let X=Y1(" Scanning files...").start(),H=await I3(Q);X.succeed(` Found ${P.bold(H.length)} files`);let B=[...N3,...Z?b3:[]],J=0,j=0,_=0,L=[],b=Y1(" Transforming...").start();for(let V of H){let w=_$.readFileSync(V,"utf-8"),T=C$.relative(Q,V),E=w,C=!1,d=A3(T,E,B);if(d.changes.length>0){E=w.split(`
98
- `).map((q,K)=>{return d.changes.find((A)=>A.line===K+1)?E.split(`
99
- `)[K]:q}).join(`
100
- `);let F=E.split(`
101
- `),R=w.split(`
102
- `);for(let q of d.changes){let K=q.line-1,M=R[K];M=M.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(A,x,k,n,e)=>{let $$=x??k??n??e;if($$==null||!X1.test($$))return A;let t=B1($$,B);return t!==$$?A.replace($$,t):A}),F[K]=M}E=F.join(`
103
- `),J+=d.changes.length,C=!0,L.push(d)}if(U){let F=D3(E);if(F.swaps>0)E=F.content,j+=F.swaps,C=!0}if(C){if(_++,!z.dryRun)_$.writeFileSync(V,E)}}b.succeed(` Processed ${P.bold(H.length)} files`);let W=!1,y="";if(Y&&j>0){let V=U1(Q);if(V)y=C$.relative(Q,V),W=E3(V,z.dryRun)}if(console.log(P.bold(`
97
+ `));return}U=!z.skipIcons&&M.swapIcons!==!1,Z=M.includeVariants!==!1,Y=U}else Y=U;let W=U1(" Scanning files...").start(),H=await E3(Q);W.succeed(` Found ${g.bold(H.length)} files`);let X=[..._3,...Z?b3:[]],G=0,N=0,b=0,j=[],_=U1(" Transforming...").start();for(let M of H){let v=b$.readFileSync(M,"utf-8"),R=C$.relative(Q,M),E=v,T=!1,C=D3(R,E,X);if(C.changes.length>0){E=v.split(`
98
+ `).map((J,q)=>{return C.changes.find((A)=>A.line===q+1)?E.split(`
99
+ `)[q]:J}).join(`
100
+ `);let O=E.split(`
101
+ `),S=v.split(`
102
+ `);for(let J of C.changes){let q=J.line-1,L=S[q];L=L.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(A,x,u,o,K$)=>{let n=x??u??o??K$;if(n==null||!B1.test(n))return A;let e=H1(n,X);return e!==n?A.replace(n,e):A}),O[q]=L}E=O.join(`
103
+ `),G+=C.changes.length,T=!0,j.push(C)}if(U){let O=I3(E);if(O.swaps>0)E=O.content,N+=O.swaps,T=!0}if(T){if(b++,!z.dryRun)b$.writeFileSync(M,E)}}_.succeed(` Processed ${g.bold(H.length)} files`);let B=!1,K="";if(Y&&N>0){let M=W1(Q);if(M)K=C$.relative(Q,M),B=T3(M,z.dryRun)}if(console.log(g.bold(`
104
104
  Summary
105
- `)),console.log(` Files modified: ${P.cyan(_)}`),console.log(` Class changes: ${P.cyan(J)}`),U)console.log(` Icon swaps: ${P.cyan(j)}`);if(W)console.log(` RTL flip rule: ${P.cyan("added")} → ${P.dim(y)}`);else if(Y&&j>0&&!W)if(!U1(Q))console.log(P.yellow(`
106
- Could not find a global CSS file to inject the RTL flip rule.`)),console.log(P.yellow(` Add this manually to your global stylesheet:
107
- `)),console.log(P.dim(` ${H1}
108
- `));else console.log(` RTL flip rule: ${P.dim("already present")}`);if(z.dryRun){if(console.log(P.yellow(`
109
- Dry run — no files were modified.`)),L.length>0){console.log(P.bold(`
105
+ `)),console.log(` Files modified: ${g.cyan(b)}`),console.log(` Class changes: ${g.cyan(G)}`),U)console.log(` Icon swaps: ${g.cyan(N)}`);if(B)console.log(` RTL flip rule: ${g.cyan("added")} → ${g.dim(K)}`);else if(Y&&N>0&&!B)if(!W1(Q))console.log(g.yellow(`
106
+ Could not find a global CSS file to inject the RTL flip rule.`)),console.log(g.yellow(` Add this manually to your global stylesheet:
107
+ `)),console.log(g.dim(` ${K1}
108
+ `));else console.log(` RTL flip rule: ${g.dim("already present")}`);if(z.dryRun){if(console.log(g.yellow(`
109
+ Dry run — no files were modified.`)),j.length>0){console.log(g.bold(`
110
110
  Changes preview:
111
- `));for(let V of L.slice(0,10)){console.log(P.dim(` ${V.file}`));for(let w of V.changes.slice(0,3))console.log(P.red(` - ${w.before.substring(0,100)}`)),console.log(P.green(` + ${w.after.substring(0,100)}`));if(V.changes.length>3)console.log(P.dim(` ... and ${V.changes.length-3} more`))}if(L.length>10)console.log(P.dim(`
112
- ... and ${L.length-10} more files`))}}else console.log(P.green(`
113
- Done! ${_} files updated.`));console.log()});import g from"chalk";import{Command as T3}from"commander";import j0 from"node-fetch";import x3 from"ora";var N0="https://www.untitledui.com/react/api/mcp/tools";async function R3($,z,Q=10,U){return(await(await j0(`${N0}/search-components`,{method:"POST",headers:{"Content-Type":"application/json",...z&&{Authorization:`Bearer ${z}`}},body:JSON.stringify({query:$,limit:Q,version:U})})).json()).results||[]}async function S3($,z,Q=10,U){return(await(await j0(`${N0}/get-page-templates`,{method:"POST",headers:{"Content-Type":"application/json",...z&&{Authorization:`Bearer ${z}`}},body:JSON.stringify({query:$,limit:Q,version:U})})).json()).templates||[]}async function w3($,z=10){return(await(await j0(`${N0}/search-icons`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:$,limit:z})})).json()).results||[]}function v3($,z){let Q=$.access==="pro"?g.magenta(" PRO"):g.green(" FREE");if(console.log(` ${g.bold(`${z+1}. ${$.name}`)}${Q} ${g.dim(`(${$.category})`)}`),console.log(` ${g.dim($.description)}`),$.key_features?.length)console.log(` ${$.key_features.map((U)=>g.cyan(U)).join(" ")}`);console.log()}function C3($,z){if(console.log(` ${g.bold(`${z+1}. ${$.name}`)} ${g.dim(`(${$.type} · ${$.layout})`)}`),console.log(` ${g.dim($.description)}`),$.sections?.length)console.log(` ${g.dim("Sections:")} ${$.sections.map((Q)=>g.cyan(Q)).join(" ")}`);if($.hero_style)console.log(` ${g.dim("Hero:")} ${g.yellow($.hero_style)}`);console.log()}function F3($,z){if(console.log(` ${g.bold(`${z+1}. ${$.importName}`)} ${g.dim(`(${$.category})`)}`),console.log(` ${g.dim(`import { ${$.importName} } from "@untitledui/icons"`)}`),$.tags?.length)console.log(` ${$.tags.slice(0,6).map((Q)=>g.dim(Q)).join(" ")}`);console.log()}var q1=new T3().name("search").description("search for components, templates, and icons using natural language").argument("<query...>","search query (e.g., 'login with reviews', 'dark pricing table')").option("-t, --type <type>","filter by type: components, templates, icons, all","all").option("-l, --limit <number>","max results per category","5").option("-k, --key <key>","API key for PRO access").option("--lib-version <version>","component library version (7 or 8)").action(async($,z)=>{let Q=$.join(" "),U=parseInt(z.limit,10),Z=z.key||q$()||void 0,Y=z.type.toLowerCase(),X=z.libVersion,H=x3(`Searching for "${Q}"...`).start();try{let B=Y==="all"||Y==="components",J=Y==="all"||Y==="templates",j=Y==="all"||Y==="icons",[_,L,b]=await Promise.all([B?R3(Q,Z,U,X):Promise.resolve([]),J?S3(Q,Z,U,X):Promise.resolve([]),j?w3(Q,U):Promise.resolve([])]);if(H.stop(),_.length+L.length+b.length===0){console.log(g.yellow(`
111
+ `));for(let M of j.slice(0,10)){console.log(g.dim(` ${M.file}`));for(let v of M.changes.slice(0,3))console.log(g.red(` - ${v.before.substring(0,100)}`)),console.log(g.green(` + ${v.after.substring(0,100)}`));if(M.changes.length>3)console.log(g.dim(` ... and ${M.changes.length-3} more`))}if(j.length>10)console.log(g.dim(`
112
+ ... and ${j.length-10} more files`))}}else console.log(g.green(`
113
+ Done! ${b} files updated.`));console.log()});import d from"chalk";import{Command as x3}from"commander";import _0 from"node-fetch";import R3 from"ora";var b0="https://www.untitledui.com/react/api/mcp/tools";async function S3($,z,Q=10,U){return(await(await _0(`${b0}/search-components`,{method:"POST",headers:{"Content-Type":"application/json",...z&&{Authorization:`Bearer ${z}`}},body:JSON.stringify({query:$,limit:Q,version:U})})).json()).results||[]}async function w3($,z,Q=10,U){return(await(await _0(`${b0}/get-page-templates`,{method:"POST",headers:{"Content-Type":"application/json",...z&&{Authorization:`Bearer ${z}`}},body:JSON.stringify({query:$,limit:Q,version:U})})).json()).templates||[]}async function v3($,z=10){return(await(await _0(`${b0}/search-icons`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:$,limit:z})})).json()).results||[]}function C3($,z){let Q=$.access==="pro"?d.magenta(" PRO"):d.green(" FREE");if(console.log(` ${d.bold(`${z+1}. ${$.name}`)}${Q} ${d.dim(`(${$.category})`)}`),console.log(` ${d.dim($.description)}`),$.key_features?.length)console.log(` ${$.key_features.map((U)=>d.cyan(U)).join(" ")}`);console.log()}function F3($,z){if(console.log(` ${d.bold(`${z+1}. ${$.name}`)} ${d.dim(`(${$.type} · ${$.layout})`)}`),console.log(` ${d.dim($.description)}`),$.sections?.length)console.log(` ${d.dim("Sections:")} ${$.sections.map((Q)=>d.cyan(Q)).join(" ")}`);if($.hero_style)console.log(` ${d.dim("Hero:")} ${d.yellow($.hero_style)}`);console.log()}function O3($,z){if(console.log(` ${d.bold(`${z+1}. ${$.importName}`)} ${d.dim(`(${$.category})`)}`),console.log(` ${d.dim(`import { ${$.importName} } from "@untitledui/icons"`)}`),$.tags?.length)console.log(` ${$.tags.slice(0,6).map((Q)=>d.dim(Q)).join(" ")}`);console.log()}var J1=new x3().name("search").description("search for components, templates, and icons using natural language").argument("<query...>","search query (e.g., 'login with reviews', 'dark pricing table')").option("-t, --type <type>","filter by type: components, templates, icons, all","all").option("-l, --limit <number>","max results per category","5").option("-k, --key <key>","API key for PRO access").option("--lib-version <version>","component library version (7 or 8)").action(async($,z)=>{let Q=$.join(" "),U=parseInt(z.limit,10),Z=z.key||q$()||void 0,Y=z.type.toLowerCase(),W=z.libVersion,H=R3(`Searching for "${Q}"...`).start();try{let X=Y==="all"||Y==="components",G=Y==="all"||Y==="templates",N=Y==="all"||Y==="icons",[b,j,_]=await Promise.all([X?S3(Q,Z,U,W):Promise.resolve([]),G?w3(Q,Z,U,W):Promise.resolve([]),N?v3(Q,U):Promise.resolve([])]);if(H.stop(),b.length+j.length+_.length===0){console.log(d.yellow(`
114
114
  No results found for "${Q}"
115
- `));return}if(_.length>0){if(console.log(g.bold.underline(`
116
- Components (${_.length})
117
- `)),_.forEach(v3),_.length>0){let y=_[0].name;console.log(g.dim(` Install: npx untitledui@latest add ${y} --yes
118
- `))}}if(L.length>0){if(console.log(g.bold.underline(`
119
- Templates (${L.length})
120
- `)),L.forEach(C3),L.length>0){let y=L[0].name;console.log(g.dim(` Install: npx untitledui@latest example ${y} --yes
121
- `))}}if(b.length>0)console.log(g.bold.underline(`
122
- Icons (${b.length})
123
- `)),b.forEach(F3)}catch(B){H.fail("Search failed"),console.error(g.red(B instanceof Error?B.message:"Unknown error")),process.exit(1)}});import D from"chalk";import{Command as f3}from"commander";import{execa as _0}from"execa";import A0 from"fast-glob";import l from"fs";import i from"ora";import p from"path";import A1 from"prompts";var J1={fromVersion:"7",toVersion:"8",classTransforms:[{pattern:/\bshadow-xs-skeumorphic\b/g,replace:"shadow-xs-skeuomorphic",description:"shadow-xs-skeumorphic → shadow-xs-skeuomorphic (typo fix)"},{pattern:/\bshadow-skeumorphic\b/g,replace:"shadow-skeuomorphic",description:"shadow-skeumorphic → shadow-skeuomorphic (typo fix)"},{pattern:/\butility-gray-blue-/g,replace:"utility-slate-",description:"utility-gray-blue- → utility-slate-"},{pattern:/\butility-blue-light-/g,replace:"utility-sky-",description:"utility-blue-light- → utility-sky-"},{pattern:/\butility-gray-/g,replace:"utility-neutral-",description:"utility-gray- → utility-neutral-"},{pattern:/\butility-error-/g,replace:"utility-red-",description:"utility-error- → utility-red-"},{pattern:/\butility-warning-/g,replace:"utility-yellow-",description:"utility-warning- → utility-yellow-"},{pattern:/\butility-success-/g,replace:"utility-green-",description:"utility-success- → utility-green-"},{pattern:/\boutline-none\b/g,replace:"outline-hidden",description:"outline-none → outline-hidden"},{pattern:/\bbg-disabled_subtle\b/g,replace:"opacity-50",description:"bg-disabled_subtle → opacity-50",needsReview:!0},{pattern:/\bbg-disabled\b/g,replace:"opacity-50",description:"bg-disabled → opacity-50",needsReview:!0},{pattern:/\btext-disabled\b/g,replace:"",description:"text-disabled → removed",needsReview:!0},{pattern:/\bring-disabled_subtle\b/g,replace:"",description:"ring-disabled_subtle → removed",needsReview:!0},{pattern:/\bring-disabled\b/g,replace:"",description:"ring-disabled → removed",needsReview:!0},{pattern:/\bborder-disabled_subtle\b/g,replace:"",description:"border-disabled_subtle → removed",needsReview:!0},{pattern:/\bborder-disabled\b/g,replace:"",description:"border-disabled → removed",needsReview:!0},{pattern:/\btext-fg-disabled_subtle\b/g,replace:"",description:"text-fg-disabled_subtle → removed",needsReview:!0},{pattern:/\btext-fg-disabled\b/g,replace:"",description:"text-fg-disabled → removed",needsReview:!0},{pattern:/\btext-placeholder_subtle\b/g,replace:"",description:"text-placeholder_subtle → removed",needsReview:!0},{pattern:/\btext-button-primary-icon_hover\b/g,replace:"text-white/70",description:"text-button-primary-icon_hover → text-white/70"},{pattern:/\btext-button-primary-icon\b/g,replace:"text-white/60",description:"text-button-primary-icon → text-white/60"},{pattern:/\btext-button-destructive-primary-icon_hover\b/g,replace:"text-white/70",description:"text-button-destructive-primary-icon_hover → text-white/70"},{pattern:/\btext-button-destructive-primary-icon\b/g,replace:"text-white/60",description:"text-button-destructive-primary-icon → text-white/60"},{pattern:/\bbg-avatar-bg\b/g,replace:"bg-tertiary",description:"bg-avatar-bg → bg-tertiary"},{pattern:/\bring-bg-brand-solid\b/g,replace:"ring-brand-solid",description:"ring-bg-brand-solid → ring-brand-solid"},{pattern:/\bbg-active\b/g,replace:"bg-primary_hover",description:"bg-active → bg-primary_hover",needsReview:!0},{pattern:/\bbg-toggle-button-fg_disabled\b/g,replace:"",description:"bg-toggle-button-fg_disabled → removed",needsReview:!0}],importTransforms:[{from:"pin-input/pin-input",to:"input/pin-input",description:"pin-input moved into input directory"},{from:"nav-item-button",to:"nav-button",description:"nav-item-button renamed to nav-button"},{from:"select/multi-select",to:"select/tag-select",description:"multi-select renamed to tag-select (new multi-select is a different component)",symbolRenames:[{from:"MultiSelect",to:"TagSelect"}]}],propTransforms:[{from:'color="gray-blue"',to:'color="slate"',description:'color="gray-blue" renamed to color="slate"'},{from:'color="blue-light"',to:'color="sky"',description:'color="blue-light" renamed to color="sky"'}],structuralPatterns:[],orphanedTokens:["bg-disabled_subtle","text-disabled","ring-disabled","border-disabled","text-fg-disabled","bg-avatar-bg","text-button-primary-icon","text-button-destructive-primary-icon","bg-toggle-button-fg_disabled","utility-gray-","utility-error-","utility-warning-","utility-success-","utility-gray-blue-","utility-blue-light-","skeumorphic"],dependencyChanges:{update:{next:"16.2.0",react:"^19.2.4","react-dom":"^19.2.4","react-aria-components":"^1.16.0","react-aria":"^3.47.0",tailwindcss:"^4.2.2",motion:"^12.38.0",recharts:"^3.8.0"},add:{},devUpdate:{storybook:"^10.3.0",vite:"^8.0.0","@vitejs/plugin-react":"^6.0.1",eslint:"^10.0.3",typescript:"^5.9.3"},devAdd:{"@storybook/test-runner":"^0.24.3"},remove:[]},configChanges:{tsconfig:[{description:"Update JSX transform to react-jsx",find:'"jsx": "preserve"',replace:'"jsx": "react-jsx"'}]},notes:["The v7 MultiSelect (tag-chip style) has been renamed to TagSelect. The new MultiSelect is a different component with autocomplete. Update your imports accordingly.","Default size for Select, ComboBox, and Input changed from 'sm' to 'md'. Review component usage.","Avatar size 'xxs' removed. Use 'xs' instead.","Dropdown no longer defaults to selectionMode='single'. Set explicitly if needed."]};import*as R$ from"fs";import*as b0 from"path";function y1($){let{tsconfigPath:z,changes:Q,dryRun:U}=$,Z=b0.resolve(z),Y=[],X=[],H;try{H=R$.readFileSync(Z,"utf-8")}catch{return{applied:Y,skipped:Q.map((J)=>J.description)}}let B=H;for(let J of Q)if(B.includes(J.find))B=B.replace(J.find,J.replace),Y.push(J.description);else X.push(J.description);if(!U&&Y.length>0)R$.writeFileSync(Z,B,"utf-8");return{applied:Y,skipped:X}}function G1($){let{packageJsonPath:z,update:Q,add:U,devUpdate:Z,devAdd:Y,remove:X,dryRun:H}=$,B=b0.resolve(z),J=[],j=[],_=[],L;try{let b=R$.readFileSync(B,"utf-8");L=JSON.parse(b)}catch{return{updated:J,added:j,removed:_}}if(!L.dependencies)L.dependencies={};if(!L.devDependencies)L.devDependencies={};for(let[b,W]of Object.entries(Q))if(L.dependencies[b])L.dependencies[b]=W,J.push(b);for(let[b,W]of Object.entries(U))if(!L.dependencies[b])L.dependencies[b]=W,j.push(b);for(let[b,W]of Object.entries(Z))if(L.devDependencies[b])L.devDependencies[b]=W,J.push(b);for(let[b,W]of Object.entries(Y))if(!L.devDependencies[b])L.devDependencies[b]=W,j.push(b);for(let b of X){if(L.dependencies[b])delete L.dependencies[b],_.push(b);if(L.devDependencies[b]){if(delete L.devDependencies[b],!_.includes(b))_.push(b)}}if(!H&&(J.length>0||j.length>0||_.length>0))R$.writeFileSync(B,JSON.stringify(L,null,2)+`
124
- `,"utf-8");return{updated:J,added:j,removed:_}}import*as S$ from"fs";import*as M1 from"path";function O3($){let z=/--color-brand-(\d+):\s*([^;]+);/g,Q={},U;while((U=z.exec($))!==null)if(U[1]&&U[2])Q[`--color-brand-${U[1]}`]=U[2].trim();return Q}function k3($,z){let Q=$;for(let[U,Z]of Object.entries(z)){let Y=new RegExp(`(${U.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}):\\s*[^;]+;`,"g");Q=Q.replace(Y,`${U}: ${Z};`)}return Q}async function L1($){let{themePath:z,newThemeContent:Q,dryRun:U}=$,Z=M1.resolve(z),Y;try{Y=S$.readFileSync(Z,"utf-8")}catch{return{brandColors:{},success:!1,message:`Theme file not found at ${Z}`}}let X=O3(Y);if(U)return{brandColors:X,success:!0,message:`Dry run: found ${Object.keys(X).length} brand color variables`};try{if(S$.writeFileSync(Z,Q,"utf-8"),Object.keys(X).length>0){let H=S$.readFileSync(Z,"utf-8"),B=k3(H,X);S$.writeFileSync(Z,B,"utf-8")}return{brandColors:X,success:!0,message:`Theme upgraded successfully. Preserved ${Object.keys(X).length} brand color variables.`}}catch(H){let B=H instanceof Error?H.message:String(H);return{brandColors:X,success:!1,message:`Failed to write theme file: ${B}`}}}var u3=/\bleft-1\/2\b.*-translate-x-1\/2|-translate-x-1\/2.*\bleft-1\/2\b/;function P3($,z){return z.some((Q)=>Q.pattern.test($))}function g3($,z){let Q=$;for(let U of z)U.pattern.lastIndex=0,Q=Q.replace(U.pattern,U.replace);return Q}function d3($,z,Q){let U=[];for(let Z of Q){if(Z.pattern.lastIndex=0,Z.pattern.test($))U.push(Z.description);Z.pattern.lastIndex=0}return U.join("; ")}function V1($,z,Q){let U={file:$,changes:[]},Z=z.split(`
125
- `);for(let Y=0;Y<Z.length;Y++){let X=Z[Y];if(/^\s*(import\b|require\s*\(|export\b.*from\b)/.test(X))continue;if(u3.test(X))continue;let H=X,B=!1;if(H=H.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(J,j,_,L,b)=>{let W=j??_??L??b;if(W==null)return J;for(let V of Q)V.pattern.lastIndex=0;if(!P3(W,Q))return J;for(let V of Q)V.pattern.lastIndex=0;let y=g3(W,Q);if(y!==W)return B=!0,J.replace(W,y);return J}),B&&H!==X){let J=d3(X,H,Q);Z[Y]=H,U.changes.push({line:Y+1,before:X.trim(),after:H.trim(),description:J})}}return U}function j1($,z){let Q=[],U=$.split(`
126
- `),Z=[];for(let Y=0;Y<U.length;Y++){let X=U[Y];if(!/^\s*(import\b|require\s*\(|export\b.*from\b)/.test(X))continue;let H=X;for(let B of z)if(H.includes(B.from)){if(H=H.replace(B.from,B.to),B.symbolRenames)Z.push(...B.symbolRenames)}if(H!==X){U[Y]=H;let B=z.find((J)=>X.includes(J.from));Q.push({line:Y+1,before:X.trim(),after:H.trim(),description:B?.description??"Import path update"})}}if(Z.length>0)for(let Y=0;Y<U.length;Y++){let X=U[Y],H=X;for(let B of Z){let J=new RegExp(`\\b${B.from}\\b`,"g");H=H.replace(J,B.to)}if(H!==X){if(U[Y]=H,!Q.some((J)=>J.line===Y+1))Q.push({line:Y+1,before:X.trim(),after:H.trim(),description:`Renamed ${Z.map((J)=>`${J.from} → ${J.to}`).join(", ")}`})}}return{content:U.join(`
127
- `),changes:Q}}function N1($,z){let Q=[],U=$.split(`
128
- `);for(let Z=0;Z<U.length;Z++){let Y=U[Z];if(/^\s*(import\b|require\s*\(|export\b.*from\b)/.test(Y))continue;let X=Y;for(let H of z)if(X.includes(H.from))X=X.split(H.from).join(H.to);if(X!==Y){U[Z]=X;let H=z.find((B)=>Y.includes(B.from));Q.push({line:Z+1,before:Y.trim(),after:X.trim(),description:H?.description??"Prop update"})}}return{content:U.join(`
115
+ `));return}if(b.length>0){if(console.log(d.bold.underline(`
116
+ Components (${b.length})
117
+ `)),b.forEach(C3),b.length>0){let K=b[0].name;console.log(d.dim(` Install: npx untitledui@latest add ${K} --yes
118
+ `))}}if(j.length>0){if(console.log(d.bold.underline(`
119
+ Templates (${j.length})
120
+ `)),j.forEach(F3),j.length>0){let K=j[0].name;console.log(d.dim(` Install: npx untitledui@latest example ${K} --yes
121
+ `))}}if(_.length>0)console.log(d.bold.underline(`
122
+ Icons (${_.length})
123
+ `)),_.forEach(O3)}catch(X){H.fail("Search failed"),console.error(d.red(X instanceof Error?X.message:"Unknown error")),process.exit(1)}});import D from"chalk";import{Command as h3}from"commander";import{execa as D0}from"execa";import I0 from"fast-glob";import l from"fs";import i from"ora";import a from"path";import D1 from"prompts";var G1={fromVersion:"7",toVersion:"8",classTransforms:[{pattern:/\bshadow-xs-skeumorphic\b/g,replace:"shadow-xs-skeuomorphic",description:"shadow-xs-skeumorphic → shadow-xs-skeuomorphic (typo fix)"},{pattern:/\bshadow-skeumorphic\b/g,replace:"shadow-skeuomorphic",description:"shadow-skeumorphic → shadow-skeuomorphic (typo fix)"},{pattern:/\butility-gray-blue-/g,replace:"utility-slate-",description:"utility-gray-blue- → utility-slate-"},{pattern:/\butility-blue-light-/g,replace:"utility-sky-",description:"utility-blue-light- → utility-sky-"},{pattern:/\butility-gray-/g,replace:"utility-neutral-",description:"utility-gray- → utility-neutral-"},{pattern:/\butility-error-/g,replace:"utility-red-",description:"utility-error- → utility-red-"},{pattern:/\butility-warning-/g,replace:"utility-yellow-",description:"utility-warning- → utility-yellow-"},{pattern:/\butility-success-/g,replace:"utility-green-",description:"utility-success- → utility-green-"},{pattern:/\boutline-none\b/g,replace:"outline-hidden",description:"outline-none → outline-hidden"},{pattern:/\bbg-disabled_subtle\b/g,replace:"opacity-50",description:"bg-disabled_subtle → opacity-50",needsReview:!0},{pattern:/\bbg-disabled\b/g,replace:"opacity-50",description:"bg-disabled → opacity-50",needsReview:!0},{pattern:/\btext-disabled\b/g,replace:"",description:"text-disabled → removed",needsReview:!0},{pattern:/\bring-disabled_subtle\b/g,replace:"",description:"ring-disabled_subtle → removed",needsReview:!0},{pattern:/\bring-disabled\b/g,replace:"",description:"ring-disabled → removed",needsReview:!0},{pattern:/\bborder-disabled_subtle\b/g,replace:"",description:"border-disabled_subtle → removed",needsReview:!0},{pattern:/\bborder-disabled\b/g,replace:"",description:"border-disabled → removed",needsReview:!0},{pattern:/\btext-fg-disabled_subtle\b/g,replace:"",description:"text-fg-disabled_subtle → removed",needsReview:!0},{pattern:/\btext-fg-disabled\b/g,replace:"",description:"text-fg-disabled → removed",needsReview:!0},{pattern:/\btext-placeholder_subtle\b/g,replace:"",description:"text-placeholder_subtle → removed",needsReview:!0},{pattern:/\btext-button-primary-icon_hover\b/g,replace:"text-white/70",description:"text-button-primary-icon_hover → text-white/70"},{pattern:/\btext-button-primary-icon\b/g,replace:"text-white/60",description:"text-button-primary-icon → text-white/60"},{pattern:/\btext-button-destructive-primary-icon_hover\b/g,replace:"text-white/70",description:"text-button-destructive-primary-icon_hover → text-white/70"},{pattern:/\btext-button-destructive-primary-icon\b/g,replace:"text-white/60",description:"text-button-destructive-primary-icon → text-white/60"},{pattern:/\bbg-avatar-bg\b/g,replace:"bg-tertiary",description:"bg-avatar-bg → bg-tertiary"},{pattern:/\bring-bg-brand-solid\b/g,replace:"ring-brand-solid",description:"ring-bg-brand-solid → ring-brand-solid"},{pattern:/\bbg-active\b/g,replace:"bg-primary_hover",description:"bg-active → bg-primary_hover",needsReview:!0},{pattern:/\bbg-toggle-button-fg_disabled\b/g,replace:"",description:"bg-toggle-button-fg_disabled → removed",needsReview:!0}],importTransforms:[{from:"pin-input/pin-input",to:"input/pin-input",description:"pin-input moved into input directory"},{from:"nav-item-button",to:"nav-button",description:"nav-item-button renamed to nav-button"},{from:"select/multi-select",to:"select/tag-select",description:"multi-select renamed to tag-select (new multi-select is a different component)",symbolRenames:[{from:"MultiSelect",to:"TagSelect"}]}],propTransforms:[{from:'color="gray-blue"',to:'color="slate"',description:'color="gray-blue" renamed to color="slate"'},{from:'color="blue-light"',to:'color="sky"',description:'color="blue-light" renamed to color="sky"'}],structuralPatterns:[],orphanedTokens:["bg-disabled_subtle","text-disabled","ring-disabled","border-disabled","text-fg-disabled","bg-avatar-bg","text-button-primary-icon","text-button-destructive-primary-icon","bg-toggle-button-fg_disabled","utility-gray-","utility-error-","utility-warning-","utility-success-","utility-gray-blue-","utility-blue-light-","skeumorphic"],dependencyChanges:{update:{next:"16.2.0",react:"^19.2.4","react-dom":"^19.2.4","react-aria-components":"^1.16.0","react-aria":"^3.47.0",tailwindcss:"^4.2.2",motion:"^12.38.0",recharts:"^3.8.0"},add:{},devUpdate:{storybook:"^10.3.0",vite:"^8.0.0","@vitejs/plugin-react":"^6.0.1",eslint:"^10.0.3",typescript:"^5.9.3"},devAdd:{"@storybook/test-runner":"^0.24.3"},remove:[]},configChanges:{tsconfig:[{description:"Update JSX transform to react-jsx",find:'"jsx": "preserve"',replace:'"jsx": "react-jsx"'}]},notes:["The v7 MultiSelect (tag-chip style) has been renamed to TagSelect. The new MultiSelect is a different component with autocomplete. Update your imports accordingly.","Default size for Select, ComboBox, and Input changed from 'sm' to 'md'. Review component usage.","Avatar size 'xxs' removed. Use 'xs' instead.","Dropdown no longer defaults to selectionMode='single'. Set explicitly if needed."]};import*as R$ from"fs";import*as A0 from"path";function M1($){let{tsconfigPath:z,changes:Q,dryRun:U}=$,Z=A0.resolve(z),Y=[],W=[],H;try{H=R$.readFileSync(Z,"utf-8")}catch{return{applied:Y,skipped:Q.map((G)=>G.description)}}let X=H;for(let G of Q)if(X.includes(G.find))X=X.replace(G.find,G.replace),Y.push(G.description);else W.push(G.description);if(!U&&Y.length>0)R$.writeFileSync(Z,X,"utf-8");return{applied:Y,skipped:W}}function y1($){let{packageJsonPath:z,update:Q,add:U,devUpdate:Z,devAdd:Y,remove:W,dryRun:H}=$,X=A0.resolve(z),G=[],N=[],b=[],j;try{let _=R$.readFileSync(X,"utf-8");j=JSON.parse(_)}catch{return{updated:G,added:N,removed:b}}if(!j.dependencies)j.dependencies={};if(!j.devDependencies)j.devDependencies={};for(let[_,B]of Object.entries(Q))if(j.dependencies[_])j.dependencies[_]=B,G.push(_);for(let[_,B]of Object.entries(U))if(!j.dependencies[_])j.dependencies[_]=B,N.push(_);for(let[_,B]of Object.entries(Z))if(j.devDependencies[_])j.devDependencies[_]=B,G.push(_);for(let[_,B]of Object.entries(Y))if(!j.devDependencies[_])j.devDependencies[_]=B,N.push(_);for(let _ of W){if(j.dependencies[_])delete j.dependencies[_],b.push(_);if(j.devDependencies[_]){if(delete j.devDependencies[_],!b.includes(_))b.push(_)}}if(!H&&(G.length>0||N.length>0||b.length>0))R$.writeFileSync(X,JSON.stringify(j,null,2)+`
124
+ `,"utf-8");return{updated:G,added:N,removed:b}}import*as S$ from"fs";import*as L1 from"path";function k3($){let z=/--color-brand-(\d+):\s*([^;]+);/g,Q={},U;while((U=z.exec($))!==null)if(U[1]&&U[2])Q[`--color-brand-${U[1]}`]=U[2].trim();return Q}function u3($,z){let Q=$;for(let[U,Z]of Object.entries(z)){let Y=new RegExp(`(${U.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}):\\s*[^;]+;`,"g");Q=Q.replace(Y,`${U}: ${Z};`)}return Q}async function V1($){let{themePath:z,newThemeContent:Q,dryRun:U}=$,Z=L1.resolve(z),Y;try{Y=S$.readFileSync(Z,"utf-8")}catch{return{brandColors:{},success:!1,message:`Theme file not found at ${Z}`}}let W=k3(Y);if(U)return{brandColors:W,success:!0,message:`Dry run: found ${Object.keys(W).length} brand color variables`};try{if(S$.writeFileSync(Z,Q,"utf-8"),Object.keys(W).length>0){let H=S$.readFileSync(Z,"utf-8"),X=u3(H,W);S$.writeFileSync(Z,X,"utf-8")}return{brandColors:W,success:!0,message:`Theme upgraded successfully. Preserved ${Object.keys(W).length} brand color variables.`}}catch(H){let X=H instanceof Error?H.message:String(H);return{brandColors:W,success:!1,message:`Failed to write theme file: ${X}`}}}var P3=/\bleft-1\/2\b.*-translate-x-1\/2|-translate-x-1\/2.*\bleft-1\/2\b/;function g3($,z){return z.some((Q)=>Q.pattern.test($))}function d3($,z){let Q=$;for(let U of z)U.pattern.lastIndex=0,Q=Q.replace(U.pattern,U.replace);return Q}function f3($,z,Q){let U=[];for(let Z of Q){if(Z.pattern.lastIndex=0,Z.pattern.test($))U.push(Z.description);Z.pattern.lastIndex=0}return U.join("; ")}function j1($,z,Q){let U={file:$,changes:[]},Z=z.split(`
125
+ `);for(let Y=0;Y<Z.length;Y++){let W=Z[Y];if(/^\s*(import\b|require\s*\(|export\b.*from\b)/.test(W))continue;if(P3.test(W))continue;let H=W,X=!1;if(H=H.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(G,N,b,j,_)=>{let B=N??b??j??_;if(B==null)return G;for(let M of Q)M.pattern.lastIndex=0;if(!g3(B,Q))return G;for(let M of Q)M.pattern.lastIndex=0;let K=d3(B,Q);if(K!==B)return X=!0,G.replace(B,K);return G}),X&&H!==W){let G=f3(W,H,Q);Z[Y]=H,U.changes.push({line:Y+1,before:W.trim(),after:H.trim(),description:G})}}return U}function N1($,z){let Q=[],U=$.split(`
126
+ `),Z=[];for(let Y=0;Y<U.length;Y++){let W=U[Y];if(!/^\s*(import\b|require\s*\(|export\b.*from\b)/.test(W))continue;let H=W;for(let X of z)if(H.includes(X.from)){if(H=H.replace(X.from,X.to),X.symbolRenames)Z.push(...X.symbolRenames)}if(H!==W){U[Y]=H;let X=z.find((G)=>W.includes(G.from));Q.push({line:Y+1,before:W.trim(),after:H.trim(),description:X?.description??"Import path update"})}}if(Z.length>0)for(let Y=0;Y<U.length;Y++){let W=U[Y],H=W;for(let X of Z){let G=new RegExp(`\\b${X.from}\\b`,"g");H=H.replace(G,X.to)}if(H!==W){if(U[Y]=H,!Q.some((G)=>G.line===Y+1))Q.push({line:Y+1,before:W.trim(),after:H.trim(),description:`Renamed ${Z.map((G)=>`${G.from} → ${G.to}`).join(", ")}`})}}return{content:U.join(`
127
+ `),changes:Q}}function _1($,z){let Q=[],U=$.split(`
128
+ `);for(let Z=0;Z<U.length;Z++){let Y=U[Z];if(/^\s*(import\b|require\s*\(|export\b.*from\b)/.test(Y))continue;let W=Y;for(let H of z)if(W.includes(H.from))W=W.split(H.from).join(H.to);if(W!==Y){U[Z]=W;let H=z.find((X)=>Y.includes(X.from));Q.push({line:Z+1,before:Y.trim(),after:W.trim(),description:H?.description??"Prop update"})}}return{content:U.join(`
129
129
  `),changes:Q}}function b1($,z,Q){let U=[],Z=z.split(`
130
- `);for(let{pattern:Y,instruction:X}of Q)for(let H=0;H<Z.length;H++){if(/^\s*(import\b|export\b.*from\b)/.test(Z[H])||/\brequire\s*\(/.test(Z[H]))continue;if(Z[H].includes(Y))U.push({file:$,line:H+1,pattern:Y,instruction:X})}return U}function _1($,z,Q){let U=[],Z=z.split(`
131
- `);for(let Y=0;Y<Z.length;Y++)for(let X of Q)if(Z[Y].includes(X))U.push({file:$,line:Y+1,token:X});return U}function h3($){return{fromVersion:$.fromVersion,toVersion:$.toVersion,classTransforms:$.classRenames.map((z)=>({pattern:new RegExp(`\\b${I1(z.from)}\\b`,"g"),replace:z.to,description:z.description,needsReview:z.needsReview})),importTransforms:$.importRenames,propTransforms:$.propRenames,structuralPatterns:$.structuralPatterns,orphanedTokens:$.orphanedTokens,dependencyChanges:$.dependencyChanges,configChanges:$.configChanges,notes:$.notes}}function I1($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function m3($){let z=p.join($,"components.json");try{return JSON.parse(l.readFileSync(z,"utf-8"))}catch{return null}}function c3($,z){let Q=p.join($,"components.json");l.writeFileSync(Q,JSON.stringify(z,null,2)+`
132
- `,"utf-8")}async function D1($){let z=p.resolve($);return A0(["**/*.{tsx,ts}"],{cwd:z,absolute:!0,ignore:["**/node_modules/**","**/*.story.tsx","**/*.demo.tsx","**/.next/**","**/dist/**","**/build/**"]})}async function l3($){return(await A0(["**/theme.css"],{cwd:$,absolute:!0,deep:5,ignore:["**/node_modules/**","**/.next/**","**/dist/**"]}))[0]}function p3($){let z=p.join($,"package.json");return l.existsSync(z)?z:void 0}function a3($){let z=p.join($,"tsconfig.json");return l.existsSync(z)?z:void 0}function s3($){let z=0;for(let Q=0;Q<$.length;Q++){let U=$.charCodeAt(Q);z=(z<<5)-z+U|0}return z.toString(36)}var E1=new f3().name("upgrade").description("upgrade your project to the latest version of Untitled UI").option("--dry-run","preview changes without writing files",!1).option("--skip-theme","skip theme.css replacement",!1).option("--skip-deps","skip dependency updates",!1).option("--skip-config","skip config file updates",!1).option("--path <dir>","directory to scan for source files").option("-y, --yes","skip prompts and use defaults",!1).action(async($)=>{console.log(D.bold(`
130
+ `);for(let{pattern:Y,instruction:W}of Q)for(let H=0;H<Z.length;H++){let X=Z[H];if(/^\s*(import\b|export\b.*from\b)/.test(X)||/\brequire\s*\(/.test(X))continue;if(X.includes(Y))U.push({file:$,line:H+1,pattern:Y,instruction:W})}return U}function A1($,z,Q){let U=[],Z=z.split(`
131
+ `);for(let Y=0;Y<Z.length;Y++){let W=Z[Y];for(let H of Q)if(W.includes(H))U.push({file:$,line:Y+1,token:H})}return U}function m3($){return{fromVersion:$.fromVersion,toVersion:$.toVersion,classTransforms:$.classRenames.map((z)=>({pattern:new RegExp(`\\b${E1(z.from)}\\b`,"g"),replace:z.to,description:z.description,needsReview:z.needsReview})),importTransforms:$.importRenames,propTransforms:$.propRenames,structuralPatterns:$.structuralPatterns,orphanedTokens:$.orphanedTokens,dependencyChanges:$.dependencyChanges,configChanges:$.configChanges,notes:$.notes}}function E1($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function c3($){let z=a.join($,"components.json");try{return JSON.parse(l.readFileSync(z,"utf-8"))}catch{return null}}function l3($,z){let Q=a.join($,"components.json");l.writeFileSync(Q,JSON.stringify(z,null,2)+`
132
+ `,"utf-8")}async function I1($){let z=a.resolve($);return I0(["**/*.{tsx,ts}"],{cwd:z,absolute:!0,ignore:["**/node_modules/**","**/*.story.tsx","**/*.demo.tsx","**/.next/**","**/dist/**","**/build/**"]})}async function a3($){return(await I0(["**/theme.css"],{cwd:$,absolute:!0,deep:5,ignore:["**/node_modules/**","**/.next/**","**/dist/**"]}))[0]}function p3($){let z=a.join($,"package.json");return l.existsSync(z)?z:void 0}function s3($){let z=a.join($,"tsconfig.json");return l.existsSync(z)?z:void 0}function r3($){let z=0;for(let Q=0;Q<$.length;Q++){let U=$.charCodeAt(Q);z=(z<<5)-z+U|0}return z.toString(36)}var T1=new h3().name("upgrade").description("upgrade your project to the latest version of Untitled UI").option("--dry-run","preview changes without writing files",!1).option("--skip-theme","skip theme.css replacement",!1).option("--skip-deps","skip dependency updates",!1).option("--skip-config","skip config file updates",!1).option("--path <dir>","directory to scan for source files").option("-y, --yes","skip prompts and use defaults",!1).action(async($)=>{console.log(D.bold(`
133
133
  Upgrade Untitled UI
134
- `));let z=p.resolve($.path||".");try{let{stdout:q}=await _0("git",["status","--porcelain"],{cwd:z});if(q.trim().length>0){if(console.log(D.yellow(" You have uncommitted changes. We recommend committing first so you can\n revert with `git checkout .` if needed.")),!$.yes){let{proceed:K}=await A1({type:"confirm",name:"proceed",message:"Continue with uncommitted changes?",initial:!0});if(!K){console.log(D.yellow(`
134
+ `));let z=a.resolve($.path||".");try{let{stdout:J}=await D0("git",["status","--porcelain"],{cwd:z});if(J.trim().length>0){if(console.log(D.yellow(" You have uncommitted changes. We recommend committing first so you can\n revert with `git checkout .` if needed.")),!$.yes){let{proceed:q}=await D1({type:"confirm",name:"proceed",message:"Continue with uncommitted changes?",initial:!0});if(!q){console.log(D.yellow(`
135
135
  Cancelled.
136
- `));return}}console.log()}}catch{}let Q=m3(z),U=Q?.version??"7";if(console.log(` Detected version: ${D.cyan(U)}
136
+ `));return}}console.log()}}catch{}let Q=c3(z),U=Q?.version??"7";if(console.log(` Detected version: ${D.cyan(U)}
137
137
  `),U==="8"){console.log(D.green(` Already on version 8. Nothing to upgrade.
138
- `));return}let Z,Y,X=i(" Fetching migration rules...").start();try{let q=await fetch("https://www.untitledui.com/react/api/upgrade",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({fromVersion:U,toVersion:"8"})});if(!q.ok)throw Error(`Server returned ${q.status}`);let K=await q.json();Z=h3(K),Y="server",X.succeed(" Migration rules fetched from server")}catch{Z=J1,Y="built-in",X.warn(" Could not reach server. Using built-in migration rules")}let H=i(" Scanning files...").start(),B=await D1(z);H.succeed(` Found ${D.bold(B.length)} source files`);let J=0,j=0,_=0,L=0,b=[],W=[],y=[],V=[];if(!$.skipTheme){let q=i(" Upgrading theme.css...").start(),K=await l3(z);if(K)try{let M=p.resolve(import.meta.dirname,"../config/styles/theme.css"),A=l.readFileSync(M,"utf-8"),x=await L1({themePath:K,newThemeContent:A,dryRun:$.dryRun});if(x.success){let k=Object.keys(x.brandColors);if(k.length>0)q.succeed(` Theme upgraded. Brand colors preserved: ${D.cyan(k.join(", "))}`);else q.succeed(" Theme upgraded (no custom brand colors found)")}else q.warn(` Theme upgrade issue: ${x.message}`)}catch(M){let A=M instanceof Error?M.message:String(M);q.warn(` Theme upgrade skipped: ${A}`)}else q.warn(" No theme.css found — skipping theme upgrade")}if(!$.skipConfig){let q=i(" Updating config files...").start(),K=a3(z);if(K&&Z.configChanges.tsconfig.length>0){let{applied:M,skipped:A}=y1({tsconfigPath:K,changes:Z.configChanges.tsconfig,dryRun:$.dryRun});if(M.length>0)q.succeed(` Config updated: ${M.map((x)=>D.cyan(x)).join(", ")}`);else q.info(" No config changes needed");if(A.length>0)for(let x of A)console.log(D.dim(` Skipped: ${x}`))}else q.info(" No config changes to apply")}if(!$.skipDeps){let q=i(" Updating dependencies...").start(),K=p3(z);if(K){let M=G1({packageJsonPath:K,update:Z.dependencyChanges.update,add:Z.dependencyChanges.add,devUpdate:Z.dependencyChanges.devUpdate,devAdd:Z.dependencyChanges.devAdd,remove:Z.dependencyChanges.remove,dryRun:$.dryRun});if(M.updated.length+M.added.length+M.removed.length>0){if(q.succeed(" Dependencies updated in package.json"),M.updated.length>0)console.log(D.dim(` Updated: ${M.updated.join(", ")}`));if(M.added.length>0)console.log(D.dim(` Added: ${M.added.join(", ")}`));if(M.removed.length>0)console.log(D.dim(` Removed: ${M.removed.join(", ")}`));if(!$.dryRun){let x=i(" Installing dependencies...").start();try{let k=X$();await _0(k==="bunx"?"bun":k==="pnpx"?"pnpm":k==="yarn"?"yarn":"npm",["install"],{cwd:z}),x.succeed(" Dependencies installed")}catch(k){let n=k instanceof Error?k.message:String(k);x.warn(` Could not auto-install dependencies: ${n.substring(0,100)}`),console.log(D.dim(" Run your package manager's install command manually."))}}}else q.info(" No dependency changes needed")}else q.warn(" No package.json found — skipping dependency updates")}let w=i(" Renaming files...").start(),T=new Set;for(let q of Z.importTransforms){let K=q.from.split("/").pop(),M=q.to.split("/").pop();if(K===M)continue;let A=A0.sync([`**/${K}.tsx`,`**/${K}.ts`],{cwd:z,absolute:!0,ignore:["**/node_modules/**"]});for(let x of A){let k=x.replace(new RegExp(`${I1(K)}(\\.tsx?)$`),`${M}$1`);if(!$.dryRun)try{l.renameSync(x,k),T.add(q.from)}catch{}else T.add(q.from)}}let E=Z.importTransforms.filter((q)=>{let K=q.from.split("/").pop(),M=q.to.split("/").pop();if(K===M)return!0;return T.has(q.from)});if(T.size>0)w.succeed(` Renamed ${D.bold(T.size)} files`),B.length=0,B.push(...await D1(z));else w.info(" No file renames needed");let C=i(" Applying source transforms...").start();for(let q of B){let K;try{K=l.readFileSync(q,"utf-8")}catch{continue}let M=p.relative(z,q),A=K,x=!1,k=V1(M,A,Z.classTransforms);if(k.changes.length>0){let $$=A.split(`
139
- `);for(let t of k.changes){let F$=t.line-1,z$=$$[F$];z$=z$.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(o$,T1,x1,R1,S1)=>{let O$=T1??x1??R1??S1;if(O$==null)return o$;let k$=O$;for(let t$ of Z.classTransforms)t$.pattern.lastIndex=0,k$=k$.replace(t$.pattern,t$.replace);return k$!==O$?o$.replace(O$,k$):o$}),$$[F$]=z$}A=$$.join(`
140
- `),J+=k.changes.length,x=!0,b.push(k);for(let t of k.changes){let F$=Z.classTransforms.find((z$)=>{return z$.pattern.lastIndex=0,z$.needsReview&&z$.pattern.test(t.before)});for(let z$ of Z.classTransforms)z$.pattern.lastIndex=0;if(F$)W.push({file:M,line:t.line,description:t.description,before:t.before,after:t.after})}}let n=N1(A,Z.propTransforms);if(n.changes.length>0)A=n.content,j+=n.changes.length,x=!0;let e=j1(A,E);if(e.changes.length>0)A=e.content,_+=e.changes.length,x=!0;if(x){if(L++,!$.dryRun)l.writeFileSync(q,A)}}C.succeed(` Processed ${D.bold(B.length)} files`);let d=i(" Detecting structural patterns...").start();for(let q of B){let K;try{K=l.readFileSync(q,"utf-8")}catch{continue}let M=p.relative(z,q),A=b1(M,K,Z.structuralPatterns);V.push(...A)}if(V.length>0)d.warn(` Found ${D.bold(V.length)} structural patterns requiring manual review`);else d.succeed(" No structural patterns found");if(Q?.components&&Array.isArray(Q.components)&&Q.components.some((q)=>q.contentHash)){let q=i(" Checking stock components...").start(),K=[];for(let M of Q.components){if(!M.contentHash||!M.filePath)continue;let A=p.resolve(z,M.filePath);try{let x=l.readFileSync(A,"utf-8");if(s3(x)===M.contentHash)K.push({name:M.name,path:M.filePath})}catch{}}if(K.length>0){q.info(` ${D.bold(K.length)} stock components can be auto-refreshed`);let M=$.yes;if(!M){let{confirm:A}=await A1({type:"confirm",name:"confirm",message:`Refresh ${K.length} unmodified stock components to v8.0?`,initial:!0});M=A}if(M&&!$.dryRun){let A=i(" Fetching v8.0 components...").start();try{let x=await fetch("https://www.untitledui.com/react/api/components",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({components:K.map((k)=>k.name),version:"8"})});if(x.ok){let k=await x.json(),n=0;for(let e of K)if(k[e.name])l.writeFileSync(p.resolve(z,e.path),k[e.name]),n++;A.succeed(` Refreshed ${D.bold(n)} stock components`)}else A.warn(" Could not fetch v8.0 components from server")}catch{A.warn(" Could not reach server for component refresh")}}}else q.info(" No unmodified stock components to refresh")}let F=i(" Scanning for orphaned tokens...").start();for(let q of B){let K;try{K=l.readFileSync(q,"utf-8")}catch{continue}let M=p.relative(z,q),A=_1(M,K,Z.orphanedTokens);y.push(...A)}if(y.length>0)F.warn(` Found ${D.bold(y.length)} orphaned v7.0 tokens remaining`);else F.succeed(" No orphaned tokens found");let R=[];if(!$.dryRun){let q=i(" Running type check...").start();try{let K=X$();await _0(K,["tsc","--noEmit"],{cwd:z}),q.succeed(" Type check passed")}catch(K){let A=(K?.stderr||K?.stdout||"").split(`
141
- `).filter((x)=>x.includes("error TS")).slice(0,20);R.push(...A),q.warn(` Type check found ${D.bold(A.length)} error(s)`)}}if(!$.dryRun){let q={version:"8",status:W.length>0||y.length>0?"partial":"success",filesScanned:B.length,filesModified:L,classChanges:J,propChanges:j,importChanges:_,manualReview:W,orphanedTokens:y,typeErrors:R,structuralPatterns:V,notes:Z.notes};try{l.writeFileSync(p.join(z,"upgrade-report.json"),JSON.stringify(q,null,2)+`
142
- `,"utf-8")}catch{}if(W.length>0||V.length>0)try{let K=`# Untitled UI v7.0 to v8.0 Upgrade Instructions
138
+ `));return}let Z,Y,W=i(" Fetching migration rules...").start();try{let J=await fetch("https://www.untitledui.com/react/api/upgrade",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({fromVersion:U,toVersion:"8"})});if(!J.ok)throw Error(`Server returned ${J.status}`);let q=await J.json();Z=m3(q),Y="server",W.succeed(" Migration rules fetched from server")}catch{Z=G1,Y="built-in",W.warn(" Could not reach server. Using built-in migration rules")}let H=i(" Scanning files...").start(),X=await I1(z);H.succeed(` Found ${D.bold(X.length)} source files`);let G=0,N=0,b=0,j=0,_=[],B=[],K=[],M=[];if(!$.skipTheme){let J=i(" Upgrading theme.css...").start(),q=await a3(z);if(q)try{let L=a.resolve(import.meta.dirname,"../config/styles/theme.css"),A=l.readFileSync(L,"utf-8"),x=await V1({themePath:q,newThemeContent:A,dryRun:$.dryRun});if(x.success){let u=Object.keys(x.brandColors);if(u.length>0)J.succeed(` Theme upgraded. Brand colors preserved: ${D.cyan(u.join(", "))}`);else J.succeed(" Theme upgraded (no custom brand colors found)")}else J.warn(` Theme upgrade issue: ${x.message}`)}catch(L){let A=L instanceof Error?L.message:String(L);J.warn(` Theme upgrade skipped: ${A}`)}else J.warn(" No theme.css found — skipping theme upgrade")}if(!$.skipConfig){let J=i(" Updating config files...").start(),q=s3(z);if(q&&Z.configChanges.tsconfig.length>0){let{applied:L,skipped:A}=M1({tsconfigPath:q,changes:Z.configChanges.tsconfig,dryRun:$.dryRun});if(L.length>0)J.succeed(` Config updated: ${L.map((x)=>D.cyan(x)).join(", ")}`);else J.info(" No config changes needed");if(A.length>0)for(let x of A)console.log(D.dim(` Skipped: ${x}`))}else J.info(" No config changes to apply")}if(!$.skipDeps){let J=i(" Updating dependencies...").start(),q=p3(z);if(q){let L=y1({packageJsonPath:q,update:Z.dependencyChanges.update,add:Z.dependencyChanges.add,devUpdate:Z.dependencyChanges.devUpdate,devAdd:Z.dependencyChanges.devAdd,remove:Z.dependencyChanges.remove,dryRun:$.dryRun});if(L.updated.length+L.added.length+L.removed.length>0){if(J.succeed(" Dependencies updated in package.json"),L.updated.length>0)console.log(D.dim(` Updated: ${L.updated.join(", ")}`));if(L.added.length>0)console.log(D.dim(` Added: ${L.added.join(", ")}`));if(L.removed.length>0)console.log(D.dim(` Removed: ${L.removed.join(", ")}`));if(!$.dryRun){let x=i(" Installing dependencies...").start();try{let u=W$();await D0(u==="bunx"?"bun":u==="pnpx"?"pnpm":u==="yarn"?"yarn":"npm",["install"],{cwd:z}),x.succeed(" Dependencies installed")}catch(u){let o=u instanceof Error?u.message:String(u);x.warn(` Could not auto-install dependencies: ${o.substring(0,100)}`),console.log(D.dim(" Run your package manager's install command manually."))}}}else J.info(" No dependency changes needed")}else J.warn(" No package.json found — skipping dependency updates")}let v=i(" Renaming files...").start(),R=new Set;for(let J of Z.importTransforms){let q=J.from.split("/").pop(),L=J.to.split("/").pop();if(q===L)continue;let A=I0.sync([`**/${q}.tsx`,`**/${q}.ts`],{cwd:z,absolute:!0,ignore:["**/node_modules/**"]});for(let x of A){let u=x.replace(new RegExp(`${E1(q)}(\\.tsx?)$`),`${L}$1`);if(!$.dryRun)try{l.renameSync(x,u),R.add(J.from)}catch{}else R.add(J.from)}}let E=Z.importTransforms.filter((J)=>{let q=J.from.split("/").pop(),L=J.to.split("/").pop();if(q===L)return!0;return R.has(J.from)});if(R.size>0)v.succeed(` Renamed ${D.bold(R.size)} files`),X.length=0,X.push(...await I1(z));else v.info(" No file renames needed");let T=i(" Applying source transforms...").start();for(let J of X){let q;try{q=l.readFileSync(J,"utf-8")}catch{continue}let L=a.relative(z,J),A=q,x=!1,u=j1(L,A,Z.classTransforms);if(u.changes.length>0){let n=A.split(`
139
+ `);for(let e of u.changes){let F$=e.line-1,$$=n[F$];$$=$$.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(o$,x1,R1,S1,w1)=>{let O$=x1??R1??S1??w1;if(O$==null)return o$;let k$=O$;for(let t$ of Z.classTransforms)t$.pattern.lastIndex=0,k$=k$.replace(t$.pattern,t$.replace);return k$!==O$?o$.replace(O$,k$):o$}),n[F$]=$$}A=n.join(`
140
+ `),G+=u.changes.length,x=!0,_.push(u);for(let e of u.changes){let F$=Z.classTransforms.find(($$)=>{return $$.pattern.lastIndex=0,$$.needsReview&&$$.pattern.test(e.before)});for(let $$ of Z.classTransforms)$$.pattern.lastIndex=0;if(F$)B.push({file:L,line:e.line,description:e.description,before:e.before,after:e.after})}}let o=_1(A,Z.propTransforms);if(o.changes.length>0)A=o.content,N+=o.changes.length,x=!0;let K$=N1(A,E);if(K$.changes.length>0)A=K$.content,b+=K$.changes.length,x=!0;if(x){if(j++,!$.dryRun)l.writeFileSync(J,A)}}T.succeed(` Processed ${D.bold(X.length)} files`);let C=i(" Detecting structural patterns...").start();for(let J of X){let q;try{q=l.readFileSync(J,"utf-8")}catch{continue}let L=a.relative(z,J),A=b1(L,q,Z.structuralPatterns);M.push(...A)}if(M.length>0)C.warn(` Found ${D.bold(M.length)} structural patterns requiring manual review`);else C.succeed(" No structural patterns found");if(Q?.components&&Array.isArray(Q.components)&&Q.components.some((J)=>J.contentHash)){let J=i(" Checking stock components...").start(),q=[];for(let L of Q.components){if(!L.contentHash||!L.filePath)continue;let A=a.resolve(z,L.filePath);try{let x=l.readFileSync(A,"utf-8");if(r3(x)===L.contentHash)q.push({name:L.name,path:L.filePath})}catch{}}if(q.length>0){J.info(` ${D.bold(q.length)} stock components can be auto-refreshed`);let L=$.yes;if(!L){let{confirm:A}=await D1({type:"confirm",name:"confirm",message:`Refresh ${q.length} unmodified stock components to v8.0?`,initial:!0});L=A}if(L&&!$.dryRun){let A=i(" Fetching v8.0 components...").start();try{let x=await fetch("https://www.untitledui.com/react/api/components",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({components:q.map((u)=>u.name),version:"8"})});if(x.ok){let u=await x.json(),o=0;for(let K$ of q){let n=u[K$.name];if(n)l.writeFileSync(a.resolve(z,K$.path),n),o++}A.succeed(` Refreshed ${D.bold(o)} stock components`)}else A.warn(" Could not fetch v8.0 components from server")}catch{A.warn(" Could not reach server for component refresh")}}}else J.info(" No unmodified stock components to refresh")}let O=i(" Scanning for orphaned tokens...").start();for(let J of X){let q;try{q=l.readFileSync(J,"utf-8")}catch{continue}let L=a.relative(z,J),A=A1(L,q,Z.orphanedTokens);K.push(...A)}if(K.length>0)O.warn(` Found ${D.bold(K.length)} orphaned v7.0 tokens remaining`);else O.succeed(" No orphaned tokens found");let S=[];if(!$.dryRun){let J=i(" Running type check...").start();try{let q=W$();await D0(q,["tsc","--noEmit"],{cwd:z}),J.succeed(" Type check passed")}catch(q){let A=(q?.stderr||q?.stdout||"").split(`
141
+ `).filter((x)=>x.includes("error TS")).slice(0,20);S.push(...A),J.warn(` Type check found ${D.bold(A.length)} error(s)`)}}if(!$.dryRun){let J={version:"8",status:B.length>0||K.length>0?"partial":"success",filesScanned:X.length,filesModified:j,classChanges:G,propChanges:N,importChanges:b,manualReview:B,orphanedTokens:K,typeErrors:S,structuralPatterns:M,notes:Z.notes};try{l.writeFileSync(a.join(z,"upgrade-report.json"),JSON.stringify(J,null,2)+`
142
+ `,"utf-8")}catch{}if(B.length>0||M.length>0)try{let q=`# Untitled UI v7.0 to v8.0 Upgrade Instructions
143
143
 
144
- `;if(K+="This file was generated by `untitledui upgrade`. It is meant to guide\n",K+=`manual review of changes that could not be fully automated.
144
+ `;if(q+="This file was generated by `untitledui upgrade`. It is meant to guide\n",q+=`manual review of changes that could not be fully automated.
145
145
 
146
- `,K+=`**Important**: Ignore pre-existing type errors and linting issues.
147
- `,K+=`Focus only on migration-related changes listed below.
146
+ `,q+=`**Important**: Ignore pre-existing type errors and linting issues.
147
+ `,q+=`Focus only on migration-related changes listed below.
148
148
 
149
- `,K+=`Delete this file after review is complete.
149
+ `,q+=`Delete this file after review is complete.
150
150
 
151
- `,V.length>0){K+=`## Structural changes
151
+ `,M.length>0){q+=`## Structural changes
152
152
 
153
- `,K+=`These patterns require manual refactoring:
153
+ `,q+=`These patterns require manual refactoring:
154
154
 
155
- `;for(let M of V)K+=`- **${M.file}:${M.line}** — \`${M.pattern}\`
156
- `,K+=` ${M.instruction}
155
+ `;for(let L of M)q+=`- **${L.file}:${L.line}** — \`${L.pattern}\`
156
+ `,q+=` ${L.instruction}
157
157
 
158
- `}if(W.length>0){K+=`## Manual review items
158
+ `}if(B.length>0){q+=`## Manual review items
159
159
 
160
- `,K+=`These class replacements may need manual verification:
160
+ `,q+=`These class replacements may need manual verification:
161
161
 
162
- `;for(let M of W)K+=`### ${M.file}:${M.line}
162
+ `;for(let L of B)q+=`### ${L.file}:${L.line}
163
163
 
164
- `,K+=`${M.description}
164
+ `,q+=`${L.description}
165
165
 
166
- `,K+="```diff\n",K+=`- ${M.before}
167
- `,K+=`+ ${M.after}
168
- `,K+="```\n\n"}if(Z.notes.length>0){K+=`## Additional notes
166
+ `,q+="```diff\n",q+=`- ${L.before}
167
+ `,q+=`+ ${L.after}
168
+ `,q+="```\n\n"}if(Z.notes.length>0){q+=`## Additional notes
169
169
 
170
- `;for(let M of Z.notes)K+=`- ${M}
171
- `;K+=`
172
- `}l.writeFileSync(p.join(z,"UPGRADE-INSTRUCTIONS.md"),K,"utf-8")}catch{}}if(!$.dryRun&&Q)Q.version="8",c3(z,Q);if(console.log(D.bold(`
170
+ `;for(let L of Z.notes)q+=`- ${L}
171
+ `;q+=`
172
+ `}l.writeFileSync(a.join(z,"UPGRADE-INSTRUCTIONS.md"),q,"utf-8")}catch{}}if(!$.dryRun&&Q)Q.version="8",l3(z,Q);if(console.log(D.bold(`
173
173
  Summary
174
- `)),console.log(` Migration source: ${D.cyan(Y)}`),console.log(` Files scanned: ${D.cyan(B.length)}`),console.log(` Files modified: ${D.cyan(L)}`),console.log(` Class changes: ${D.cyan(J)}`),console.log(` Prop changes: ${D.cyan(j)}`),console.log(` Import changes: ${D.cyan(_)}`),V.length>0){console.log(` Structural patterns: ${D.yellow(V.length)}`);for(let q of V.slice(0,5))console.log(D.dim(` ${q.file}:${q.line} — ${q.pattern}`));if(V.length>5)console.log(D.dim(` ... and ${V.length-5} more (see UPGRADE-INSTRUCTIONS.md)`))}if(W.length>0){console.log(` Manual review items: ${D.yellow(W.length)}`);for(let q of W.slice(0,5))console.log(D.dim(` ${q.file}:${q.line} — ${q.description}`));if(W.length>5)console.log(D.dim(` ... and ${W.length-5} more (see UPGRADE-INSTRUCTIONS.md)`))}if(y.length>0){console.log(` Orphaned tokens: ${D.yellow(y.length)}`);let q=[...new Set(y.map((K)=>K.token))];for(let K of q.slice(0,5))console.log(D.dim(` ${K}`));if(q.length>5)console.log(D.dim(` ... and ${q.length-5} more`))}if(R.length>0)console.log(` Type errors: ${D.yellow(R.length)}`);if($.dryRun){if(console.log(D.yellow(`
175
- Dry run — no files were modified.`)),b.length>0){console.log(D.bold(`
174
+ `)),console.log(` Migration source: ${D.cyan(Y)}`),console.log(` Files scanned: ${D.cyan(X.length)}`),console.log(` Files modified: ${D.cyan(j)}`),console.log(` Class changes: ${D.cyan(G)}`),console.log(` Prop changes: ${D.cyan(N)}`),console.log(` Import changes: ${D.cyan(b)}`),M.length>0){console.log(` Structural patterns: ${D.yellow(M.length)}`);for(let J of M.slice(0,5))console.log(D.dim(` ${J.file}:${J.line} — ${J.pattern}`));if(M.length>5)console.log(D.dim(` ... and ${M.length-5} more (see UPGRADE-INSTRUCTIONS.md)`))}if(B.length>0){console.log(` Manual review items: ${D.yellow(B.length)}`);for(let J of B.slice(0,5))console.log(D.dim(` ${J.file}:${J.line} — ${J.description}`));if(B.length>5)console.log(D.dim(` ... and ${B.length-5} more (see UPGRADE-INSTRUCTIONS.md)`))}if(K.length>0){console.log(` Orphaned tokens: ${D.yellow(K.length)}`);let J=[...new Set(K.map((q)=>q.token))];for(let q of J.slice(0,5))console.log(D.dim(` ${q}`));if(J.length>5)console.log(D.dim(` ... and ${J.length-5} more`))}if(S.length>0)console.log(` Type errors: ${D.yellow(S.length)}`);if($.dryRun){if(console.log(D.yellow(`
175
+ Dry run — no files were modified.`)),_.length>0){console.log(D.bold(`
176
176
  Changes preview:
177
- `));for(let q of b.slice(0,10)){console.log(D.dim(` ${q.file}`));for(let K of q.changes.slice(0,3))console.log(D.red(` - ${K.before.substring(0,100)}`)),console.log(D.green(` + ${K.after.substring(0,100)}`));if(q.changes.length>3)console.log(D.dim(` ... and ${q.changes.length-3} more`))}if(b.length>10)console.log(D.dim(`
178
- ... and ${b.length-10} more files`))}console.log(D.dim(`
177
+ `));for(let J of _.slice(0,10)){console.log(D.dim(` ${J.file}`));for(let q of J.changes.slice(0,3))console.log(D.red(` - ${q.before.substring(0,100)}`)),console.log(D.green(` + ${q.after.substring(0,100)}`));if(J.changes.length>3)console.log(D.dim(` ... and ${J.changes.length-3} more`))}if(_.length>10)console.log(D.dim(`
178
+ ... and ${_.length-10} more files`))}console.log(D.dim(`
179
179
  Run without --dry-run to apply changes.
180
- `))}else console.log(D.green("\n Done! Run `bun run build` to verify.")),console.log(D.dim(" If something went wrong, run `git checkout .` to revert.\n"))});var D0={name:"untitledui",version:"0.1.61",main:"dist/index.mjs",description:"The Untitled UI CLI tool helps you quickly scaffold projects with Untitled UI React and add components and page examples to your existing projects with an interactive interface in seconds.",type:"module",publishConfig:{access:"public"},scripts:{test:"bun test __tests__/",dev:"bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=http://localhost:3000/react/api --watch",build:"bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=https://www.untitledui.com/react/api","publish:npm":"bun run build && npm publish --access public",start:"node dist/index.mjs"},bugs:{url:"https://github.com/untitleduico/react/issues"},homepage:"https://github.com/untitleduico/react#readme",repository:{type:"git",url:"https://github.com/untitleduico/react.git",directory:"cli"},engines:{node:">=18"},keywords:["untitledui","untitled-ui","untitledui-cli","untitledui-react","untitledui-components","untitledui-examples","untitledui-vite","untitledui-nextjs","cli","tailwindcss","nextjs","react","components","examples","vite"],files:["dist","config","templates","README.md"],author:{name:"Untitled UI",url:"https://www.untitledui.com/react"},contributors:[{name:"Dilshod Turobov",url:"https://x.com/deebovv"},{name:"Jordan Hughes",url:"https://x.com/jordanphughes"}],license:"MIT",bin:{untitledui:"dist/index.mjs"},exports:"./dist/index.mjs",dependencies:{"async-retry":"^1.3.3",chalk:"^5.6.2",commander:"^13.1.0",execa:"^7.2.0","fast-glob":"^3.3.3","node-fetch":"^3.3.2",open:"^10.2.0",ora:"^8.2.0",prettier:"^3.7.4",prompts:"^2.4.2",tar:"^7.5.2","ts-morph":"^25.0.1","tsconfig-paths":"^4.2.0","update-check":"^1.5.4"},devDependencies:{"@types/async-retry":"^1.4.9","@types/bun":"^1.3.10","@types/prompts":"^2.4.9","@types/tar":"^6.1.13","type-fest":"^4.41.0",typescript:"^5.9.3"}};process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function n3(){let $=new i3().name(D0.name).version(D0.version);$.addCommand(Q1).addCommand(s0).addCommand(Z1).addCommand(q1).addCommand(n0).addCommand(K1).addCommand(E1),$.parse()}n3();
180
+ `))}else console.log(D.green("\n Done! Run `bun run build` to verify.")),console.log(D.dim(" If something went wrong, run `git checkout .` to revert.\n"))});var E0={name:"untitledui",version:"0.1.62",main:"dist/index.mjs",description:"The Untitled UI CLI tool helps you quickly scaffold projects with Untitled UI React and add components and page examples to your existing projects with an interactive interface in seconds.",type:"module",publishConfig:{access:"public"},scripts:{test:"bun test __tests__/",dev:"bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=http://localhost:3000/react/api --watch",build:"bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=https://www.untitledui.com/react/api","publish:npm":"bun run build && npm publish --access public",start:"node dist/index.mjs"},bugs:{url:"https://github.com/untitleduico/cli/issues"},homepage:"https://github.com/untitleduico/cli#readme",repository:{type:"git",url:"git+https://github.com/untitleduico/cli.git"},engines:{node:">=18"},keywords:["untitledui","untitled-ui","untitledui-cli","untitledui-react","untitledui-components","untitledui-examples","untitledui-vite","untitledui-nextjs","cli","tailwindcss","nextjs","react","components","examples","vite"],files:["dist","config","templates","README.md"],author:{name:"Untitled UI",url:"https://www.untitledui.com/react"},contributors:[{name:"Dilshod Turobov",url:"https://x.com/deebovv"},{name:"Jordan Hughes",url:"https://x.com/jordanphughes"}],license:"MIT",bin:{untitledui:"dist/index.mjs"},exports:"./dist/index.mjs",dependencies:{"async-retry":"^1.3.3",chalk:"^5.6.2",commander:"^13.1.0",execa:"^7.2.0","fast-glob":"^3.3.3","node-fetch":"^3.3.2",open:"^10.2.0",ora:"^8.2.0",prettier:"^3.7.4",prompts:"^2.4.2",tar:"^7.5.2","ts-morph":"^25.0.1","tsconfig-paths":"^4.2.0","update-check":"^1.5.4"},devDependencies:{"@types/async-retry":"^1.4.9","@types/bun":"^1.3.10","@types/prompts":"^2.4.9","@types/tar":"^6.1.13","type-fest":"^4.41.0",typescript:"^5.9.3"}};process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function o3(){let $=new n3().name(E0.name).version(E0.version);$.addCommand(Z1).addCommand(r0).addCommand(Y1).addCommand(J1).addCommand(o0).addCommand(q1).addCommand(T1),$.parse()}o3();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "untitledui",
3
- "version": "0.1.61",
3
+ "version": "0.1.63",
4
4
  "main": "dist/index.mjs",
5
5
  "description": "The Untitled UI CLI tool helps you quickly scaffold projects with Untitled UI React and add components and page examples to your existing projects with an interactive interface in seconds.",
6
6
  "type": "module",
@@ -15,13 +15,12 @@
15
15
  "start": "node dist/index.mjs"
16
16
  },
17
17
  "bugs": {
18
- "url": "https://github.com/untitleduico/react/issues"
18
+ "url": "https://github.com/untitleduico/cli/issues"
19
19
  },
20
- "homepage": "https://github.com/untitleduico/react#readme",
20
+ "homepage": "https://github.com/untitleduico/cli#readme",
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "https://github.com/untitleduico/react.git",
24
- "directory": "cli"
23
+ "url": "git+https://github.com/untitleduico/cli.git"
25
24
  },
26
25
  "engines": {
27
26
  "node": ">=18"